Add network broadcasting functionality for client displays and command handling
This commit is contained in:
@@ -15,6 +15,11 @@ local CACHE_FILE = ".inventory_cache" -- persistent cache file
|
||||
local SMELTER_MONITOR_SIDE = "top"
|
||||
local DISABLED_RECIPES_FILE = ".disabled_recipes"
|
||||
|
||||
-- Network sync (for client displays)
|
||||
local BROADCAST_CHANNEL = 4200
|
||||
local ORDER_CHANNEL = 4201
|
||||
local BROADCAST_INTERVAL = 1 -- seconds between state broadcasts
|
||||
|
||||
-------------------------------------------------
|
||||
-- Furnace types to manage
|
||||
-------------------------------------------------
|
||||
@@ -651,6 +656,8 @@ local mon = nil
|
||||
local monName = nil
|
||||
local smelterMon = nil
|
||||
local smelterMonName = nil
|
||||
local networkModem = nil
|
||||
local networkModemName = nil
|
||||
|
||||
local function setupMonitor()
|
||||
mon = peripheral.wrap(MONITOR_SIDE)
|
||||
@@ -2133,6 +2140,36 @@ local function handleSmelterTouch(x, y)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------
|
||||
-- Network broadcast (sends state to client displays)
|
||||
-------------------------------------------------
|
||||
|
||||
local function broadcastState()
|
||||
if not networkModem then return end
|
||||
local state = {
|
||||
type = "state",
|
||||
cache = {
|
||||
itemList = cache.itemList,
|
||||
grandTotal = cache.grandTotal,
|
||||
chestCount = cache.chestCount,
|
||||
totalSlots = cache.totalSlots,
|
||||
usedSlots = cache.usedSlots,
|
||||
freeSlots = cache.freeSlots,
|
||||
usedRatio = cache.usedRatio,
|
||||
dropperOk = cache.dropperOk,
|
||||
barrelOk = cache.barrelOk,
|
||||
furnaceCount = cache.furnaceCount,
|
||||
furnaceStatus = cache.furnaceStatus,
|
||||
},
|
||||
activity = activity,
|
||||
alerts = activeAlerts,
|
||||
smeltingPaused = smeltingPaused,
|
||||
disabledRecipes = disabledRecipes,
|
||||
smeltable = SMELTABLE,
|
||||
}
|
||||
networkModem.transmit(BROADCAST_CHANNEL, ORDER_CHANNEL, state)
|
||||
end
|
||||
|
||||
-------------------------------------------------
|
||||
-- Main
|
||||
-------------------------------------------------
|
||||
@@ -2167,6 +2204,21 @@ local function main()
|
||||
print("[WARN] No smelter monitor on " .. SMELTER_MONITOR_SIDE)
|
||||
end
|
||||
|
||||
-- Find modem for client communication
|
||||
for _, name in ipairs(peripheral.getNames()) do
|
||||
if peripheral.getType(name) == "modem" then
|
||||
networkModem = peripheral.wrap(name)
|
||||
networkModemName = name
|
||||
networkModem.open(ORDER_CHANNEL)
|
||||
break
|
||||
end
|
||||
end
|
||||
if networkModem then
|
||||
print("[OK] Network modem: " .. networkModemName)
|
||||
else
|
||||
print("[WARN] No modem found for client sync")
|
||||
end
|
||||
|
||||
-- Load recipe toggles from disk
|
||||
loadDisabledRecipes()
|
||||
if smeltingPaused then
|
||||
@@ -2404,6 +2456,73 @@ local function main()
|
||||
handleTouch(x, y)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
-- Task 10: Network state broadcast
|
||||
function()
|
||||
while true do
|
||||
pcall(broadcastState)
|
||||
sleep(BROADCAST_INTERVAL)
|
||||
end
|
||||
end,
|
||||
|
||||
-- Task 11: Network order/command listener
|
||||
function()
|
||||
if not networkModem then return end
|
||||
while true do
|
||||
local event, side, channel, replyChannel, message, distance = os.pullEvent("modem_message")
|
||||
if channel == ORDER_CHANNEL and type(message) == "table" then
|
||||
if message.type == "order" and message.itemName and message.amount then
|
||||
print(string.format("[NET] Order: %s x%d", message.itemName, message.amount))
|
||||
local success = orderItem(message.itemName, message.amount)
|
||||
networkModem.transmit(replyChannel, ORDER_CHANNEL, {
|
||||
type = "order_result",
|
||||
success = success,
|
||||
message = statusMessage,
|
||||
color = statusColor,
|
||||
})
|
||||
pcall(broadcastState)
|
||||
elseif message.type == "scan" then
|
||||
print("[NET] Scan request from client")
|
||||
pcall(refreshCache)
|
||||
pcall(checkAlerts)
|
||||
needsRedraw = true
|
||||
smelterNeedsRedraw = true
|
||||
pcall(broadcastState)
|
||||
elseif message.type == "toggle_pause" then
|
||||
smeltingPaused = not smeltingPaused
|
||||
print("[NET] Smelting " .. (smeltingPaused and "PAUSED" or "RESUMED"))
|
||||
saveDisabledRecipes()
|
||||
smelterNeedsRedraw = true
|
||||
needsRedraw = true
|
||||
pcall(broadcastState)
|
||||
elseif message.type == "toggle_recipe" and message.recipe then
|
||||
if disabledRecipes[message.recipe] then
|
||||
disabledRecipes[message.recipe] = nil
|
||||
else
|
||||
disabledRecipes[message.recipe] = true
|
||||
end
|
||||
print("[NET] Recipe toggle: " .. message.recipe)
|
||||
saveDisabledRecipes()
|
||||
smelterNeedsRedraw = true
|
||||
pcall(broadcastState)
|
||||
elseif message.type == "enable_all" then
|
||||
disabledRecipes = {}
|
||||
print("[NET] All recipes enabled")
|
||||
saveDisabledRecipes()
|
||||
smelterNeedsRedraw = true
|
||||
pcall(broadcastState)
|
||||
elseif message.type == "disable_all" then
|
||||
for inputName in pairs(SMELTABLE) do
|
||||
disabledRecipes[inputName] = true
|
||||
end
|
||||
print("[NET] All recipes disabled")
|
||||
saveDisabledRecipes()
|
||||
smelterNeedsRedraw = true
|
||||
pcall(broadcastState)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user