CCCPaste

djjsshjqshjqksjwjsj


-- nanomachine_server.lua
local component = require("component")
local event = require("event")
local serialization = require("serialization")
local filesystem = require("filesystem")

-- Config
local PORT = 2000
local UPDATE_INTERVAL = 1
local SAVE_FILE = "/home/nanomachine_data.cfg"

-- Components
local modem = component.modem
local nano = component.nanomachines

-- State Management
local state = {
  power = 0,
  maxPower = 0,
  health = 0,
  maxHealth = 20,
  hunger = 0,
  activeInputs = 0,
  totalInputs = 0,
  activeEffects = 0,
  currentProfile = nil,
  autoProtect = false,
  healthThreshold = 10,
  hungerThreshold = 6,
  discoveryActive = false,
  discoveryProgress = 0,
  discoveryTested = 0,
  discoveryFound = 0,
  lastUpdate = 0
}

-- Data Storage
local profiles = {}
local inputStates = {}
local discoveredEffects = {}
local discoveryQueue = {}
local discoveryIndex = 1

-- Initialize
local function initialize()
  print("=== NANOMACHINE SERVER INITIALIZING ===")
  print("")
  
  modem.open(PORT)
  print("✓ Modem listening on port " .. PORT)
  print("✓ Server Address: " .. modem.address)
  print("")
  
  -- Check for nanomachines
  if not nano then
    print("⚠ WARNING: No nanomachines component found!")
    print("Make sure nanomachines are installed and connected.")
    return false
  end
  
  print("✓ Nanomachines detected")
  
  -- Get total inputs
  state.totalInputs = nano.getInputCount()
  print("✓ Total inputs: " .. state.totalInputs)
  
  -- Initialize input states
  for i = 1, state.totalInputs do
    inputStates[i] = {
      id = i,
      active = false,
      lastToggled = 0
    }
  end
  
  -- Load saved data
  loadData()
  
  print("")
  print("=== SERVER READY ===")
  print("")
  
  return true
end

-- Save/Load Functions
local function saveData()
  local data = {
    profiles = profiles,
    discoveredEffects = discoveredEffects,
    autoProtect = state.autoProtect,
    healthThreshold = state.healthThreshold,
    hungerThreshold = state.hungerThreshold
  }
  
  local file = io.open(SAVE_FILE, "w")
  if file then
    file:write(serialization.serialize(data))
    file:close()
    print("[SAVE] Data saved successfully")
    return true
  else
    print("[ERROR] Failed to save data")
    return false
  end
end

