if SERVER then return end --prevents it from running on the server function blue_prints.validate_blueprint_xml(xmlString) if not xmlString then return false, "No XML content provided" end -- Check for required main elements if not xmlString:match("") then return false, "Missing CircuitBox element" end if not xmlString:match("]+>") then return false, "Missing InputNode" end if not xmlString:match("]+>") then return false, "Missing OutputNode" end -- Validate input/output node positions local inputNode = xmlString:match("]+>") local outputNode = xmlString:match("]+>") if inputNode then local posX, posY = inputNode:match('pos="([%d%.%-]+),([%d%.%-]+)"') if not (posX and posY and tonumber(posX) and tonumber(posY)) then return false, "Invalid InputNode position" end end if outputNode then local posX, posY = outputNode:match('pos="([%d%.%-]+),([%d%.%-]+)"') if not (posX and posY and tonumber(posX) and tonumber(posY)) then return false, "Invalid OutputNode position" end end -- Validate components for component in xmlString:gmatch('') do -- Check required attributes local id = component:match('id="(%d+)"') local posX, posY = component:match('position="([%-%d%.]+),([%-%d%.]+)"') -- Check both old and new format for item and class local item = component:match('item="([^"]+)"') or component:match('item=<<>>([^<]+)<<>>') local class = component:match('Class="([^"]+)"') or component:match('Class=<<>>([^<]+)<<>>') if not (id and posX and posY and item and class) then return false, "Invalid component definition - missing required attributes" end -- Validate position values are numbers if not (tonumber(posX) and tonumber(posY)) then return false, "Invalid component position values" end -- Validate ID is a number if not tonumber(id) then return false, "Invalid component ID" end -- Check if item prefab exists if item == "oscillatorcomponent" then item = "oscillator" elseif item == "concatenationcomponent" then item = "concatcomponent" elseif item == "exponentiationcomponent" then item = "powcomponent" elseif item == "regexfind" then item = "regexcomponent" elseif item == "signalcheck" then item = "signalcheckcomponent" elseif item == "squareroot" then item = "squarerootcomponent" end local itemPrefab = ItemPrefab.GetItemPrefab(item) if not itemPrefab then return false, "Invalid item prefab: " .. tostring(item) end end -- Validate wire connections for wire in xmlString:gmatch("") do local id = wire:match('id="(%d+)"') if not id or not tonumber(id) then return false, "Invalid wire ID" end -- Check wire prefab local prefab = wire:match('prefab="([^"]+)"') if not prefab then return false, "Missing wire prefab" end local wirePrefab = ItemPrefab.GetItemPrefab(prefab) if not wirePrefab then return false, "Invalid wire prefab: " .. tostring(prefab) end -- Check connections local fromName, fromTarget = wire:match('') do local id = label:match('id="(%d+)"') local posX, posY = label:match('position="([%d%.%-]+),([%d%.%-]+)"') local sizeW, sizeH = label:match('size="([%d%.%-]+),([%d%.%-]+)"') local color = label:match('color="([^"]+)"') if not (id and posX and posY and sizeW and sizeH and color) then return false, "Invalid label definition - missing required attributes" end -- Validate numeric values if not (tonumber(posX) and tonumber(posY) and tonumber(sizeW) and tonumber(sizeH)) then return false, "Invalid label position or size values" end -- Validate color format (basic check for hex color) if not color:match("^#[0-9A-Fa-f]+$") then return false, "Invalid label color format" end end -- If all checks pass return true, "Blueprint XML is valid" end function blue_prints.validate_blueprint_file(provided_path) -- Add .txt extension if not present if not string.match(provided_path, "%.txt$") then provided_path = provided_path .. ".txt" end -- Normalize the path local file_path = blue_prints.normalizePath(blue_prints.save_path .. "/" .. provided_path) -- Try to read the file content using our safe read function local xmlContent = blue_prints.readFileContents(file_path) if not xmlContent then return false, "Could not read file: " .. provided_path end -- Use the XML string validator to check the content return blue_prints.validate_blueprint_xml(xmlContent) end