mirror of
https://github.com/damp11113-software/ccIDE.git
synced 2025-04-28 06:58:13 +00:00
Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
2e855b9907 | |||
5200e86f7d | |||
a5ac8c99c8 | |||
4cad5389d3 | |||
cdfaf53a5c |
@ -1,50 +0,0 @@
|
|||||||
local ws = assert(http.websocket("ws://127.0.0.1:5133"))
|
|
||||||
print("connected to server")
|
|
||||||
|
|
||||||
local id
|
|
||||||
local isrunning = true
|
|
||||||
|
|
||||||
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
|
|
||||||
print("Received message:", message)
|
|
||||||
if message == "ping" then
|
|
||||||
ws.send("pong")
|
|
||||||
elseif message == "sendcode" then
|
|
||||||
local file = io.open("main.lua", "w")
|
|
||||||
print("waiting for code")
|
|
||||||
local filedata, error = ws.receive()
|
|
||||||
file:write(filedata)
|
|
||||||
file:close()
|
|
||||||
elseif message == "runcode" then
|
|
||||||
id = multishell.launch({}, "main.lua")
|
|
||||||
multishell.setTitle(id, "Code")
|
|
||||||
multishell.setFocus(id)
|
|
||||||
elseif message == "exit" then
|
|
||||||
print("Exiting...")
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
print("WebSocket error:", error)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
parallel.waitForAny(exitcheck, main)
|
|
||||||
print("Exited")
|
|
BIN
assets/DOPFoundationLogo.png
Normal file
BIN
assets/DOPFoundationLogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
assets/DPSoftware2.png
Normal file
BIN
assets/DPSoftware2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -218,7 +218,7 @@
|
|||||||
"tooltip": "Send message formatted to player chat"
|
"tooltip": "Send message formatted to player chat"
|
||||||
},
|
},
|
||||||
"advanced_peripherals_chatbox_send_toast_formatted_to_player": {
|
"advanced_peripherals_chatbox_send_toast_formatted_to_player": {
|
||||||
"message0": "Chatbox %1 toast send %2 and title %3 to player %4\nPrefix %5 Brackets %6 Bracket color %7 Range %8",
|
"message0": "Chatbox %1 toast send formatted json %2 and title %3 to player %4\nPrefix %5 Brackets %6 Bracket color %7 Range %8",
|
||||||
"args0": [
|
"args0": [
|
||||||
{
|
{
|
||||||
"type": "input_value",
|
"type": "input_value",
|
||||||
@ -227,7 +227,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "input_value",
|
"type": "input_value",
|
||||||
"name": "TEXT",
|
"name": "JSON",
|
||||||
"check": "String"
|
"check": "String"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1508,5 +1508,301 @@
|
|||||||
"nextStatement": null,
|
"nextStatement": null,
|
||||||
"colour": 200,
|
"colour": 200,
|
||||||
"tooltip": "Sets the redstone level output on the given side to the given power level. (0-15)"
|
"tooltip": "Sets the redstone level output on the given side to the given power level. (0-15)"
|
||||||
|
},
|
||||||
|
|
||||||
|
"advanced_peripherals_mc_beacon_get_level": {
|
||||||
|
"message0": "Get level from beacon %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "BEACON",
|
||||||
|
"check": "Peripheral"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"output": "Number",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the level of the Beacon."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_mc_beacon_get_primary_effect": {
|
||||||
|
"message0": "Get primary effect from beacon %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "BEACON",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "String",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the registry name of the beacon's primary effect."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_mc_beacon_get_secondary_effect": {
|
||||||
|
"message0": "Get secondary secondary effect from beacon %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "BEACON",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "String",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the registry name of the beacon's secondary effect."
|
||||||
|
},
|
||||||
|
|
||||||
|
"advanced_peripherals_mc_note_block_play_note": {
|
||||||
|
"message0": "Play current note sound at note block %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "NOTEBLOCK",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Plays the Note Block's current note sound."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_mc_note_block_get_note": {
|
||||||
|
"message0": "Get current note from note block %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "NOTEBLOCK",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Number",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the index for the Note Block's current note. A number from 0 to 24."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_mc_note_block_change_note_by": {
|
||||||
|
"message0": "Change note to %1 at note block %2",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "TO",
|
||||||
|
"check": "Number"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "NOTEBLOCK",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Changes the Note Block's note to the given note. note must be a number from 0 to 24."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_mc_note_block_change_note": {
|
||||||
|
"message0": "Change note by 1 at note block %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "NOTEBLOCK",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Increments the Note Block's note to the next available note."
|
||||||
|
},
|
||||||
|
|
||||||
|
"advanced_peripherals_botania_flowers_get_mana": {
|
||||||
|
"message0": "Get mana from flower %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "FLOWER",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Number",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the amount of mana stored in the flower."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_flowers_get_max_mana": {
|
||||||
|
"message0": "Get max mana from flower %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "FLOWER",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Number",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the maximum amount of mana that the flower can hold."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_flowers_is_floating": {
|
||||||
|
"message0": "Is flower %1 floating",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "FLOWER",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Boolean",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns true if the flower is a floating flower.",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_flowers_is_on_enchanted_soil": {
|
||||||
|
"message0": "Is flower %1 on enchanted soil",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "FLOWER",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Boolean",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns true if the flower is placed on enchanted soil.",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_flowers_is_empty": {
|
||||||
|
"message0": "Is flower %1 empty",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "FLOWER",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Boolean",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns true if the Flower is empty.",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_flowers_is_full": {
|
||||||
|
"message0": "Is flower %1 full",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "FLOWER",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Boolean",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns true if the Flower is full.",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"advanced_peripherals_botania_mana_pool_get_mana": {
|
||||||
|
"message0": "Get mana from pool %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "POOL",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Number",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the amount of mana stored in the pool."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_mana_pool_get_max_mana": {
|
||||||
|
"message0": "Get max mana from pool %1",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "POOL",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Number",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the maximum amount of mana that the pool can hold."
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_mana_pool_get_mana_needed": {
|
||||||
|
"message0": "Get amount of mana is pool %1 needed to fill full",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "POOL",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Number",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns the amount of mana needed to fill the pool. Equivalent to getMaxMana() - getMana().",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_mana_pool_is_empty": {
|
||||||
|
"message0": "Is pool %1 empty",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "POOL",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Boolean",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns true if the Mana Pool is empty.",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_mana_pool_is_full": {
|
||||||
|
"message0": "Is pool %1 full",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "POOL",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Boolean",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns true if the Mana Pool is full.",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_mana_pool_can_charge_item": {
|
||||||
|
"message0": "Can pool %1 change item",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "POOL",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Boolean",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns true if mode of the Mana Pool is set to charge the items on it.",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_mana_pool_has_items": {
|
||||||
|
"message0": "Is pool %1 has item",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "POOL",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Boolean",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns true if the Mana Pool has at least one item on it.",
|
||||||
|
"inputsInline": true
|
||||||
|
},
|
||||||
|
"advanced_peripherals_botania_mana_pool_get_items": {
|
||||||
|
"message0": "get items from pool %1 ",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "POOL",
|
||||||
|
"check": "Peripheral"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"output": "Array",
|
||||||
|
"colour": 200,
|
||||||
|
"tooltip": "Returns a table with the items lying on the Mana Pool."
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -553,3 +553,138 @@ luaGenerator.forBlock['advanced_peripherals_redstone_integrator_set_analog_outpu
|
|||||||
|
|
||||||
return `${integrator}.setOutput("${side}", ${power})\n`;
|
return `${integrator}.setOutput("${side}", ${power})\n`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Generator for Minecraft: Beacon
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_mc_beacon_get_level'] = function(block, generator) {
|
||||||
|
var beacon = generator.valueToCode(block, 'BEACON', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${beacon}.getLevel()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_mc_beacon_get_primary_effect'] = function(block, generator) {
|
||||||
|
var beacon = generator.valueToCode(block, 'BEACON', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${beacon}.getPrimaryEffect()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_mc_beacon_get_secondary_effect'] = function(block, generator) {
|
||||||
|
var beacon = generator.valueToCode(block, 'BEACON', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${beacon}.getSecondaryEffect()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generator for Minecraft: Note Block
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_mc_note_block_play_note'] = function(block, generator) {
|
||||||
|
var noteblock = generator.valueToCode(block, 'NOTEBLOCK', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return `${noteblock}.playNote()\n`;
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_mc_note_block_get_note'] = function(block, generator) {
|
||||||
|
var noteblock = generator.valueToCode(block, 'NOTEBLOCK', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${beacon}.getNote()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_mc_note_block_change_note_by'] = function(block, generator) {
|
||||||
|
var to = generator.valueToCode(block, 'TO', generator.ORDER_ATOMIC);
|
||||||
|
var noteblock = generator.valueToCode(block, 'NOTEBLOCK', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return `${noteblock}.changeNoteBy(${to})\n`;
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_mc_note_block_change_note'] = function(block, generator) {
|
||||||
|
var noteblock = generator.valueToCode(block, 'NOTEBLOCK', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return `${noteblock}.changeNote()\n`;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generator for Botania: Flowers
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_flowers_get_mana'] = function(block, generator) {
|
||||||
|
var flower = generator.valueToCode(block, 'FLOWER', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${flower}.getMana()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_flowers_get_max_mana'] = function(block, generator) {
|
||||||
|
var flower = generator.valueToCode(block, 'FLOWER', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${flower}.getMaxMana()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_flowers_is_floating'] = function(block, generator) {
|
||||||
|
var flower = generator.valueToCode(block, 'FLOWER', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${flower}.isFloating()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_flowers_is_on_enchanted_soil'] = function(block, generator) {
|
||||||
|
var flower = generator.valueToCode(block, 'FLOWER', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${flower}.isOnEnchantedSoil()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_flowers_is_empty'] = function(block, generator) {
|
||||||
|
var flower = generator.valueToCode(block, 'FLOWER', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${flower}.isEmpty()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_flowers_is_full'] = function(block, generator) {
|
||||||
|
var flower = generator.valueToCode(block, 'FLOWER', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${flower}.isFull()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generator for Botania: Mana Pool
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_mana_pool_get_mana'] = function(block, generator) {
|
||||||
|
var pool = generator.valueToCode(block, 'POOL', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${pool}.getMana()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_mana_pool_get_max_mana'] = function(block, generator) {
|
||||||
|
var pool = generator.valueToCode(block, 'POOL', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${pool}.getMaxMana()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_mana_pool_get_mana_needed'] = function(block, generator) {
|
||||||
|
var pool = generator.valueToCode(block, 'POOL', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${pool}.getManaNeeded()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_mana_pool_is_empty'] = function(block, generator) {
|
||||||
|
var pool = generator.valueToCode(block, 'POOL', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${pool}.isEmpty()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_mana_pool_is_full'] = function(block, generator) {
|
||||||
|
var pool = generator.valueToCode(block, 'POOL', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${pool}.isFull()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_mana_pool_can_charge_item'] = function(block, generator) {
|
||||||
|
var pool = generator.valueToCode(block, 'POOL', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${pool}.canChargeItem()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_mana_pool_has_items'] = function(block, generator) {
|
||||||
|
var pool = generator.valueToCode(block, 'POOL', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${pool}.hasItems()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
luaGenerator.forBlock['advanced_peripherals_botania_mana_pool_get_items'] = function(block, generator) {
|
||||||
|
var pool = generator.valueToCode(block, 'POOL', generator.ORDER_ATOMIC);
|
||||||
|
|
||||||
|
return [`${pool}.getItems()`, luaGenerator.ORDER_NONE];
|
||||||
|
};
|
@ -2,14 +2,16 @@
|
|||||||
"name": "Advanced Peripherals",
|
"name": "Advanced Peripherals",
|
||||||
"author": "DPSoftware Foundation",
|
"author": "DPSoftware Foundation",
|
||||||
"description": "Advanced Peripherals is a mod that adds many useful extensions for CC:Tweaked.",
|
"description": "Advanced Peripherals is a mod that adds many useful extensions for CC:Tweaked.",
|
||||||
"version": "1.0.0",
|
"version": "1.2",
|
||||||
"category": "Mod",
|
"category": "Mod",
|
||||||
"keyword": "mod",
|
"keyword": "mod",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"peripherals": true,
|
"peripherals": true,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [
|
||||||
|
"CCPeripheral"
|
||||||
|
],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
<shadow type="logic_null"></shadow>
|
<shadow type="logic_null"></shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
<block type="advanced_peripherals_chatbox_send_message_to_player">
|
<block type="advanced_peripherals_chatbox_send_toast_to_player">
|
||||||
<value name="TEXT">
|
<value name="TEXT">
|
||||||
<shadow type="text">
|
<shadow type="text">
|
||||||
<field name="TEXT">Hello, world!</field>
|
<field name="TEXT">Hello, world!</field>
|
||||||
@ -107,6 +107,30 @@
|
|||||||
<shadow type="logic_null"></shadow>
|
<shadow type="logic_null"></shadow>
|
||||||
</value>
|
</value>
|
||||||
</block>
|
</block>
|
||||||
|
<block type="advanced_peripherals_chatbox_send_toast_formatted_to_player">
|
||||||
|
<value name="TITLE">
|
||||||
|
<shadow type="text">
|
||||||
|
<field name="TEXT">Hi</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
<value name="PLAYER">
|
||||||
|
<shadow type="text">
|
||||||
|
<field name="TEXT">Player</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
<value name="PREFIX">
|
||||||
|
<shadow type="logic_null"></shadow>
|
||||||
|
</value>
|
||||||
|
<value name="BRACKET">
|
||||||
|
<shadow type="logic_null"></shadow>
|
||||||
|
</value>
|
||||||
|
<value name="BRACKETCOLOR">
|
||||||
|
<shadow type="logic_null"></shadow>
|
||||||
|
</value>
|
||||||
|
<value name="RANGE">
|
||||||
|
<shadow type="logic_null"></shadow>
|
||||||
|
</value>
|
||||||
|
</block>
|
||||||
|
|
||||||
<label text="Energy Detector"></label>
|
<label text="Energy Detector"></label>
|
||||||
<block type="advanced_peripherals_energy_detector_get_transfer_rate"></block>
|
<block type="advanced_peripherals_energy_detector_get_transfer_rate"></block>
|
||||||
@ -462,5 +486,41 @@
|
|||||||
<label text="RS Bridge"></label>
|
<label text="RS Bridge"></label>
|
||||||
|
|
||||||
<label text="Colony Integrator"></label>
|
<label text="Colony Integrator"></label>
|
||||||
|
|
||||||
|
<label text="Minecraft: Beacon"></label>
|
||||||
|
<block type="advanced_peripherals_mc_beacon_get_level"></block>
|
||||||
|
<block type="advanced_peripherals_mc_beacon_get_primary_effect"></block>
|
||||||
|
<block type="advanced_peripherals_mc_beacon_get_secondary_effect"></block>
|
||||||
|
|
||||||
|
<label text="Minecraft: Note Block"></label>
|
||||||
|
<block type="advanced_peripherals_mc_note_block_play_note"></block>
|
||||||
|
<block type="advanced_peripherals_mc_note_block_get_note"></block>
|
||||||
|
<block type="advanced_peripherals_mc_note_block_change_note_by">
|
||||||
|
<value name="TO">
|
||||||
|
<shadow type="math_number">
|
||||||
|
<field name="NUM">0</field>
|
||||||
|
</shadow>
|
||||||
|
</value>
|
||||||
|
</block>
|
||||||
|
<block type="advanced_peripherals_mc_note_block_change_note"></block>
|
||||||
|
|
||||||
|
<label text="Botania: Flowers"></label>
|
||||||
|
<block type="advanced_peripherals_botania_flowers_get_mana"></block>
|
||||||
|
<block type="advanced_peripherals_botania_flowers_get_max_mana"></block>
|
||||||
|
<block type="advanced_peripherals_botania_flowers_is_floating"></block>
|
||||||
|
<block type="advanced_peripherals_botania_flowers_is_on_enchanted_soil"></block>
|
||||||
|
<block type="advanced_peripherals_botania_flowers_is_empty"></block>
|
||||||
|
<block type="advanced_peripherals_botania_flowers_is_full"></block>
|
||||||
|
|
||||||
|
<label text="Botania: Mana Pool"></label>
|
||||||
|
<block type="advanced_peripherals_botania_mana_pool_get_mana"></block>
|
||||||
|
<block type="advanced_peripherals_botania_mana_pool_get_max_mana"></block>
|
||||||
|
<block type="advanced_peripherals_botania_mana_pool_get_mana_needed"></block>
|
||||||
|
<block type="advanced_peripherals_botania_mana_pool_is_empty"></block>
|
||||||
|
<block type="advanced_peripherals_botania_mana_pool_is_full"></block>
|
||||||
|
<block type="advanced_peripherals_botania_mana_pool_can_charge_item"></block>
|
||||||
|
<block type="advanced_peripherals_botania_mana_pool_has_items"></block>
|
||||||
|
<block type="advanced_peripherals_botania_mana_pool_get_items"></block>
|
||||||
|
|
||||||
</category>
|
</category>
|
||||||
</xml>
|
</xml>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": false,
|
"basic": false,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": true,
|
"peripherals": true,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": true,
|
"peripherals": true,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
"peripherals": true,
|
"peripherals": true,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [
|
||||||
|
"CCPeripheral"
|
||||||
|
],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
"peripherals": true,
|
"peripherals": true,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [
|
||||||
|
"CCPeripheral"
|
||||||
|
],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
"peripherals": true,
|
"peripherals": true,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [
|
||||||
|
"CCPeripheral"
|
||||||
|
],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": true,
|
"peripherals": true,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": false,
|
"basic": false,
|
||||||
"adv": false,
|
"adv": false,
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
"peripherals": true,
|
"peripherals": true,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [
|
||||||
|
"CCPeripheral"
|
||||||
|
],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": true,
|
"basic": true,
|
||||||
"adv": true,
|
"adv": true,
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"peripherals": false,
|
"peripherals": false,
|
||||||
"library": false,
|
"library": false,
|
||||||
"require_network": false,
|
"require_network": false,
|
||||||
"dependencies": {},
|
"dependencies": [],
|
||||||
"design_for_computer": {
|
"design_for_computer": {
|
||||||
"basic": false,
|
"basic": false,
|
||||||
"adv": false,
|
"adv": false,
|
||||||
|
23
index.js
23
index.js
@ -6,14 +6,15 @@ const path = require('path');
|
|||||||
const pino = require('pino')
|
const pino = require('pino')
|
||||||
const pretty = require('pino-pretty');
|
const pretty = require('pino-pretty');
|
||||||
const https = require('node:https');
|
const https = require('node:https');
|
||||||
const LocalStorage = require('node-localstorage').LocalStorage
|
|
||||||
const ipc = ipcMain
|
const ipc = ipcMain
|
||||||
|
|
||||||
const logger = pino(pretty())
|
const logger = pino(pretty())
|
||||||
const localStorage = new LocalStorage('.');
|
|
||||||
|
|
||||||
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
|
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
|
||||||
|
|
||||||
|
var ena_splash = process.env['CCIDE_ENABLE_MAIN_SPLASH'] == 'true';
|
||||||
|
|
||||||
var currentprojectpath = null;
|
var currentprojectpath = null;
|
||||||
var currentprojectname = null;
|
var currentprojectname = null;
|
||||||
var currentprojectopen = false;
|
var currentprojectopen = false;
|
||||||
@ -111,12 +112,16 @@ app.whenReady().then(async () => {
|
|||||||
logger.error('Error in update check:', error);
|
logger.error('Error in update check:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Version in github: " + gitver)
|
|
||||||
logger.info("Current version: " + version)
|
logger.info("Current version: " + version)
|
||||||
|
logger.info("Version in github: " + gitver)
|
||||||
|
|
||||||
|
|
||||||
const normalizedAppVersion = normalizeVersion(version);
|
const normalizedAppVersion = normalizeVersion(version);
|
||||||
const normalizedReleaseVersion = normalizeVersion(gitver);
|
|
||||||
|
|
||||||
|
if (!gitver) {
|
||||||
|
logger.error("Can't check update")
|
||||||
|
} else {
|
||||||
|
const normalizedReleaseVersion = normalizeVersion(gitver);
|
||||||
if (normalizedAppVersion >= normalizedReleaseVersion) {
|
if (normalizedAppVersion >= normalizedReleaseVersion) {
|
||||||
logger.info("Software is up-to-date.");
|
logger.info("Software is up-to-date.");
|
||||||
} else {
|
} else {
|
||||||
@ -154,6 +159,7 @@ app.whenReady().then(async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.info("Initializing main windows...")
|
logger.info("Initializing main windows...")
|
||||||
splash.webContents.send("change-status", "Initializing main windows...")
|
splash.webContents.send("change-status", "Initializing main windows...")
|
||||||
@ -168,7 +174,7 @@ app.whenReady().then(async () => {
|
|||||||
enableRemoteModule: true,
|
enableRemoteModule: true,
|
||||||
contextIsolation: false,
|
contextIsolation: false,
|
||||||
},
|
},
|
||||||
show: false,
|
show: ena_splash,
|
||||||
center: true,
|
center: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -218,9 +224,12 @@ app.whenReady().then(async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipc.on('update-log-status', (event, status) => {
|
ipc.on('update-log-status', (event, status) => {
|
||||||
logger.info(status)
|
logger.info(status);
|
||||||
if (!appstarted) {
|
if (!appstarted) {
|
||||||
splash.webContents.send("change-status", status)
|
splash.webContents.send("change-status", status);
|
||||||
|
}
|
||||||
|
if (status == "Downloading blocks...") {
|
||||||
|
win.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
10639
package-lock.json
generated
10639
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@ -1,20 +1,31 @@
|
|||||||
{
|
{
|
||||||
"name": "ccide",
|
"name": "ccide",
|
||||||
"version": "1.4",
|
"version": "1.6.0",
|
||||||
"description": "ComputerCraft mod virtual lua IDE",
|
"description": "ComputerCraft mod virtual lua IDE",
|
||||||
"main": "index.js",
|
"main": "dist/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "electron .",
|
"dev": "title ccIDE && electron .",
|
||||||
"build": "electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist --overwrite && for /d %i in (dist\\ccIDE-*) do copy package.json %i\\",
|
"build": "title building ccIDE && electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist --overwrite && for /d %i in (dist\\ccIDE-*) do copy package.json %i\\",
|
||||||
"build_debug": "electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist_debug --overwrite --debug && for /d %i in (dist_debug\\ccIDE-*) do copy package.json %i\\"
|
"build_debug": "title building ccIDE (Debug) && electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist_debug --overwrite --debug && for /d %i in (dist_debug\\ccIDE-*) do copy package.json %i\\",
|
||||||
|
"new_build": "webpack --config webpack.main.config.js && webpack --config webpack.renderer.config.js",
|
||||||
|
"dist": "electron-builder"
|
||||||
},
|
},
|
||||||
"author": "DPSoftware Foundation",
|
"author": "DPSoftware Foundation",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"electron": "^31.1.0"
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
|
"electron": "^31.7.7",
|
||||||
|
"electron-builder": "^25.1.8",
|
||||||
|
"html-webpack-plugin": "^5.6.3",
|
||||||
|
"terser-webpack-plugin": "^5.3.11",
|
||||||
|
"webpack": "^5.97.1",
|
||||||
|
"webpack-cli": "^6.0.1",
|
||||||
|
"webpack-merge": "^6.0.1",
|
||||||
|
"webpack-node-externals": "^3.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blockly/plugin-workspace-search": "^9.0.5",
|
"@blockly/plugin-workspace-search": "^9.0.5",
|
||||||
|
"@blockly/theme-dark": "^7.0.7",
|
||||||
"@electron/remote": "^2.1.2",
|
"@electron/remote": "^2.1.2",
|
||||||
"blockly": "^11.1.1",
|
"blockly": "^11.1.1",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
@ -23,6 +34,19 @@
|
|||||||
"open": "^10.1.0",
|
"open": "^10.1.0",
|
||||||
"pino": "^9.3.2",
|
"pino": "^9.3.2",
|
||||||
"pino-pretty": "^11.2.2",
|
"pino-pretty": "^11.2.2",
|
||||||
|
"toastify-js": "^1.12.0",
|
||||||
|
"unzipper": "^0.12.3",
|
||||||
"xmldom": "^0.6.0"
|
"xmldom": "^0.6.0"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"appId": "dev.dpsoftware.ccide",
|
||||||
|
"productName": "ccIDE",
|
||||||
|
"files": [
|
||||||
|
"dist/**/*",
|
||||||
|
"node_modules/**/*"
|
||||||
|
],
|
||||||
|
"directories": {
|
||||||
|
"output": "release"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
readme.md
30
readme.md
@ -6,34 +6,18 @@ special thank for [ccblockly](https://github.com/Mirka1405/ccblockly) for idea
|
|||||||

|

|
||||||
|
|
||||||
# Quick Start
|
# Quick Start
|
||||||
1. install nodejs and git
|
1. install nodejs and git.
|
||||||
2. git clone cd to this project
|
2. git clone and cd to this project .
|
||||||
3. Install dependency use `npm install .`
|
3. Install dependency use `npm install .`.
|
||||||
4. To run this IDE use `npm run dev` or if you using windows you can use `run.bat` to run it.
|
4. To run this IDE use `npm run dev` or if you using windows you can use `run.bat` to run it.
|
||||||
5. Done!
|
|
||||||
|
|
||||||
## Install Remote code into computercraft
|
## Install Remote code into computercraft
|
||||||
it very simple! to install Remote code.
|
it very simple! to install Remote code.
|
||||||
### Run from URL
|
|
||||||
for advanced computer/pocket/turtle
|
|
||||||
```
|
```
|
||||||
wget run https://raw.githubusercontent.com/DPSoftware-Foundation/ccIDE/main/advremote.lua
|
wget https://raw.githubusercontent.com/DPSoftware-Foundation/ccIDE/main/startup.lua
|
||||||
```
|
|
||||||
for non advance computer/pocket/turtle
|
|
||||||
```
|
|
||||||
wget run https://raw.githubusercontent.com/DPSoftware-Foundation/ccIDE/main/remote.lua
|
|
||||||
```
|
|
||||||
### Download and Run
|
|
||||||
for advanced computer/pocket/turtle
|
|
||||||
```
|
|
||||||
wget https://raw.githubusercontent.com/DPSoftware-Foundation/ccIDE/main/advremote.lua advremote.lua
|
|
||||||
advremote
|
|
||||||
```
|
|
||||||
for non advanced computer/pocket/turtle
|
|
||||||
```
|
|
||||||
wget https://raw.githubusercontent.com/DPSoftware-Foundation/ccIDE/main/remote.lua remote.lua
|
|
||||||
remote
|
|
||||||
```
|
```
|
||||||
|
And restart the computer.
|
||||||
|
|
||||||
If error "Domain not permitted" try [this solution](https://github.com/cc-tweaked/CC-Tweaked/discussions/626#discussioncomment-241924).
|
If error "Domain not permitted" try [this solution](https://github.com/cc-tweaked/CC-Tweaked/discussions/626#discussioncomment-241924).
|
||||||
|
|
||||||
## official support library, peripheral and module function
|
## official support library, peripheral and module function
|
||||||
@ -150,7 +134,7 @@ https://github.com/user-attachments/assets/195231d4-8fd8-4101-8068-70bc038a5c4f
|
|||||||
https://github.com/user-attachments/assets/8f114cfa-d87c-47d0-a670-a13dc975ab06
|
https://github.com/user-attachments/assets/8f114cfa-d87c-47d0-a670-a13dc975ab06
|
||||||
|
|
||||||
# For adapting in other project
|
# For adapting in other project
|
||||||
This project is based for every block based IDE from DPSoftware Foundation
|
This project is for every block based IDE from DPSoftware Foundation.
|
||||||
|
|
||||||
# License
|
# License
|
||||||
This project is licensed under the [GPL v3 License](https://github.com/DPSoftware-Foundation/ccIDE/blob/main/LICENSE).
|
This project is licensed under the [GPL v3 License](https://github.com/DPSoftware-Foundation/ccIDE/blob/main/LICENSE).
|
||||||
|
48
remote.lua
48
remote.lua
@ -1,48 +0,0 @@
|
|||||||
local ws = assert(http.websocket("ws://127.0.0.1:5133"))
|
|
||||||
print("connected to server")
|
|
||||||
|
|
||||||
local id
|
|
||||||
local isrunning = true
|
|
||||||
|
|
||||||
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
|
|
||||||
print("Received message:", message)
|
|
||||||
if message == "ping" then
|
|
||||||
ws.send("pong")
|
|
||||||
elseif message == "sendcode" then
|
|
||||||
local file = io.open("main.lua", "w")
|
|
||||||
print("waiting for code")
|
|
||||||
local filedata, error = ws.receive()
|
|
||||||
file:write(filedata)
|
|
||||||
file:close()
|
|
||||||
elseif message == "runcode" then
|
|
||||||
shell.run("main")
|
|
||||||
elseif message == "exit" then
|
|
||||||
print("Exiting...")
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
print("WebSocket error:", error)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
parallel.waitForAny(exitcheck, main)
|
|
||||||
print("Exited")
|
|
2
run.bat
2
run.bat
@ -1,3 +1,5 @@
|
|||||||
@echo off
|
@echo off
|
||||||
title Starting ccIDE
|
title Starting ccIDE
|
||||||
|
start "" cmd /c "npm cache clean --force"
|
||||||
|
timeout 2
|
||||||
npm run dev
|
npm run dev
|
@ -1,11 +1,110 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const https = require('https');
|
||||||
|
const unzipper = require('unzipper');
|
||||||
const { DOMParser, XMLSerializer } = require('xmldom');
|
const { DOMParser, XMLSerializer } = require('xmldom');
|
||||||
|
|
||||||
|
|
||||||
const peripheralsfolder = path.join(__dirname, "../blocks");
|
const peripheralsfolder = path.join(__dirname, "../blocks");
|
||||||
|
|
||||||
const fallbackImagePath = path.join(__dirname, '..', 'assets', 'noimagefallback.png'); // Path to fallback image
|
const fallbackImagePath = path.join(__dirname, '..', 'assets', 'noimagefallback.png'); // Path to fallback image
|
||||||
|
|
||||||
|
if (!fs.existsSync(peripheralsfolder)) {
|
||||||
|
// If it doesn't exist, create it
|
||||||
|
fs.mkdirSync(peripheralsfolder, { recursive: true });
|
||||||
|
console.log('Block Folder created');
|
||||||
|
}
|
||||||
|
|
||||||
|
let progressBar = document.getElementById('progressBarloading');
|
||||||
|
let blocks_url = "https://cdn.damp11113.xyz/file/zip/ccide/blockslastest.zip?dl=1"
|
||||||
|
|
||||||
|
function isBlocksFolderEmpty() {
|
||||||
|
try {
|
||||||
|
const files = fs.readdirSync(peripheralsfolder);
|
||||||
|
return files.length === 0; // Returns true if the folder is empty
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error reading folder:', err);
|
||||||
|
return false; // Return false or handle error as needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function downloadBlocks() {
|
||||||
|
try {
|
||||||
|
progressBar.style.display = 'inline-block';
|
||||||
|
// Create the output directory if it doesn't exist
|
||||||
|
if (!fs.existsSync(peripheralsfolder)) {
|
||||||
|
fs.mkdirSync(peripheralsfolder, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Downloading blocks...');
|
||||||
|
|
||||||
|
const zipFilePath = path.join(peripheralsfolder, 'blocks.zip');
|
||||||
|
|
||||||
|
// Download the file as a Promise
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
https.get(blocks_url, (response) => {
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
reject(new Error(`Download failed with status code ${response.statusCode}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalBytes = parseInt(response.headers['content-length'], 10);
|
||||||
|
let downloadedBytes = 0;
|
||||||
|
|
||||||
|
const file = fs.createWriteStream(zipFilePath);
|
||||||
|
|
||||||
|
response.on('data', (chunk) => {
|
||||||
|
downloadedBytes += chunk.length;
|
||||||
|
const percentCompleted = Math.round((downloadedBytes / totalBytes) * 100);
|
||||||
|
progressBar.value = percentCompleted;
|
||||||
|
progressBar.innerText = percentCompleted + '%'; // Fallback text
|
||||||
|
process.stdout.write(`Download progress: ${percentCompleted}%\r`);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.pipe(file);
|
||||||
|
|
||||||
|
file.on('finish', () => {
|
||||||
|
file.close();
|
||||||
|
console.log('\nFile downloaded successfully.');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
file.on('error', (error) => {
|
||||||
|
fs.unlinkSync(zipFilePath);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
}).on('error', (error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Unzipping file...');
|
||||||
|
|
||||||
|
// Unzip the file as a Promise
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
fs.createReadStream(zipFilePath)
|
||||||
|
.pipe(unzipper.Extract({ path: peripheralsfolder }))
|
||||||
|
.on('close', () => {
|
||||||
|
console.log('File unzipped successfully.');
|
||||||
|
fs.unlinkSync(zipFilePath); // Delete the zip file after extraction
|
||||||
|
console.log('Zip file deleted.');
|
||||||
|
|
||||||
|
console.log('Downloaded blocks');
|
||||||
|
progressBar.style.display = 'none';
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.on('error', (error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error downloading or unzipping file:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const defineicon = {
|
const defineicon = {
|
||||||
computer: {
|
computer: {
|
||||||
@ -41,23 +140,26 @@ function mergeXml(xml1, xml2) {
|
|||||||
return mergedXml;
|
return mergedXml;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadperipheral(workspace, currenttoolbar, peripherals) {
|
function loadperipheral(workspace, currenttoolbar, peripherals, usedlibinproject) {
|
||||||
console.log(`Importing ${peripherals} blocks`)
|
if (!usedlibinproject.includes(peripherals)) {
|
||||||
|
try {
|
||||||
|
console.log(`Importing ${peripherals} blocks`);
|
||||||
|
|
||||||
const filePath = path.join(peripheralsfolder, peripherals);
|
const filePath = path.join(peripheralsfolder, peripherals);
|
||||||
const jsonfilePath = path.join(filePath, "block_design.json");
|
const jsonfilePath = path.join(filePath, "block_design.json");
|
||||||
const xmlfilePath = path.join(filePath, "toolbox.xml");
|
const xmlfilePath = path.join(filePath, "toolbox.xml");
|
||||||
const generatorfilePath = path.join(filePath, "generator.js"); // Path to generator.js
|
const generatorfilePath = path.join(filePath, "generator.js");
|
||||||
|
const indexfilePath = path.join(filePath, "index.json");
|
||||||
|
|
||||||
// Load generator.js
|
// Synchronously read and parse the index.json file
|
||||||
// Load blocks from block_design.json
|
const indexcontent = JSON.parse(fs.readFileSync(indexfilePath, 'utf8'));
|
||||||
fs.readFile(jsonfilePath, 'utf-8', (err, data) => {
|
const dependencies = indexcontent.dependencies;
|
||||||
if (err) {
|
dependencies.forEach((dependency) => {
|
||||||
console.error('Error loading JSON file:', err);
|
currenttoolbar = loadperipheral(workspace, currenttoolbar, dependency, usedlibinproject);
|
||||||
return;
|
});
|
||||||
}
|
|
||||||
try {
|
// Synchronously load and parse block_design.json
|
||||||
const blocksJson = JSON.parse(data);
|
const blocksJson = JSON.parse(fs.readFileSync(jsonfilePath, 'utf8'));
|
||||||
for (const blockId in blocksJson) {
|
for (const blockId in blocksJson) {
|
||||||
if (blocksJson.hasOwnProperty(blockId)) {
|
if (blocksJson.hasOwnProperty(blockId)) {
|
||||||
Blockly.Blocks[blockId] = {
|
Blockly.Blocks[blockId] = {
|
||||||
@ -67,25 +169,28 @@ function loadperipheral(workspace, currenttoolbar, peripherals) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
document.getElementById('statusMessage').textContent = 'Error parsing JSON file: ' + e;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Load and merge new toolbox XML
|
// Synchronously load and merge new toolbox XML
|
||||||
const toolbar = fs.readFileSync(xmlfilePath, 'utf8');
|
const toolbar = fs.readFileSync(xmlfilePath, 'utf8');
|
||||||
const newxml = mergeXml(currenttoolbar, toolbar);
|
const newxml = mergeXml(currenttoolbar, toolbar);
|
||||||
|
|
||||||
workspace.updateToolbox(newxml);
|
workspace.updateToolbox(newxml);
|
||||||
|
|
||||||
document.getElementById('statusMessage').textContent = `Loaded ${peripherals}`;
|
fireNotify(`Loaded ${peripherals}`, "success")
|
||||||
|
|
||||||
|
// Synchronously require generator.js
|
||||||
require(generatorfilePath); // This will execute generator.js if it's a Node.js module
|
require(generatorfilePath); // This will execute generator.js if it's a Node.js module
|
||||||
|
|
||||||
console.log(`Loaded ${peripherals} blocks`)
|
console.log(`Loaded ${peripherals} blocks`);
|
||||||
|
usedlibinproject.push(peripherals);
|
||||||
|
|
||||||
return newxml;
|
return newxml;
|
||||||
|
} catch (e) {
|
||||||
|
fireNotify(`Can't Import ${peripherals}: ${e}`, "error")
|
||||||
|
ipc.send("error", `Can't Import ${peripherals}: ${e}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return currenttoolbar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractFolderName(path) {
|
function extractFolderName(path) {
|
||||||
@ -119,7 +224,6 @@ function addimageiconinfo(div, src, tiptool) {
|
|||||||
|
|
||||||
function scanindex() {
|
function scanindex() {
|
||||||
let foundedpackages = 0;
|
let foundedpackages = 0;
|
||||||
document.getElementById('statusMessage').textContent = "Scanning Packages...";
|
|
||||||
// clear all item in libcontainer
|
// clear all item in libcontainer
|
||||||
document.getElementById('libcontainer').innerHTML = "";
|
document.getElementById('libcontainer').innerHTML = "";
|
||||||
|
|
||||||
@ -167,9 +271,15 @@ function scanindex() {
|
|||||||
|
|
||||||
// Create the title element
|
// Create the title element
|
||||||
const title = document.createElement('h3');
|
const title = document.createElement('h3');
|
||||||
title.textContent = jsonData.name + ` [v${jsonData.version} by ${jsonData.author}]`;
|
title.textContent = jsonData.name;
|
||||||
libraryDetails.appendChild(title);
|
libraryDetails.appendChild(title);
|
||||||
|
|
||||||
|
// Create the credit and version element
|
||||||
|
const cv = document.createElement('p');
|
||||||
|
cv.classList.add('library-details-cv');
|
||||||
|
cv.textContent = `v${jsonData.version} by ${jsonData.author}`;
|
||||||
|
libraryDetails.appendChild(cv);
|
||||||
|
|
||||||
// Create the description element
|
// Create the description element
|
||||||
const description = document.createElement('p');
|
const description = document.createElement('p');
|
||||||
description.innerHTML = jsonData.description;
|
description.innerHTML = jsonData.description;
|
||||||
@ -224,14 +334,12 @@ function scanindex() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('statusMessage').textContent = `Founded ${foundedpackages} Packages`;
|
fireNotify(`Founded ${foundedpackages} Packages`, "success")
|
||||||
setTimeout(() => {
|
|
||||||
document.getElementById('statusMessage').textContent = `Ready`;
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
loadperipheral,
|
loadperipheral,
|
||||||
scanindex
|
scanindex,
|
||||||
|
isBlocksFolderEmpty,
|
||||||
|
downloadBlocks
|
||||||
}
|
}
|
245
src/ccRemote.js
245
src/ccRemote.js
@ -7,109 +7,258 @@ class CCRemote {
|
|||||||
host: ip
|
host: ip
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.clients = new Map(); // Map to track client data (numeric IDs)
|
||||||
|
this.clientIdCounter = 0; // Counter for numeric client IDs
|
||||||
|
|
||||||
console.log("Remote server is started");
|
console.log("Remote server is started");
|
||||||
|
fireNotify(
|
||||||
|
"Remote server started, waiting for clients to connect...",
|
||||||
|
"info"
|
||||||
|
);
|
||||||
|
|
||||||
this.socket.on('connection', (ws) => {
|
this.socket.on('connection', (ws) => {
|
||||||
|
const clientId = this.clientIdCounter++;
|
||||||
|
this.clients.set(clientId, { ws, isAlive: true, name: `Client-${clientId}`, clientInfo: null });
|
||||||
|
|
||||||
|
if (this.clients.size >= 0) {
|
||||||
document.getElementById("navbar-button-computer-disconnect").disabled = false;
|
document.getElementById("navbar-button-computer-disconnect").disabled = false;
|
||||||
document.getElementById("navbar-button-computer-run").disabled = false;
|
document.getElementById("navbar-button-computer-run").disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('statusMessage').textContent = "Computer connected";
|
console.log(`Client ${clientId} connected.`);
|
||||||
setTimeout(() => {
|
fireNotify(`Client ${clientId} connected`, "success");
|
||||||
document.getElementById('statusMessage').textContent = `Ready`;
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
console.log('WebSocket connection established.');
|
// Send "info" command to the client immediately upon connection
|
||||||
|
this.sendCommandToClient(clientId, 'info', true);
|
||||||
|
|
||||||
// Set up heartbeat
|
|
||||||
ws.isAlive = true;
|
|
||||||
ws.on('pong', () => {
|
ws.on('pong', () => {
|
||||||
ws.isAlive = true;
|
this.clients.get(clientId).isAlive = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on('message', (message) => {
|
ws.on('message', (message) => {
|
||||||
console.log(`Received message => ${message}`);
|
console.log(`Message from Client ${clientId}: ${message}`);
|
||||||
|
// Handle info response
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(message);
|
||||||
|
|
||||||
|
if (data.OSVersion && typeof data.OSVersion === 'string' &&
|
||||||
|
data.Name && typeof data.Name === 'string' &&
|
||||||
|
typeof data.ID === 'number' &&
|
||||||
|
typeof data.uptime === 'number' &&
|
||||||
|
typeof data.Type === 'number') {
|
||||||
|
|
||||||
|
// Update clientInfo with the received data
|
||||||
|
this.clients.get(clientId).clientInfo = data;
|
||||||
|
console.log(`Client ${clientId} info updated:`, data);
|
||||||
|
} else {
|
||||||
|
console.log(`Invalid data format from Client ${clientId}:`, data);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error parsing message from Client ${clientId}:`, error);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ws.on('close', () => {
|
ws.on('close', () => {
|
||||||
|
console.log(`Client ${clientId} disconnected.`);
|
||||||
|
this.clients.delete(clientId);
|
||||||
|
fireNotify(`Client ${clientId} disconnected`, "warning");
|
||||||
|
|
||||||
|
if (this.clients.size === 0) {
|
||||||
document.getElementById("navbar-button-computer-disconnect").disabled = true;
|
document.getElementById("navbar-button-computer-disconnect").disabled = true;
|
||||||
document.getElementById("navbar-button-computer-run").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) => {
|
ws.on('error', (error) => {
|
||||||
console.error('Client error:', error);
|
console.error(`Client ${clientId} error:`, error);
|
||||||
|
fireNotify(`Error with Client ${clientId}: ${error.message}`, "error");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ping clients every 30 seconds to check if they are alive
|
// Ping clients every 30 seconds to check if they are alive
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
this.socket.clients.forEach((ws) => {
|
for (const [clientId, clientData] of this.clients.entries()) {
|
||||||
if (ws.isAlive === false) {
|
if (clientData.isAlive === false) {
|
||||||
console.log('Client did not respond to ping, terminating connection.');
|
console.log(`Client ${clientId} did not respond to ping, terminating connection.`);
|
||||||
return ws.terminate();
|
fireNotify(`Client ${clientId} did not respond to ping, disconnected`, "warning");
|
||||||
|
clientData.ws.terminate();
|
||||||
|
this.clients.delete(clientId);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.isAlive = false;
|
clientData.isAlive = false;
|
||||||
ws.ping();
|
clientData.ws.ping();
|
||||||
});
|
}
|
||||||
}, 1000);
|
}, 30000);
|
||||||
|
|
||||||
this.socket.on('close', () => {
|
this.socket.on('close', () => {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
console.log('WebSocket server closed.');
|
console.log('WebSocket server closed.');
|
||||||
|
fireNotify("WebSocket server closed.", "info");
|
||||||
});
|
});
|
||||||
|
|
||||||
this.socket.on('error', (error) => {
|
this.socket.on('error', (error) => {
|
||||||
console.error('WebSocket server error:', error);
|
console.error('WebSocket server error:', error);
|
||||||
|
fireNotify(`WebSocket server error: ${error.message}`, "error");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List all connected clients with their IDs, names, and clientInfo
|
||||||
|
// List all connected clients with their IDs, names, and clientInfo
|
||||||
|
async listClients() {
|
||||||
|
const clientList = [];
|
||||||
|
|
||||||
|
// Create an array of promises for fetching client info
|
||||||
|
const infoPromises = [];
|
||||||
|
|
||||||
|
// Loop over each client and trigger 'info' command to get the latest information
|
||||||
|
for (const [clientId, clientData] of this.clients.entries()) {
|
||||||
|
if (clientData.ws.readyState === WebSocket.OPEN) {
|
||||||
|
const infoPromise = new Promise((resolve) => {
|
||||||
|
// Set a timeout to handle cases where no response is received
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
resolve({ id: clientId, name: clientData.name, info: null });
|
||||||
|
}, 5000); // Wait 5 seconds for a response
|
||||||
|
|
||||||
|
// Listen for the response from the client
|
||||||
|
const messageHandler = (message) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(message);
|
||||||
|
if (data.OSVersion && typeof data.OSVersion === 'string' &&
|
||||||
|
data.Name && typeof data.Name === 'string' &&
|
||||||
|
typeof data.ID === 'number' &&
|
||||||
|
typeof data.uptime === 'number' &&
|
||||||
|
typeof data.Type === 'number') {
|
||||||
|
|
||||||
|
// Resolve with the valid data
|
||||||
|
resolve({ id: clientId, name: clientData.name, info: data });
|
||||||
|
} else {
|
||||||
|
resolve({ id: clientId, name: clientData.name, info: null });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
resolve({ id: clientId, name: clientData.name, info: null });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send the "info" command to the client
|
||||||
|
this.sendCommandToClient(clientId, 'info', true);
|
||||||
|
|
||||||
|
// Attach the handler for this specific client
|
||||||
|
clientData.ws.on('message', messageHandler);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add the promise to the array
|
||||||
|
infoPromises.push(infoPromise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all promises to resolve (all client info to be updated)
|
||||||
|
const resolvedClientInfo = await Promise.all(infoPromises);
|
||||||
|
|
||||||
|
// Construct the final list of clients with updated information
|
||||||
|
for (const clientInfo of resolvedClientInfo) {
|
||||||
|
clientList.push(clientInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clientList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if any client is connected
|
||||||
isClientConnect() {
|
isClientConnect() {
|
||||||
for (const client of this.socket.clients) {
|
return this.clients.size > 0;
|
||||||
if (client.readyState === WebSocket.OPEN) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendCommand(command) {
|
// Send code to all clients
|
||||||
this.socket.clients.forEach((client) => {
|
sendCode(code) {
|
||||||
if (client.readyState === WebSocket.OPEN) {
|
this.clients.forEach((clientData, clientId) => {
|
||||||
client.send(command);
|
if (clientData.ws.readyState === WebSocket.OPEN) {
|
||||||
}
|
clientData.ws.send("sendcode");
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sendCode(Code) {
|
|
||||||
this.socket.clients.forEach((client) => {
|
|
||||||
if (client.readyState === WebSocket.OPEN) {
|
|
||||||
client.send("sendcode");
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
client.send(Code);
|
clientData.ws.send(code);
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send code to a specific client
|
||||||
|
sendCodeToClient(clientId, code) {
|
||||||
|
const client = this.clients.get(clientId);
|
||||||
|
if (!client || client.ws.readyState !== WebSocket.OPEN) {
|
||||||
|
console.error(`Client ${clientId} is not available or not connected.`);
|
||||||
|
fireNotify(`Client ${clientId} is not connected.`, "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.ws.send("sendcode");
|
||||||
|
setTimeout(() => {
|
||||||
|
client.ws.send(code);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run code on all clients
|
||||||
runCode() {
|
runCode() {
|
||||||
this.socket.clients.forEach((client) => {
|
this.clients.forEach((clientData, clientId) => {
|
||||||
if (client.readyState === WebSocket.OPEN) {
|
if (clientData.ws.readyState === WebSocket.OPEN) {
|
||||||
client.send("runcode");
|
clientData.ws.send("runcode");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run code on a specific client
|
||||||
|
runCodeOnClient(clientId) {
|
||||||
|
const client = this.clients.get(clientId);
|
||||||
|
if (!client || client.ws.readyState !== WebSocket.OPEN) {
|
||||||
|
console.error(`Client ${clientId} is not available or not connected.`);
|
||||||
|
fireNotify(`Client ${clientId} is not connected.`, "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.ws.send("runcode");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disconnect all clients
|
||||||
disconnectAllClients() {
|
disconnectAllClients() {
|
||||||
this.socket.clients.forEach((client) => {
|
this.clients.forEach((clientData, clientId) => {
|
||||||
if (client.readyState === WebSocket.OPEN) {
|
if (clientData.ws.readyState === WebSocket.OPEN) {
|
||||||
client.close();
|
clientData.ws.send("exit");
|
||||||
|
clientData.ws.close();
|
||||||
|
fireNotify(`Client ${clientId} disconnected`, "warning");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.clients.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a command to a specific client
|
||||||
|
sendCommandToClient(clientId, command, expectResponse = false) {
|
||||||
|
const client = this.clients.get(clientId);
|
||||||
|
if (!client || client.ws.readyState !== WebSocket.OPEN) {
|
||||||
|
console.error(`Client ${clientId} is not available or not connected.`);
|
||||||
|
fireNotify(`Client ${clientId} is not connected.`, "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.ws.send(command);
|
||||||
|
|
||||||
|
if (expectResponse) {
|
||||||
|
client.ws.on('message', (response) => {
|
||||||
|
console.log(`Response from Client ${clientId}: ${response}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a command to all clients
|
||||||
|
sendCommandToAll(command, expectResponse = false) {
|
||||||
|
for (const [clientId, clientData] of this.clients.entries()) {
|
||||||
|
if (clientData.ws.readyState === WebSocket.OPEN) {
|
||||||
|
clientData.ws.send(command);
|
||||||
|
|
||||||
|
if (expectResponse) {
|
||||||
|
clientData.ws.on('message', (response) => {
|
||||||
|
console.log(`Response from Client ${clientId}: ${response}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
122
src/codegen.js
122
src/codegen.js
@ -9,6 +9,16 @@ const circles = document.querySelectorAll(".circle");
|
|||||||
let upcurrentActive = 1;
|
let upcurrentActive = 1;
|
||||||
let uploadError = false; // Flag to track if there's an error
|
let uploadError = false; // Flag to track if there's an error
|
||||||
|
|
||||||
|
const defineicon = {
|
||||||
|
5: path.join(__dirname, '..', 'assets', 'basic_computer.png'),
|
||||||
|
6: path.join(__dirname, '..', 'assets', 'adv_computer.png'),
|
||||||
|
7: path.join(__dirname, '..', 'assets', 'command_computer.png'),
|
||||||
|
2: path.join(__dirname, '..', 'assets', 'pocket_computer.png'),
|
||||||
|
4: path.join(__dirname, '..', 'assets', 'adv_pocket_computer.png'),
|
||||||
|
1: path.join(__dirname, '..', 'assets', 'turtle.png'),
|
||||||
|
3: path.join(__dirname, '..', 'assets', 'adv_turtle.png')
|
||||||
|
}
|
||||||
|
|
||||||
const uploadUpdateProgress = () => {
|
const uploadUpdateProgress = () => {
|
||||||
circles.forEach((circle, index) => {
|
circles.forEach((circle, index) => {
|
||||||
if (index < upcurrentActive) {
|
if (index < upcurrentActive) {
|
||||||
@ -34,7 +44,6 @@ const uploadUpdateProgress = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function clientexit() {
|
function clientexit() {
|
||||||
ccInstance.sendCommand("exit")
|
|
||||||
ccInstance.disconnectAllClients();
|
ccInstance.disconnectAllClients();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,15 +51,17 @@ function gencodeonly() {
|
|||||||
return luaGenerator.workspaceToCode(workspace);
|
return luaGenerator.workspaceToCode(workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let selectedClientId = null;
|
||||||
|
|
||||||
async function gencode() {
|
async function gencode() {
|
||||||
console.log("Starting generate code")
|
console.log("Starting generate code")
|
||||||
document.getElementById('upload-popup').style.display = 'block';
|
document.getElementById('upload-popup').style.display = 'block';
|
||||||
upcurrentActive = 1;
|
upcurrentActive = 1;
|
||||||
uploadError = false;
|
uploadError = false;
|
||||||
uploadUpdateProgress();
|
uploadUpdateProgress();
|
||||||
// compile/convert code
|
|
||||||
|
|
||||||
console.log("Generating code...")
|
// Compile/convert code
|
||||||
|
console.log("Generating code...");
|
||||||
upcurrentActive++;
|
upcurrentActive++;
|
||||||
uploadUpdateProgress();
|
uploadUpdateProgress();
|
||||||
document.getElementById('upload-status').textContent = "Generating code";
|
document.getElementById('upload-status').textContent = "Generating code";
|
||||||
@ -61,37 +72,108 @@ async function gencode() {
|
|||||||
uploadError = true;
|
uploadError = true;
|
||||||
uploadUpdateProgress();
|
uploadUpdateProgress();
|
||||||
document.getElementById('upload-status').textContent = e;
|
document.getElementById('upload-status').textContent = e;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
upcurrentActive++;
|
upcurrentActive++;
|
||||||
uploadUpdateProgress();
|
uploadUpdateProgress();
|
||||||
if (ccInstance.isClientConnect()) {
|
|
||||||
// upload to computercraft with remote
|
|
||||||
console.log("Uploading code to machine...")
|
|
||||||
document.getElementById('upload-status').textContent = "Uploading code to machine";
|
|
||||||
ccInstance.sendCode(code);
|
|
||||||
await delay(500)
|
|
||||||
|
|
||||||
// execute with remote
|
if (ccInstance.isClientConnect()) {
|
||||||
console.log("Executing code in machine...")
|
const clients = await ccInstance.listClients();
|
||||||
|
document.getElementById('upload-status').innerHTML = "";
|
||||||
|
|
||||||
|
const ClientLists = document.createElement('div');
|
||||||
|
ClientLists.classList.add("library-content");
|
||||||
|
|
||||||
|
clients.forEach(client => {
|
||||||
|
console.log(`Info:`, client.info);
|
||||||
|
|
||||||
|
const ClientItem = document.createElement('div');
|
||||||
|
ClientItem.classList.add('library-item', 'overflow-auto', 'library-container');
|
||||||
|
ClientItem.setAttribute('data-clientid', client.id);
|
||||||
|
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.classList.add('libimage');
|
||||||
|
img.src = defineicon[client.info.Type];
|
||||||
|
ClientItem.appendChild(img);
|
||||||
|
|
||||||
|
const ClientDetails = document.createElement('div');
|
||||||
|
ClientDetails.classList.add('library-details');
|
||||||
|
|
||||||
|
const title = document.createElement('h3');
|
||||||
|
title.textContent = client.info.Name;
|
||||||
|
ClientDetails.appendChild(title);
|
||||||
|
|
||||||
|
const description = document.createElement('p');
|
||||||
|
description.innerHTML = `OS: ${client.info.OSVersion} | ID: ${client.info.ID} | Uptime: ${client.info.uptime}s`;
|
||||||
|
ClientDetails.appendChild(description);
|
||||||
|
|
||||||
|
ClientItem.appendChild(ClientDetails);
|
||||||
|
|
||||||
|
// Add event listener for user selection
|
||||||
|
ClientItem.addEventListener('click', () => {
|
||||||
|
selectedClientId = client.id; // Correctly store the client ID
|
||||||
|
ClientItem.classList.add('selected'); // Optional: Style selected item
|
||||||
|
});
|
||||||
|
|
||||||
|
ClientLists.appendChild(ClientItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
const title = document.createElement("h3");
|
||||||
|
title.textContent = "Upload to machine";
|
||||||
|
document.getElementById('upload-status').appendChild(title);
|
||||||
|
|
||||||
|
document.getElementById('upload-status').appendChild(ClientLists);
|
||||||
|
|
||||||
|
// Wait for user selection
|
||||||
|
const waitForSelection = () => new Promise((resolve, reject) => {
|
||||||
|
const checkSelection = setInterval(() => {
|
||||||
|
if (selectedClientId !== null) {
|
||||||
|
clearInterval(checkSelection);
|
||||||
|
resolve(selectedClientId);
|
||||||
|
}
|
||||||
|
}, 100); // Check every 100ms if a client is selected
|
||||||
|
});
|
||||||
|
|
||||||
|
// Wait until the user selects a client
|
||||||
|
try {
|
||||||
|
const selectedClientId = await waitForSelection();
|
||||||
|
console.log(`Selected client: ${selectedClientId}`);
|
||||||
|
|
||||||
|
document.getElementById('upload-status').innerHTML = "";
|
||||||
|
|
||||||
|
// Now proceed with uploading code to the selected client
|
||||||
|
console.log("Uploading code to machine...");
|
||||||
|
document.getElementById('upload-status').textContent = "Uploading code to machine";
|
||||||
|
ccInstance.sendCodeToClient(selectedClientId, code);
|
||||||
|
await delay(500);
|
||||||
|
|
||||||
|
// Execute with remote
|
||||||
|
console.log("Executing code in machine...");
|
||||||
document.getElementById('upload-status').textContent = "Executing code";
|
document.getElementById('upload-status').textContent = "Executing code";
|
||||||
upcurrentActive++;
|
upcurrentActive++;
|
||||||
uploadUpdateProgress();
|
uploadUpdateProgress();
|
||||||
ccInstance.runCode();
|
ccInstance.runCodeOnClient(selectedClientId);
|
||||||
} else {
|
} catch (error) {
|
||||||
console.log("Machine is not connected")
|
console.error("Error waiting for selection:", error);
|
||||||
uploadError = true;
|
uploadError = true;
|
||||||
uploadUpdateProgress();
|
uploadUpdateProgress();
|
||||||
document.getElementById('upload-status').innerHTML = `Please Connect Computer to IDE.\nInstruction: <a href="https://github.com/DPSoftware-Foundation/ccIDE#install-remote-code-into-computercraft">Install Remote code into computercraft</a> in github. (Please press SHIFT or CTRL and click)`;
|
document.getElementById('upload-status').innerHTML = `Error selecting client.`;
|
||||||
return
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Machine is not connected");
|
||||||
|
uploadError = true;
|
||||||
|
uploadUpdateProgress();
|
||||||
|
document.getElementById('upload-status').innerHTML = `Please Connect Computer to IDE.\nInstruction: <a href="https://github.com/DPSoftware-Foundation/ccIDE#install-remote-code-into-computercraft">Install Remote code into computercraft</a> in github.`;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// done!
|
// Done!
|
||||||
console.log("Run code done!")
|
console.log("Run code done!");
|
||||||
document.getElementById('upload-status').textContent = "Done!";
|
document.getElementById('upload-status').textContent = "Done!";
|
||||||
await delay(1000)
|
await delay(1000);
|
||||||
document.getElementById('upload-popup').style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
document.getElementById('upload-popup').style.animation = 'fadeOut 0.3s ease'; // Apply fade-out animation
|
||||||
|
selectedClientId = null;
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
document.getElementById('upload-popup').style.display = 'none'; // Hide popup after animation completes
|
document.getElementById('upload-popup').style.display = 'none'; // Hide popup after animation completes
|
||||||
document.getElementById('upload-popup').style.animation = ''; // Reset animation property
|
document.getElementById('upload-popup').style.animation = ''; // Reset animation property
|
||||||
|
@ -3,15 +3,29 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&display=swap" rel="stylesheet">
|
<!-- <meta charset="utf-8" http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-m0mwdxEgv9nMDDw3gHrhX/xCs/OAiZg5/bQ/6X5SIcA='"/> -->
|
||||||
<script>
|
<div class="loading-area">
|
||||||
const {shell} = require('electron');
|
<div id="loadingContent">
|
||||||
</script>
|
<div class="loader"></div>
|
||||||
|
<br>
|
||||||
|
<h3>Please wait...</h3>
|
||||||
|
<h5 id="loadingstatus"></h5>
|
||||||
|
<progress id="progressBarloading" value="0" max="100"></progress>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="dpclogoload">
|
||||||
|
<img src="../assets/DPSoftware2.png" style="width: 25%;"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
|
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
|
||||||
<script src="../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
<link rel="stylesheet" href="../node_modules/toastify-js/src/toastify.css">
|
||||||
<link rel="stylesheet" type="text/css" href="styles.css" />
|
<link rel="stylesheet" type="text/css" href="styles.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<div class="content-area">
|
||||||
<!-- Navigation bar -->
|
<!-- Navigation bar -->
|
||||||
<nav id="navbar">
|
<nav id="navbar">
|
||||||
<!--
|
<!--
|
||||||
@ -40,13 +54,8 @@
|
|||||||
<div id="blocklyDiv"></div>
|
<div id="blocklyDiv"></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Status bar -->
|
<div class="popup" id="upload-popup" style="overflow-y:hidden;">
|
||||||
<div id="statusBar">
|
<div class="popup-content p-3" style="max-width: 720px; position: relative; margin-top: 100px;">
|
||||||
<p id="statusMessage">Initializing...</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="popup" id="upload-popup">
|
|
||||||
<div class="popup-content">
|
|
||||||
<button type="button" class="btn-close float-end" aria-label="Close" id="uploadCloseBtn"></button>
|
<button type="button" class="btn-close float-end" aria-label="Close" id="uploadCloseBtn"></button>
|
||||||
<div class="upload-progress-container" style="text-align: center;">
|
<div class="upload-progress-container" style="text-align: center;">
|
||||||
<div class="progress-container">
|
<div class="progress-container">
|
||||||
@ -64,7 +73,7 @@
|
|||||||
<svg viewBox="0 0 24 24"><path d="m20 22-3.86-1.55c.7-1.53 1.2-3.11 1.51-4.72L20 22M7.86 20.45 4 22l2.35-6.27c.31 1.61.81 3.19 1.51 4.72M12 2s5 2 5 10c0 3.1-.75 5.75-1.67 7.83A2 2 0 0 1 13.5 21h-3a2 2 0 0 1-1.83-1.17C7.76 17.75 7 15.1 7 12c0-8 5-10 5-10m0 10c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z" /></svg>
|
<svg viewBox="0 0 24 24"><path d="m20 22-3.86-1.55c.7-1.53 1.2-3.11 1.51-4.72L20 22M7.86 20.45 4 22l2.35-6.27c.31 1.61.81 3.19 1.51 4.72M12 2s5 2 5 10c0 3.1-.75 5.75-1.67 7.83A2 2 0 0 1 13.5 21h-3a2 2 0 0 1-1.83-1.17C7.76 17.75 7 15.1 7 12c0-8 5-10 5-10m0 10c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z" /></svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p id="upload-status"></p>
|
<div id="upload-status"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -109,7 +118,9 @@
|
|||||||
<div class="library-item overflow-auto library-container" data-libraryfolder="name">
|
<div class="library-item overflow-auto library-container" data-libraryfolder="name">
|
||||||
<img src="image.jpg" class="libimage" onerror="this.onerror=null;this.src='../assets/noimagefallback.png'; this.alt='No Image Available';">
|
<img src="image.jpg" class="libimage" onerror="this.onerror=null;this.src='../assets/noimagefallback.png'; this.alt='No Image Available';">
|
||||||
<div class="library-details">
|
<div class="library-details">
|
||||||
<h3>Title [v1.0 by Author]</h3>
|
<h3>Title</h3>
|
||||||
|
<!--Add Author credit-->
|
||||||
|
<h6>v1.0 by Author</h6>
|
||||||
<p>Library description goes here.</p>
|
<p>Library description goes here.</p>
|
||||||
<img src="../assets/basic_computer.png" class="libimageicon" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Basic Computer">
|
<img src="../assets/basic_computer.png" class="libimageicon" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Basic Computer">
|
||||||
<img src="../assets/adv_computer.png" class="libimageicon" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Advanced Computer">
|
<img src="../assets/adv_computer.png" class="libimageicon" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Advanced Computer">
|
||||||
@ -123,17 +134,21 @@
|
|||||||
<img src="../assets/network-require.png" class="libimageicon" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Network Require">
|
<img src="../assets/network-require.png" class="libimageicon" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Network Require">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
<button type="button" class="btn btn-success btn-sm" id="packageman-import-btn">Import Packages</button>
|
<button type="button" class="btn btn-success btn-sm" id="packageman-import-btn">Import Packages</button>
|
||||||
<button type="button" class="btn btn-warning btn-sm" onclick='scanindex()'>Refetch Packages</button>
|
<button type="button" class="btn btn-warning btn-sm" onclick='scanindex()'>Refetch Packages</button>
|
||||||
<button type="button" class="btn btn-primary btn-sm" onclick='shell.openExternal("https://damp11113.xyz/dpsoftware/ccide/library")'>Download Packages</button>
|
<button type="button" class="btn btn-primary btn-sm" onclick='downloadBlocks()'>Download Packages</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const {shell} = require('electron');
|
||||||
|
</script>
|
||||||
|
<script src="../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="frontend.js"></script>
|
<script src="frontend.js"></script>
|
||||||
<script src="index.js"></script>
|
<script src="index.js"></script>
|
||||||
<script src="codegen.js"></script>
|
<script src="codegen.js"></script>
|
||||||
|
166
src/index.js
166
src/index.js
@ -20,14 +20,43 @@ console.originalLog = console.log;
|
|||||||
console.log = function (...args) {
|
console.log = function (...args) {
|
||||||
ipc.send("update-log-status", ...args)
|
ipc.send("update-log-status", ...args)
|
||||||
console.originalLog(...args)
|
console.originalLog(...args)
|
||||||
|
document.getElementById("loadingstatus").textContent = args.join(' ');
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("Importing module...")
|
console.log("Importing module...")
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { loadperipheral, scanindex } = require("./blocksmanager");
|
const { loadperipheral, scanindex, isBlocksFolderEmpty, downloadBlocks } = require("./blocksmanager");
|
||||||
const Blockly = require('blockly');
|
const Blockly = require('blockly');
|
||||||
const { WorkspaceSearch } = require("@blockly/plugin-workspace-search")
|
const { WorkspaceSearch } = require("@blockly/plugin-workspace-search")
|
||||||
|
const Toastify = require('toastify-js');
|
||||||
|
|
||||||
|
function fireNotify(text, status, destination, duration=3000) {
|
||||||
|
let color;
|
||||||
|
if (status == "success") {
|
||||||
|
color = "#a5dc86"
|
||||||
|
} else if (status == "warning") {
|
||||||
|
color = "#f8bb86"
|
||||||
|
} else if (status == "error") {
|
||||||
|
color = "#f27474"
|
||||||
|
} else if (status == "info") {
|
||||||
|
color = "#3fc3ee"
|
||||||
|
}
|
||||||
|
|
||||||
|
Toastify({
|
||||||
|
text: text,
|
||||||
|
duration: duration,
|
||||||
|
destination: destination,
|
||||||
|
newWindow: true,
|
||||||
|
close: true,
|
||||||
|
gravity: "top", // `top` or `bottom`
|
||||||
|
position: "right", // `left`, `center` or `right`
|
||||||
|
stopOnFocus: true, // Prevents dismissing of toast on hover
|
||||||
|
style: {
|
||||||
|
background: color,
|
||||||
|
}
|
||||||
|
}).showToast();
|
||||||
|
}
|
||||||
|
|
||||||
let isprojectsaved = false;
|
let isprojectsaved = false;
|
||||||
let isprojectopened = false;
|
let isprojectopened = false;
|
||||||
@ -39,6 +68,24 @@ Blockly.utils.colour.setHsvSaturation(0.9)
|
|||||||
let originaltoolbar = fs.readFileSync(path.join(__dirname, "toolbox.xml"), 'utf8');
|
let originaltoolbar = fs.readFileSync(path.join(__dirname, "toolbox.xml"), 'utf8');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const theme = Blockly.Theme.defineTheme('themeName', {
|
||||||
|
base: Blockly.Themes.Classic,
|
||||||
|
componentStyles: {
|
||||||
|
workspaceBackgroundColour: "#1e1e1e",
|
||||||
|
toolboxBackgroundColour: "blackBackground",
|
||||||
|
toolboxForegroundColour: "#fff",
|
||||||
|
flyoutBackgroundColour: "#252526",
|
||||||
|
flyoutForegroundColour: "#ccc",
|
||||||
|
flyoutOpacity: 1,
|
||||||
|
scrollbarColour: "#797979",
|
||||||
|
insertionMarkerColour: "#fff",
|
||||||
|
insertionMarkerOpacity: .3,
|
||||||
|
scrollbarOpacity: .4,
|
||||||
|
cursorColour: "#d0d0d0",
|
||||||
|
blackBackground: "#333"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var workspace = Blockly.inject('blocklyDiv', {
|
var workspace = Blockly.inject('blocklyDiv', {
|
||||||
toolbox: originaltoolbar,
|
toolbox: originaltoolbar,
|
||||||
trashcan: true,
|
trashcan: true,
|
||||||
@ -56,7 +103,8 @@ try {
|
|||||||
minScale: 0.1,
|
minScale: 0.1,
|
||||||
scaleSpeed: 1.1,
|
scaleSpeed: 1.1,
|
||||||
pinch: true
|
pinch: true
|
||||||
}
|
},
|
||||||
|
theme: theme
|
||||||
});
|
});
|
||||||
|
|
||||||
const workspaceSearch = new WorkspaceSearch(workspace);
|
const workspaceSearch = new WorkspaceSearch(workspace);
|
||||||
@ -67,27 +115,6 @@ try {
|
|||||||
ipc.send("erroronstart", `Error on initializing workspace: ${e}`)
|
ipc.send("erroronstart", `Error on initializing workspace: ${e}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
console.log("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")
|
|
||||||
|
|
||||||
console.log("Scanning library...")
|
|
||||||
scanindex();
|
|
||||||
} catch (e) {
|
|
||||||
ipc.send("erroronstart", `Error on loading block: ${e}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Initializing event...")
|
console.log("Initializing event...")
|
||||||
|
|
||||||
ipc.on('export-lua-request', (event) => {
|
ipc.on('export-lua-request', (event) => {
|
||||||
@ -98,7 +125,7 @@ ipc.on('export-lua-request', (event) => {
|
|||||||
// Save workspace
|
// Save workspace
|
||||||
ipc.on('save-workspace-request', (event) => {
|
ipc.on('save-workspace-request', (event) => {
|
||||||
console.log("Saving project...")
|
console.log("Saving project...")
|
||||||
document.getElementById('statusMessage').textContent = `Saving...`;
|
fireNotify(`Saving...`, "warning")
|
||||||
const state = Blockly.serialization.workspaces.save(workspace);
|
const state = Blockly.serialization.workspaces.save(workspace);
|
||||||
const data = {
|
const data = {
|
||||||
"usedlibrary": usedlibinproject,
|
"usedlibrary": usedlibinproject,
|
||||||
@ -120,28 +147,21 @@ ipc.on('load-workspace', (event, json) => {
|
|||||||
const packagefolder = libinproject[i]
|
const packagefolder = libinproject[i]
|
||||||
if (!usedlibinproject.includes(packagefolder)) {
|
if (!usedlibinproject.includes(packagefolder)) {
|
||||||
try {
|
try {
|
||||||
originaltoolbar = loadperipheral(workspace, originaltoolbar, packagefolder);
|
originaltoolbar = loadperipheral(workspace, originaltoolbar, packagefolder, usedlibinproject);
|
||||||
usedlibinproject.push(packagefolder);
|
usedlibinproject.push(packagefolder);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
document.getElementById('statusMessage').textContent = `Can't Import ${usedlibinproject[i]}: ${e}`;
|
fireNotify(`Can't Import ${usedlibinproject[i]}: ${e}`, "error")
|
||||||
setTimeout(() => {
|
}
|
||||||
document.getElementById('statusMessage').textContent = `Ready`;
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
Blockly.serialization.workspaces.load(data.content, workspace);
|
Blockly.serialization.workspaces.load(data.content, workspace);
|
||||||
isprojectsaved = true
|
isprojectsaved = true
|
||||||
document.getElementById('statusMessage').textContent = `Project Loaded`;
|
fireNotify(`Project Loaded`, "success")
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
document.getElementById('statusMessage').textContent = `Can't Load Project: ${e}`;
|
fireNotify(`Can't Load Project: ${e}`, "error")
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
|
||||||
document.getElementById('statusMessage').textContent = `Ready`;
|
|
||||||
}, 1000);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
ipc.on('workspace-saved', (event, success) => {
|
ipc.on('workspace-saved', (event, success) => {
|
||||||
@ -149,10 +169,7 @@ ipc.on('workspace-saved', (event, success) => {
|
|||||||
if (!isprojectopened) {
|
if (!isprojectopened) {
|
||||||
isprojectopened = true;
|
isprojectopened = true;
|
||||||
}
|
}
|
||||||
document.getElementById('statusMessage').textContent = `Project Saved`;
|
fireNotify(`Project Saved`, "success")
|
||||||
setTimeout(() => {
|
|
||||||
document.getElementById('statusMessage').textContent = `Ready`;
|
|
||||||
}, 1000);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ipc.on("open-about", () => {
|
ipc.on("open-about", () => {
|
||||||
@ -185,27 +202,54 @@ document.getElementById("packageman-import-btn").addEventListener('click', () =>
|
|||||||
const selectedItems = document.querySelectorAll('.library-item.selected');
|
const selectedItems = document.querySelectorAll('.library-item.selected');
|
||||||
selectedItems.forEach(item => {
|
selectedItems.forEach(item => {
|
||||||
const packagefolder = item.getAttribute('data-libraryfolder');
|
const packagefolder = item.getAttribute('data-libraryfolder');
|
||||||
if (!usedlibinproject.includes(packagefolder)) {
|
originaltoolbar = loadperipheral(workspace, originaltoolbar, packagefolder, usedlibinproject);
|
||||||
try {
|
fireNotify(`Loaded ${packagefolder}`, "success")
|
||||||
originaltoolbar = loadperipheral(workspace, originaltoolbar, packagefolder);
|
|
||||||
usedlibinproject.push(packagefolder);
|
|
||||||
} catch (e) {
|
|
||||||
document.getElementById('statusMessage').textContent = `Can't Import ${packagefolder}: ${e}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
document.getElementById('statusMessage').textContent = `Ready`;
|
|
||||||
}, 1000);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ensure Blockly container is shown after the workspace is injected
|
async function InitializingBlock() {
|
||||||
console.log("Finished")
|
try {
|
||||||
setTimeout(() => {
|
console.log("Importing system library...");
|
||||||
ipc.send("ready")
|
const sysmodulejson = fs.readFileSync(path.join(__dirname, "module_block_design.json"), 'utf8');
|
||||||
}, 500);
|
const blocksJson = JSON.parse(sysmodulejson);
|
||||||
|
|
||||||
document.getElementById('statusMessage').textContent = "Computer isn't connect";
|
for (const blockId in blocksJson) {
|
||||||
setTimeout(() => {
|
if (blocksJson.hasOwnProperty(blockId)) {
|
||||||
document.getElementById('statusMessage').textContent = `Ready`;
|
Blockly.Blocks[blockId] = {
|
||||||
}, 10000);
|
init: function() {
|
||||||
|
this.jsonInit(blocksJson[blockId]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require("./module_generator");
|
||||||
|
|
||||||
|
console.log("Check library folder...");
|
||||||
|
if (isBlocksFolderEmpty()) {
|
||||||
|
await downloadBlocks();
|
||||||
|
}
|
||||||
|
scanindex();
|
||||||
|
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
ipc.send("erroronstart", `Error on loading block: ${e}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure Blockly container is shown after the workspace is injected
|
||||||
|
console.log("Finished")
|
||||||
|
setTimeout(() => {
|
||||||
|
ipc.send("ready")
|
||||||
|
// Hide loading area
|
||||||
|
const loadingArea = document.querySelector('.loading-area');
|
||||||
|
loadingArea.style.opacity = '0';
|
||||||
|
loadingArea.style.visibility = 'hidden';
|
||||||
|
loadingArea.style.display = 'none';
|
||||||
|
|
||||||
|
// Show content area
|
||||||
|
const contentArea = document.querySelector('.content-area');
|
||||||
|
contentArea.style.opacity = '1';
|
||||||
|
contentArea.style.visibility = 'visible';
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializingBlock();
|
147
src/styles.css
147
src/styles.css
@ -1,16 +1,90 @@
|
|||||||
:root {
|
:root {
|
||||||
--line-border-fill: #3498db;
|
--line-border-fill: #3498db;
|
||||||
--line-border-empty: #e0e0e0;
|
--line-border-empty: #7f8c8d; /* Lighter gray for dark mode */
|
||||||
|
--background-color: #121212; /* Dark background for body */
|
||||||
|
--text-color: #e0e0e0; /* Lighter text color */
|
||||||
|
--button-bg: #333; /* Dark button background */
|
||||||
|
--button-hover-bg: #0066cc; /* Button hover color */
|
||||||
|
--progress-bg: #3498db; /* Progress bar fill color */
|
||||||
|
--error-color: #e74c3c; /* Error state color */
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #212121;
|
background-color: var(--background-color);
|
||||||
margin: 0;
|
color: var(--text-color);
|
||||||
|
font-family: 'Arial', sans-serif;
|
||||||
|
overflow: hidden; /* Hide scrollbars */
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-area {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-area {
|
||||||
|
color: #cacaca;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 400;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 22px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#progressBarloading {
|
||||||
|
display: none; /* Initially hidden */
|
||||||
|
}
|
||||||
|
|
||||||
|
#loadingContent {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100vh;
|
align-items: center;
|
||||||
font-family: 'Noto Sans', sans-serif;
|
justify-content: center;
|
||||||
overflow: hidden; /* Hide scrollbars */
|
}
|
||||||
|
|
||||||
|
.loader {
|
||||||
|
width: 90px;
|
||||||
|
height: 14px;
|
||||||
|
box-shadow: 0 3px 0 #fff;
|
||||||
|
position: relative;
|
||||||
|
clip-path: inset(-40px 0 -5px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.loader:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: auto calc(50% - 17px) 0;
|
||||||
|
height: 50px;
|
||||||
|
--g:no-repeat linear-gradient(#ccc 0 0);
|
||||||
|
background: var(--g),var(--g),var(--g),var(--g);
|
||||||
|
background-size: 16px 14px;
|
||||||
|
animation:
|
||||||
|
l7-1 2s infinite linear,
|
||||||
|
l7-2 2s infinite linear;
|
||||||
|
}
|
||||||
|
@keyframes l7-1 {
|
||||||
|
0%,
|
||||||
|
100% {background-position: 0 -50px,100% -50px}
|
||||||
|
17.5% {background-position: 0 100%,100% -50px,0 -50px,100% -50px}
|
||||||
|
35% {background-position: 0 100%,100% 100% ,0 -50px,100% -50px}
|
||||||
|
52.5% {background-position: 0 100%,100% 100% ,0 calc(100% - 16px),100% -50px}
|
||||||
|
70%,
|
||||||
|
98% {background-position: 0 100%,100% 100% ,0 calc(100% - 16px),100% calc(100% - 16px)}
|
||||||
|
}
|
||||||
|
@keyframes l7-2 {
|
||||||
|
0%,70% {transform:translate(0)}
|
||||||
|
100% {transform:translate(200%)}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dpclogoload {
|
||||||
|
display: flex; /* Enable flexbox */
|
||||||
|
justify-content: center; /* Center horizontally */
|
||||||
|
position: fixed; /* Fixed position */
|
||||||
|
bottom: 30px; /* Adjust as necessary */
|
||||||
|
z-index: 20; /* Ensure it appears above other content */
|
||||||
|
width: 100%; /* Ensure the div takes full width */
|
||||||
}
|
}
|
||||||
|
|
||||||
#navbar {
|
#navbar {
|
||||||
@ -22,7 +96,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navbar-button {
|
.navbar-button {
|
||||||
background-color: #2c3e50;
|
background-color: var(--button-bg);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 50%; /* Make the button circular */
|
border-radius: 50%; /* Make the button circular */
|
||||||
@ -48,7 +122,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navbar-button:hover {
|
.navbar-button:hover {
|
||||||
background-color: #0066cc; /* Darken color on hover */
|
background-color: var(--button-hover-bg); /* Darken color on hover */
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,20 +140,6 @@ body {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#statusBar {
|
|
||||||
height: 3vh; /* Set the height of the status bar */
|
|
||||||
background-color: #333;
|
|
||||||
color: #ffffff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 10px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
#statusMessage {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styles for the upload-popup container */
|
/* Styles for the upload-popup container */
|
||||||
.popup {
|
.popup {
|
||||||
display: none; /* Hide initially */
|
display: none; /* Hide initially */
|
||||||
@ -97,7 +157,8 @@ body {
|
|||||||
|
|
||||||
/* Styles for the upload-popup content */
|
/* Styles for the upload-popup content */
|
||||||
.popup-content {
|
.popup-content {
|
||||||
background-color: #fefefe;
|
background-color: #333;
|
||||||
|
color: #fefefe;
|
||||||
margin: 15% auto; /* Center the upload-popup vertically and horizontally */
|
margin: 15% auto; /* Center the upload-popup vertically and horizontally */
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border: 1px solid #888;
|
border: 1px solid #888;
|
||||||
@ -151,7 +212,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.progress {
|
.progress {
|
||||||
background-color: var(--line-border-fill);
|
background-color: var(--progress-bg);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -163,10 +224,9 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.progress.error {
|
.progress.error {
|
||||||
background-color: red; /* Set to red color for error state */
|
background-color: var(--error-color); /* Set to red color for error state */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.circle {
|
.circle {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
color: #999;
|
color: #999;
|
||||||
@ -186,7 +246,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.circle.error {
|
.circle.error {
|
||||||
border-color: red; /* Optionally, change border color to red */
|
border-color: var(--error-color); /* Optionally, change border color to red */
|
||||||
color: white; /* Optionally, adjust text color for visibility */
|
color: white; /* Optionally, adjust text color for visibility */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,15 +271,20 @@ body {
|
|||||||
}
|
}
|
||||||
.library-details {
|
.library-details {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
line-height: 10px;
|
line-height: 5px;
|
||||||
}
|
}
|
||||||
|
.library-details-cv {
|
||||||
|
color: #7a7a7a;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.library-item {
|
.library-item {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-bottom: 1px solid #e9ecef;
|
border-bottom: 1px solid #7f8c8d; /* Lighter border */
|
||||||
}
|
}
|
||||||
.library-item.selected {
|
.library-item.selected {
|
||||||
background-color: #e9ecef;
|
background-color: #34495e; /* Darker background for selected items */
|
||||||
}
|
}
|
||||||
.library-content {
|
.library-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -228,11 +293,27 @@ body {
|
|||||||
max-height: 720px; /* Ensure a max height for scrolling */
|
max-height: 720px; /* Ensure a max height for scrolling */
|
||||||
}
|
}
|
||||||
.library-item:hover {
|
.library-item:hover {
|
||||||
background-color: #cacaca;
|
background-color: #7f8c8d; /* Hover effect for items */
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-container {
|
.button-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: center;
|
||||||
gap: 10px;
|
align-items: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.btn-invisible {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
padding: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.swipe-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pointer-pointer {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
117
startup.lua
Normal file
117
startup.lua
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
print("checking computer type...")
|
||||||
|
local machineType = 0
|
||||||
|
local isAdvanced = false
|
||||||
|
local isPocket = false
|
||||||
|
local isTurtle = false
|
||||||
|
local isCommand = false
|
||||||
|
|
||||||
|
-- Check if advanced (multishell exists in advanced computers and advanced pocket computers)
|
||||||
|
if multishell then
|
||||||
|
isAdvanced = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if Pocket Computer (API specific to Pocket Computers)
|
||||||
|
if pocket then
|
||||||
|
isPocket = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check if Turtle (turtle API is available for turtles)
|
||||||
|
if turtle then
|
||||||
|
isTurtle = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if commands then
|
||||||
|
isCommand = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Determine machine type
|
||||||
|
if isTurtle then
|
||||||
|
if isAdvanced then
|
||||||
|
machineType = 3 -- Advanced Turtle
|
||||||
|
else
|
||||||
|
machineType = 1 -- Standard Turtle
|
||||||
|
end
|
||||||
|
elseif isPocket then
|
||||||
|
if isAdvanced then
|
||||||
|
machineType = 4 -- Advanced Pocket Computer
|
||||||
|
else
|
||||||
|
machineType = 2 -- Standard Pocket Computer
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if isAdvanced then
|
||||||
|
if isCommand then
|
||||||
|
machineType = 7 -- Command Computer
|
||||||
|
else
|
||||||
|
machineType = 6 -- Advanced Computer
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
machineType = 5 -- Standard Computer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Machine Type: " .. machineType)
|
||||||
|
print("connecting to IDE...")
|
||||||
|
local ws = assert(http.websocket("ws://127.0.0.1:5133"))
|
||||||
|
print("connected to server")
|
||||||
|
|
||||||
|
local id
|
||||||
|
local isrunning = true
|
||||||
|
|
||||||
|
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
|
||||||
|
print("Received message:", message)
|
||||||
|
if message == "ping" then
|
||||||
|
ws.send("pong")
|
||||||
|
elseif message == "info" then
|
||||||
|
info = {
|
||||||
|
OSVersion = os.version(),
|
||||||
|
ID = os.getComputerID(),
|
||||||
|
Name = os.getComputerLabel() or "No Name",
|
||||||
|
Type = machineType,
|
||||||
|
uptime = os.clock()
|
||||||
|
}
|
||||||
|
ws.send(textutils.serialiseJSON(info))
|
||||||
|
elseif message == "sendcode" then
|
||||||
|
local file = io.open("main.lua", "w")
|
||||||
|
print("waiting for code")
|
||||||
|
local filedata, error = ws.receive()
|
||||||
|
file:write(filedata)
|
||||||
|
file:close()
|
||||||
|
elseif message == "runcode" then
|
||||||
|
if isAdvanced then
|
||||||
|
id = multishell.launch({}, "main.lua")
|
||||||
|
multishell.setTitle(id, "Code")
|
||||||
|
multishell.setFocus(id)
|
||||||
|
else
|
||||||
|
shell.run("main")
|
||||||
|
end
|
||||||
|
elseif message == "exit" then
|
||||||
|
print("Exiting...")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
print("WebSocket error:", error)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
parallel.waitForAny(exitcheck, main)
|
||||||
|
print("Exited")
|
23
webpack.main.config.js
Normal file
23
webpack.main.config.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||||
|
const nodeExternals = require("webpack-node-externals");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: "production",
|
||||||
|
target: "electron-main", // For Electron main process
|
||||||
|
entry: "./src/index.js", // Adjust based on your main entry file
|
||||||
|
output: {
|
||||||
|
filename: "main.js",
|
||||||
|
path: path.resolve(__dirname, "dist"),
|
||||||
|
},
|
||||||
|
externals: [nodeExternals()], // Exclude node_modules
|
||||||
|
plugins: [
|
||||||
|
new CopyWebpackPlugin({
|
||||||
|
patterns: [
|
||||||
|
{ from: "assets", to: "assets" },
|
||||||
|
{ from: "blocks", to: "blocks" },
|
||||||
|
{ from: "src/styles.css", to: "styles.css" },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
18
webpack.renderer.config.js
Normal file
18
webpack.renderer.config.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: "production",
|
||||||
|
target: "web", // This should target the web environment for the renderer process
|
||||||
|
entry: "./src/frontend.js", // Ensure this points to the correct renderer entry
|
||||||
|
output: {
|
||||||
|
filename: "renderer.js",
|
||||||
|
path: path.resolve(__dirname, "dist"),
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
template: "src/index.html", // Ensure this injects the renderer script
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user