local function loadData()
  if not filesystem.exists(SAVE_FILE) then
    print("[LOAD] No saved data found, starting fresh")
    
    -- Create default profiles
    profiles = {
      {
        name = "Combat",
        description = "Speed + Strength + Resistance",
        inputs = {}
      },
      {
        name = "Mining",
        description = "Haste + Night Vision",
        inputs = {}
      },
      {
        name = "Safe",
        description = "Regeneration only",
        inputs = {}
      }
    }
    
    return
  end
  
  local file = io.open(SAVE_FILE, "r")
  if file then
    local content = file:read("*a")
    file:close()
    
    local success, data = pcall(serialization.unserialize, content)
    if success and data then
      profiles = data.profiles or {}
      discoveredEffects = data.discoveredEffects or {}
      state.autoProtect = data.autoProtect or false
      state.healthThreshold = data.healthThreshold or 10
      state.hungerThreshold = data.hungerThreshold or 6
      
      print("[LOAD] Data loaded successfully")
      print("       Profiles: " .. #profiles)
      print("       Discovered Effects: " .. #discoveredEffects)
    else
      print("[ERROR] Failed to parse saved data")
    end
  end
end

-- Nanomachine Control Functions
local function updateNanoStatus()
  if not nano then return end
  
  -- Get power
  state.power = nano.getPowerState()
  state.maxPower = nano.getMaxPower()
  
  -- Count active inputs
  state.activeInputs = 0
  for i = 1, state.totalInputs do
    if nano.getInput(i) then
      inputStates[i].active = true
      state.activeInputs = state.activeInputs + 1
    else
      inputStates[i].active = false
    end
  end
  
  -- Get active effects
  local effects = nano.getActiveEffects()
  state.activeEffects = effects and #effects or 0
  
  state.lastUpdate = os.time()
end

local function setInput(inputId, active)
  if not nano or inputId < 1 or inputId > state.totalInputs then
    return false
  end
  
  nano.setInput(inputId, active)
  inputStates[inputId].active = active
  inputStates[inputId].lastToggled = os.time()
  
  print("[INPUT] Input " .. inputId .. " set to " .. (active and "ON" or "OFF"))
  return true
end

local function toggleInput(inputId)
  if not nano or inputId < 1 or inputId > state.totalInputs then
    return false
  end
  
  local currentState = nano.getInput(inputId)
  return setInput(inputId, not currentState)
end

local function disableAllInputs()
  print("[ACTION] Disabling all inputs...")
  
  for i = 1, state.totalInputs do
    setInput(i, false)
  end
  
  state.currentProfile = nil
  print("[ACTION] All inputs disabled")
end

-- Profile Management
local function activateProfile(profileName)
  print("[PROFILE] Activating profile: " .. profileName)
  
  -- Find profile
  local profile = nil
  for _, p in ipairs(profiles) do
    if p.name == profileName then
      profile = p
      break
    end
  end
  
  if not profile then
    print("[ERROR] Profile not found: " .. profileName)
    return false
  end
  
  -- Disable all first
  disableAllInputs()
  
  -- Activate profile inputs
  if profile.inputs and #profile.inputs > 0 then
    for _, inputId in ipairs(profile.inputs) do
      setInput(inputId, true)
    end
  end
  
  state.currentProfile = profileName
  print("[PROFILE] Profile activated: " .. profileName)
  
  return true
end

local function createProfile(profileName)
  print("[PROFILE] Creating profile: " .. profileName)
  
  -- Get current active inputs
  local activeInputs = {}
  for i = 1, state.totalInputs do
    if inputStates[i].active then
      table.insert(activeInputs, i)
    end
  end
  
  -- Create profile
  local profile = {
    name = profileName,
    description = "Custom profile",
    inputs = activeInputs,
    created = os.time()
  }
  
  table.insert(profiles, profile)
  saveData()
  
  print("[PROFILE] Profile created with " .. #activeInputs .. " inputs")
  return true
end

local function deleteProfile(profileName)
  for i, profile in ipairs(profiles) do
    if profile.name == profileName then
      table.remove(profiles, i)
      saveData()
      print("[PROFILE] Deleted profile: " .. profileName)
      return true
    end
  end
  
  print("[ERROR] Profile not found: " .. profileName)
  return false
end

-- Auto-Protection System
local function checkAutoProtection()
  if not state.autoProtect or not nano then
    return
  end
  
  -- Check health (would need player component or other method to get real health)
  -- This is a placeholder - you'd need to implement actual health checking
  
  -- For now, we'll use a simple low power protection
  if state.power < (state.maxPower * 0.2) then
    print("[AUTO-PROTECT] Low power detected, activating emergency profile")
    -- Could activate a specific safe profile here
  end
end

-- Discovery System
local function initializeDiscovery()
  print("[DISCOVERY] Initializing discovery system...")
  
  discoveryQueue = {}
  
  -- Generate all possible single input combinations
  for i = 1, state.totalInputs do
    table.insert(discoveryQueue, {i})
  end
  
  -- Generate all possible double input combinations
  for i = 1, state.totalInputs do
    for j = i + 1, state.totalInputs do
      table.insert(discoveryQueue, {i, j})
    end
  end
  
  -- Could add triple combinations but that's a lot
  -- For 32 inputs: 32 + 496 + 4960 = 5488 combinations
  
  print("[DISCOVERY] Queue size: " .. #discoveryQueue .. " combinations")
  discoveryIndex = 1
  state.discoveryTested = 0
  state.discoveryFound = 0
end

local function runDiscoveryStep()
  if not state.discoveryActive or discoveryIndex > #discoveryQueue then
    state.discoveryActive = false
    print("[DISCOVERY] Discovery complete!")
    saveData()
    return
  end
  
  local combination = discoveryQueue[discoveryIndex]
  
  -- Disable all inputs
  for i = 1, state.totalInputs do
    setInput(i, false)
  end
  
  -- Wait a bit for effects to clear
  os.sleep(0.5)
  
  -- Enable combination
  for _, inputId in ipairs(combination) do
    setInput(inputId, true)
  end
  
  -- Wait for effects to activate
  os.sleep(1)
  
  -- Check for effects
  local effects = nano.getActiveEffects()
  
  if effects and #effects > 0 then
    local effectData = {
      combination = combination,
      effects = effects,
      discovered = os.time()
    }
    
    table.insert(discoveredEffects, effectData)
    state.discoveryFound = state.discoveryFound + 1
    
    print("[DISCOVERY] Found effects: " .. table.concat(effects, ", "))
    print("            Inputs: " .. table.concat(combination, ", "))
  end
  
  state.discoveryTested = state.discoveryTested + 1
  state.discoveryProgress = math.floor((discoveryIndex / #discoveryQueue) * 100)
  
  discoveryIndex = discoveryIndex + 1
end

-- Message Handler
local function handleMessage(sender, port, distance, command, data)
  print("[REQUEST] " .. command .. " from " .. sender:sub(1, 8))
  
  if command == "GET_STATUS" then
    local serialized = serialization.serialize(state)
    modem.send(sender, PORT, "GET_STATUS_RESPONSE", serialized)
    
  elseif command == "GET_PROFILES" then
    local serialized = serialization.serialize(profiles)
    modem.send(sender, PORT, "GET_PROFILES_RESPONSE", serialized)
    
  elseif command == "GET_INPUTS" then
    local serialized = serialization.serialize(inputStates)
    modem.send(sender, PORT, "GET_INPUTS_RESPONSE", serialized)
    
  elseif command == "ACTIVATE_PROFILE" then
    activateProfile(data)
    modem.send(sender, PORT, "ACK")
    
  elseif command == "CREATE_PROFILE" then
    createProfile(data)
    modem.send(sender, PORT, "ACK")
    
  elseif command == "DELETE_PROFILE" then
    deleteProfile(data)
    modem.send(sender, PORT, "ACK")
    
  elseif command == "TOGGLE_INPUT" then
    toggleInput(data)
    modem.send(sender, PORT, "ACK")
    
  elseif command == "DISABLE_ALL" then
    disableAllInputs()
    modem.send(sender, PORT, "ACK")
    
  elseif command == "EMERGENCY_STOP" then
    disableAllInputs()
    state.autoProtect = false
    state.discoveryActive = false
    print("[EMERGENCY] Emergency stop activated!")
    modem.send(sender, PORT, "ACK")
    
  elseif command == "TOGGLE_AUTO" then
    state.autoProtect = not state.autoProtect
    saveData()
    print("[AUTO-PROTECT] " .. (state.autoProtect and "ENABLED" or "DISABLED"))
    modem.send(sender, PORT, "ACK")
    
  elseif command == "SET_HEALTH_THRESHOLD" then
    state.healthThreshold = data
    saveData()
    print("[SETTING] Health threshold set to " .. data)
    modem.send(sender, PORT, "ACK")
    
  elseif command == "SET_HUNGER_THRESHOLD" then
    state.hungerThreshold = data
    saveData()
    print("[SETTING] Hunger threshold set to " .. data)
    modem.send(sender, PORT, "ACK")
    
  elseif command == "START_DISCOVERY" then
    initializeDiscovery()
    state.discoveryActive = true
    print("[DISCOVERY] Discovery started")
    modem.send(sender, PORT, "ACK")
    
  elseif command == "PAUSE_DISCOVERY" then
    state.discoveryActive = false
    print("[DISCOVERY] Discovery paused")
    modem.send(sender, PORT, "ACK")
    
  elseif command == "RESET_DISCOVERY" then
    initializeDiscovery()
    state.discoveryActive = true
    print("[DISCOVERY] Discovery reset and restarted")
    modem.send(sender, PORT, "ACK")
    
  elseif command == "PING" then
    modem.send(sender, PORT, "PONG")
    
  else
    modem.send(sender, PORT, "ERROR")
  end
end

-- Status Display
local function displayStatus()
  print("╔═══════════════════════════════════════════════╗")
  print("║     NANOMACHINE SERVER STATUS                 ║")
  print("╚═══════════════════════════════════════════════╝")
  print("")
  print("Server: " .. modem.address:sub(1, 8) .. "...")
  print("Port: " .. PORT)
  print("")
  print("Power: " .. state.power .. "/" .. state.maxPower)
  print("Active Inputs: " .. state.activeInputs .. "/" .. state.totalInputs)
  print("Active Effects: " .. state.activeEffects)
  print("")
  print("Current Profile: " .. (state.currentProfile or "None"))
  print("Auto-Protect: " .. (state.autoProtect and "ENABLED" or "DISABLED"))
  print("")
  
  if state.discoveryActive then
    print("Discovery: ACTIVE")
    print("  Progress: " .. state.discoveryProgress .. "%")
    print("  Tested: " .. state.discoveryTested)
    print("  Found: " .. state.discoveryFound .. " effects")
  else
    print("Discovery: IDLE")
    print("  Total Discovered: " .. #discoveredEffects .. " effects")
  end
  
  print("")
  print("Profiles: " .. #profiles)
  print("")
  print("Press Ctrl+C to stop server")
  print("───────────────────────────────────────────────")
end

-- Main Loop
local function main()
  if not initialize() then
    print("Failed to initialize server")
    return
  end
  
  local lastStatusDisplay = 0
  local lastDataUpdate = 0
  local lastAutoCheck = 0
  local lastDiscoveryStep = 0
  
  while true do
    local currentTime = os.time()
    
    -- Update nanomachine status
    if currentTime - lastDataUpdate >= UPDATE_INTERVAL then
      updateNanoStatus()
      lastDataUpdate = currentTime
    end
    
    -- Check auto-protection
    if currentTime - lastAutoCheck >= 2 then
      checkAutoProtection()
      lastAutoCheck = currentTime
    end
    
    -- Run discovery step
    if state.discoveryActive and currentTime - lastDiscoveryStep >= 2 then
      runDiscoveryStep()
      lastDiscoveryStep = currentTime
    end
    
    -- Display status
    if currentTime - lastStatusDisplay >= 5 then
      displayStatus()
      lastStatusDisplay = currentTime
    end
    
    -- Handle messages
    local _, _, sender, port, distance, command, data = event.pull(0.1, "modem_message")
    
    if command then
      handleMessage(sender, port, distance, command, data)
    end
  end
end

-- Cleanup
local function cleanup()
  print("")
  print("=== SERVER SHUTTING DOWN ===")
  
  -- Save data
  saveData()
  
  -- Close modem
  modem.close(PORT)
  
  print("✓ Server stopped")
end

-- Error handling
local success, err = xpcall(main, debug.traceback)

if not success then
  print("")
  print("ERROR: " .. tostring(err))
end

cleanup()