Drum_Stick

creditAdd_Remove

Nov 21st, 2025 (edited)
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 27.09 KB | Gaming | 0 0
  1.  
  2.  
  3. leftMonitor = peripheral.wrap("left")
  4. topMonitor = peripheral.wrap("top")
  5. diskDrive = peripheral.wrap("right")
  6. ditoCreds = 30  -- Credits per diamond
  7.  
  8.  
  9. function findItemSlot(itemName)
  10.     local chest = peripheral.wrap("minecraft:chest_0")
  11.     for slot = 1, 27 do
  12.         local item = chest.getItemDetail(slot)
  13.         if item and item.name == itemName then
  14.             return slot
  15.         end
  16.     end
  17.     topMonitor.write("diamonds not found in chest.")
  18.     return nil
  19. end
  20.  
  21. function deposit(player)
  22.     local chest2 = peripheral.wrap("minecraft:chest_2")
  23.     local chest = peripheral.wrap("minecraft:chest_0")
  24.     for slot, item in pairs(chest.list()) do
  25.         print(("%d x %s in slot %s"):format(item.count, item.name, slot))
  26.     end
  27.     local desiredItemName = "minecraft:diamond"  -- item to deposit
  28.     local itemFound = false
  29.     local totalDiamonds = 0
  30.     for i = 1, chest.size() do
  31.         local item = chest.getItemDetail(i)
  32.         if item and item.name == desiredItemName then
  33.             if not itemFound then
  34.                 topMonitor.setCursorPos(1, 4)
  35.             end
  36.         end
  37.     end
  38.     local desiredItemName = "minecraft:diamond"  -- item to deposit
  39.     local diamondSlots = {}
  40.  
  41.     -- First, find all diamond stacks and sum their counts
  42.     for i = 1, chest.size() do
  43.         local item = chest.getItemDetail(i)
  44.         if item and item.name == desiredItemName then
  45.             totalDiamonds = totalDiamonds + item.count
  46.             table.insert(diamondSlots, {slot = i, count = item.count})
  47.         end
  48.     end
  49.  
  50.     if totalDiamonds > 0 then
  51.         topMonitor.setCursorPos(1, 4)
  52.         topMonitor.write("Depositing " .. totalDiamonds .. " of diamonds")
  53.         topMonitor.setCursorPos(1, 5)
  54.         topMonitor.write("Credits to be added: " .. (totalDiamonds * ditoCreds))
  55.  
  56.         -- Move all diamond stacks to chest2
  57.         for _, entry in ipairs(diamondSlots) do
  58.             chest.pushItems(peripheral.getName(chest2), entry.slot, entry.count)
  59.         end
  60.  
  61.         -- Add credits for all deposited diamonds
  62.         local newCredits = loadCreditsFromDisk() + (totalDiamonds * ditoCreds)
  63.         saveCreditsToDisk(newCredits)
  64.         savePlayerData(loadUsernameFromDisk(), newCredits)
  65.     else
  66.         topMonitor.setCursorPos(1, 6)
  67.         topMonitor.write("No diamonds found in the chest.")
  68.     end
  69.    
  70.     sleep(3)
  71.  
  72.     displayMain(loadUsernameFromDisk())
  73.  
  74.  
  75. end
  76.  
  77. function withdraw()
  78.     -- chest2 is the storage (source), chest is the withdrawal location (destination)
  79.     local chest2 = peripheral.wrap("minecraft:chest_2")
  80.     local chest = peripheral.wrap("minecraft:chest_0")
  81.     drawWithdrawKeyboard()
  82.     local amount = handleWithdrawalKeyboardInput()
  83.  
  84.     -- We assume the user is standing next to chest_0 (destination) and that it has space.
  85.     -- The slot number returned here is usually where the item *already* is or where it *should go*.
  86.     -- The push/pull functions handle finding an empty slot automatically if you don't specify the destination slot index.
  87.  
  88.     while true do
  89.         if amount > loadCreditsFromDisk() then
  90.             topMonitor.setCursorPos(1, 6)
  91.             topMonitor.write("Insufficient credits. Please enter a smaller amount.")
  92.             sleep(2)
  93.             topMonitor.clearLine(1, 6)
  94.             drawWithdrawKeyboard()
  95.             amount = handleWithdrawalKeyboardInput()
  96.         else
  97.             break
  98.         end
  99.     end
  100.    
  101.     -- Calculate the exact diamonds required, then convert to an integer (floor)
  102.     local diamondsToWithdraw = math.floor(amount / ditoCreds)
  103.    
  104.     topMonitor.clearLine(1, 3)
  105.     topMonitor.clearLine(1, 5)
  106.     topMonitor.clearLine(1,9)
  107.     topMonitor.setCursorPos(1, 3)
  108.     topMonitor.write("Withdrawing " .. diamondsToWithdraw .. " diamonds.")
  109.    
  110.     -- The primary logic should be a single push or pull operation, optimized for moving from source to destination.
  111.    
  112.     -- We call 'pushItems' on the source (chest2) to move items into the destination (chest)
  113.     local actualMovedCount = 0
  114.     -- Iterate over chest2 slots to find diamonds
  115.     for slot = 1, chest2.size() do
  116.         local item = chest2.getItemDetail(slot)
  117.         if item and item.name == "minecraft:diamond" then
  118.             local toMove = math.min(item.count, diamondsToWithdraw - actualMovedCount)
  119.            
  120.             -- Push from chest2 into chest
  121.             -- Arguments: target name, source slot, limit
  122.             local moved = chest2.pushItems(peripheral.getName(chest), slot, toMove)
  123.             actualMovedCount = actualMovedCount + (moved or 0)
  124.            
  125.             if actualMovedCount >= diamondsToWithdraw then break end
  126.         end
  127.     end
  128.  
  129.     -- Update credits based on what was *actually* moved, not just requested
  130.     if actualMovedCount > 0 then
  131.         local newCredits = - (actualMovedCount * ditoCreds)
  132.         saveCreditsToDisk(newCredits)
  133.         savePlayerData(loadUsernameFromDisk(), newCredits)
  134.     end
  135.    
  136.     sleep(3)
  137.     displayMain(loadUsernameFromDisk())
  138. end
  139.  
  140. function Log_Off()
  141.     topMonitor.clear()
  142.     topMonitor.setCursorPos(1, 1)
  143.     topMonitor.write("Logging off... Please remove your disk.")
  144.     sleep(5)
  145.     topMonitor.clear()
  146.     leftMonitor.clear()
  147.     setUpMonitors()
  148.     waitForDisk()
  149. end
  150.  
  151. function setUpMonitors()
  152.  
  153.     leftMonitor.clear()
  154.     leftMonitor.setTextScale(1)
  155.     topMonitor.clear()
  156.     topMonitor.setTextScale(1)
  157.     topMonitor.setBackgroundColor(colors.black)
  158.     topMonitor.setTextColor(colors.red)
  159.  
  160. end
  161.  
  162. function drawKeyboard()
  163.     topMonitor.setBackgroundColor(colors.black)
  164.     topMonitor.setTextColor(colors.red)
  165.    
  166.     -- Draw letters (3 rows of letters)
  167.     local letters = {
  168.         "qwertyuiop",
  169.         "asdfghjkl",
  170.         "zxcvbnm"
  171.     }
  172.    
  173.     -- Draw the letters on the top monitor (adjust x, y positions for rows)
  174.     for row = 1, #letters do
  175.         local y = row + 4  -- Start the keyboard lower on the screen (row 5)
  176.         for i = 1, #letters[row] do
  177.             local letter = letters[row]:sub(i, i)
  178.             local x = (i * 3) - 2  -- Space out letters and adjust for alignment
  179.             topMonitor.setCursorPos(x, y)
  180.             topMonitor.write("[" .. letter .. "]")
  181.         end
  182.     end
  183.  
  184.     -- Draw numbers
  185.     local numbers = "1234567890"
  186.     topMonitor.setCursorPos(1, 3)  -- Numbers row above letters
  187.     for i = 1, #numbers do
  188.         local x = (i * 3) - 2  -- Space out numbers properly
  189.         topMonitor.setCursorPos(x, 3)
  190.         topMonitor.write("[" .. numbers:sub(i, i) .. "]")
  191.     end
  192.  
  193.     -- Draw special controls (Backspace and Submit)
  194.     topMonitor.setCursorPos(1, 9)
  195.     topMonitor.write("[Backspace] [Submit]")
  196.  
  197.     -- Draw the spacebar (new addition)
  198.     topMonitor.setCursorPos(1, 8)  -- Place it one row above Backspace/Submit
  199.     topMonitor.write("[           Space           ]")  -- Large button for space
  200. end
  201.  
  202. function drawWithdrawKeyboard()
  203.         topMonitor.setBackgroundColor(colors.black)
  204.         topMonitor.setTextColor(colors.white)
  205.         -- Draw numbers for withdrawal amounts
  206.         local numbers = {
  207.             "123",
  208.             "456",
  209.             "789",
  210.             "0"
  211.         }
  212.         -- Draw each row of numbers at a different y-coordinate
  213.         for row = 1, #numbers do
  214.             local y = row + 4  -- Start at y=5 for the first row
  215.             for i = 1, #numbers[row] do
  216.                 local x = (i * 3) - 2  -- Space out numbers properly
  217.                 topMonitor.setCursorPos(x, y)
  218.                 topMonitor.write("[" .. numbers[row]:sub(i, i) .. "]")
  219.             end
  220.         end
  221.  
  222.         -- Draw special controls (Backspace and Submit)
  223.         topMonitor.setCursorPos(1, 9)
  224.         topMonitor.write("[Backspace] [Submit]")
  225. end
  226.  
  227. function handleWithdrawalKeyboardInput()
  228.  
  229.     topMonitor.setBackgroundColor(colors.black)
  230.     topMonitor.setTextColor(colors.white)
  231.     local amount = ""  -- The entered amount (masked)
  232.  
  233.     while true do
  234.         topMonitor.setBackgroundColor(colors.black)
  235.         topMonitor.setTextColor(colors.red)
  236.         -- Redraw the "Amount:" label before every key press update
  237.         topMonitor.setCursorPos(1, 3)
  238.         topMonitor.write("Amount:")  -- Keep the label on the screen
  239.  
  240.         -- Wait for a touch event on the monitor
  241.         local event, side, x, y = os.pullEvent("monitor_touch")
  242.  
  243.         -- Handle number inputs
  244.         if y >= 5 and y <= 8 then
  245.             local numbers = {
  246.                 "123",
  247.                 "456",
  248.                 "789",
  249.                 "0"
  250.             }
  251.             local row = y - 4
  252.             local numberRow = numbers[row]
  253.             if numberRow then
  254.                 local numberIndex = math.ceil(x / 3)
  255.                 local number = numberRow:sub(numberIndex, numberIndex)
  256.                 if number and number ~= "" then
  257.                     amount = amount .. number
  258.                     updateWithdrawDisplay(amount)
  259.                 end
  260.             end
  261.  
  262.         -- Handle special buttons (Backspace and Submit)
  263.         elseif y == 9 then
  264.             if x >= 1 and x <= 11 then  -- Backspace button
  265.                 amount = amount:sub(1, -2)
  266.                 updateWithdrawDisplay(amount)
  267.  
  268.             elseif x >= 13 and x <= 20 then  -- Submit button
  269.                 local num = tonumber(amount)
  270.                 if num and num > 0 then
  271.                     return num  -- Return the entered amount as a number
  272.                 else
  273.                     topMonitor.setCursorPos(1, 10)
  274.                     topMonitor.write("Enter a valid amount.")
  275.                     sleep(1)
  276.                     topMonitor.setCursorPos(1, 10)
  277.                     topMonitor.clearLine()
  278.                 end
  279.             end
  280.         end
  281.     end
  282. end
  283.  
  284.  
  285. function updateWithdrawDisplay(amount)
  286.     topMonitor.setCursorPos(8, 3)
  287.     topMonitor.clearLine()
  288.     topMonitor.write(amount)
  289. end
  290.  
  291. function resetOnDiskRemove()
  292.     while true do
  293.         -- Wait for the "disk" or "disk_eject" event
  294.         local event, side = os.pullEvent()
  295.        
  296.         -- If the event is related to the disk and it has been removed
  297.         if event == "disk_eject" or event == "disk" then
  298.             if not diskDrive.isDiskPresent() then
  299.                 -- Clear any stored global variables related to user info
  300.                 username = nil
  301.                 password = nil
  302.                 hint = nil
  303.                 credits = 0
  304.                 -- Clear monitors
  305.                 topMonitor.clear()
  306.                 leftMonitor.clear()
  307.                 topMonitor.setCursorPos(1, 1)
  308.                 topMonitor.write("Disk removed! Returning to main menu...")
  309.                 sleep(2)
  310.                 main() -- Reset to main menu or startup script
  311.             end
  312.         end
  313.     end
  314. end
  315.  
  316. function handleKeyboardInput(hint)
  317.     topMonitor.setBackgroundColor(colors.black)
  318.     topMonitor.setTextColor(colors.red)
  319.     local password = ""  -- The entered password (masked)
  320.  
  321.     while true do
  322.         topMonitor.setBackgroundColor(colors.black)
  323.         topMonitor.setTextColor(colors.red)
  324.         -- Redraw the "Password:" label before every key press update
  325.         topMonitor.setCursorPos(1, 1)
  326.         topMonitor.write("Password: ")  -- Keep the label on the screen
  327.  
  328.         -- Display the password hint below the keyboard if available
  329.         if hint and hint ~= "" then
  330.             topMonitor.setCursorPos(1, 11)
  331.             topMonitor.write("Password Hint: " .. hint)
  332.         end
  333.  
  334.         -- Wait for a touch event on the monitor
  335.         local event, side, x, y = os.pullEvent("monitor_touch")
  336.  
  337.         -- DEBUG: Print the touch event to the console for debugging
  338.         --print("Touch event: x = " .. x .. ", y = " .. y)
  339.  
  340.         -- Handle letter inputs
  341.         if y >= 5 and y <= 7 then
  342.             local row = y - 4
  343.             local letters = {
  344.                 "qwertyuiop",  -- First row of letters
  345.                 "asdfghjkl",   -- Second row of letters
  346.                 "zxcvbnm"      -- Third row of letters
  347.             }
  348.             local letterIndex = math.ceil(x / 3)  -- Correct letter position based on new spacing
  349.             local letter = letters[row]:sub(letterIndex, letterIndex)
  350.  
  351.             -- DEBUG: Print the selected letter
  352.             --print("Selected letter: " .. letter)
  353.  
  354.             if letter and letter ~= "" then
  355.                 password = password .. letter
  356.                 updatePasswordDisplay(password)
  357.             end
  358.  
  359.         -- Handle number inputs
  360.         elseif y == 3 then
  361.             local numbers = "1234567890"
  362.             local numberIndex = math.ceil(x / 3)
  363.             local number = numbers:sub(numberIndex, numberIndex)
  364.  
  365.             -- DEBUG: Print the selected number
  366.             --print("Selected number: " .. number)
  367.  
  368.             if number and number ~= "" then
  369.                 password = password .. number
  370.                 updatePasswordDisplay(password)
  371.             end
  372.  
  373.         -- Handle special buttons (Backspace and Submit)
  374.         elseif y == 9 then
  375.             if x >= 1 and x <= 11 then  -- Backspace button
  376.                 password = password:sub(1, -2)
  377.                 updatePasswordDisplay(password)
  378.  
  379.                 -- DEBUG: Print Backspace press
  380.                 --print("Pressed: [Backspace]")
  381.  
  382.             elseif x >= 13 and x <= 20 then  -- Submit button
  383.                 -- DEBUG: Print Submit press and the entered password
  384.                 --print("Pressed: [Submit], Password: " .. password)
  385.                 return password  -- Return the entered password
  386.             end
  387.         end
  388.     end
  389. end
  390.  
  391.  
  392.  
  393. -- Update the password display (masked with *)
  394. function updatePasswordDisplay(password)
  395.     topMonitor.setCursorPos(11, 1)  -- Password display starts at column 11
  396.     topMonitor.clearLine()
  397.     topMonitor.write(string.rep("*", #password))
  398. end
  399.  
  400. -- Main menu buttons
  401. function drawMainMenu()
  402.     leftMonitor.setBackgroundColor(colors.black)
  403.     leftMonitor.setTextColor(colors.red)
  404.     leftMonitor.clear()
  405.     leftMonitor.setCursorPos(1, 1)
  406.     leftMonitor.write("[deposit]")  -- Button for Item Shop
  407.     leftMonitor.setCursorPos(1, 2)
  408.     leftMonitor.write("[withdraw]")  -- Button for Slot Machine
  409.     leftMonitor.setCursorPos(1, 3)
  410.     leftMonitor.write("[Log_Off]")  -- Button to exit to disk prompt
  411. end
  412.  
  413. -- Handle Main Menu touch events
  414. function handleMainMenuTouch(player)
  415.     while true do
  416.         local event, side, x, y = os.pullEvent("monitor_touch")
  417.         if side == "left" then
  418.             if y == 1 then
  419.                 deposit(player)  -- Launch Item Shop
  420.             elseif y == 2 then
  421.                 withdraw(player)  -- Launch Slot Machine
  422.             elseif y == 3 then
  423.                 Log_Off(player)  -- Exit to disk prompt
  424.             end
  425.         end
  426.     end
  427. end
  428.  
  429.  
  430.  
  431.  
  432. -- Display welcome message and credit info on top monitor
  433. function displayMain(player)
  434.     -- Load credits from the floppy disk (source of truth)
  435.     local credits = loadCreditsFromDisk()
  436.     -- Keep player data file in sync
  437.     savePlayerData(player, credits)
  438.  
  439.     topMonitor.clear()
  440.     topMonitor.setCursorPos(1, 1)
  441.     topMonitor.write("Welcome, " .. player)
  442.     topMonitor.setCursorPos(1, 2)
  443.     topMonitor.write("Credits: " .. credits)
  444.    
  445. end
  446.  
  447. -- Deprecated: Save Player Data to Disk (use saveCreditsToDisk instead)
  448. function savePlayerData(player, credits)
  449.     -- No longer used; kept for compatibility
  450.     saveCreditsToDisk(credits)
  451. end
  452.  
  453. -- Deprecated: Load Player Data from Disk (use loadCreditsFromDisk instead)
  454. function loadPlayerData(player)
  455.     -- No longer used; kept for compatibility
  456.     return loadCreditsFromDisk()
  457. end
  458.  
  459. -- Save credentials (username, password, hint) to disk
  460. function saveCredentials(username, password, hint)
  461.     local diskPath = diskDrive.getMountPath()
  462.     if diskPath then
  463.         local file = fs.open(diskPath .. "/" .. username .. "_credentials.txt", "w")
  464.         file.writeLine(password)  -- Ensure password is written as a string
  465.         file.writeLine(hint)
  466.         file.close()
  467.         diskDrive.setDiskLabel(username)
  468.     end
  469. end
  470.  
  471. -- Load credentials from disk
  472. function loadCredentials(username)
  473.     local diskPath = diskDrive.getMountPath()
  474.     if diskPath and fs.exists(diskPath .. "/" .. username .. "_credentials.txt") then
  475.         local file = fs.open(diskPath .. "/" .. username .. "_credentials.txt", "r")
  476.         local password = file.readLine()  -- Read password as string
  477.         local hint = file.readLine()
  478.         file.close()
  479.         return password, hint
  480.     else
  481.         return nil, nil
  482.     end
  483. end
  484.  
  485. -- Function to save credits directly to the floppy disk in the drive
  486. function saveCreditsToDisk(credits)
  487.     local diskPath = diskDrive.getMountPath()  -- Get the disk's path
  488.     if diskPath then
  489.         local file = fs.open(diskPath .. "disk/credits.txt", "w")  -- Open or create 'credits.txt'
  490.         file.writeLine(tostring(credits))  -- Write the credits as a string
  491.         file.close()
  492.     else
  493.         print("No disk found.")
  494.     end
  495. end
  496.  
  497. -- Function to load credits directly from the floppy disk
  498. function loadCreditsFromDisk()
  499.     local diskPath = diskDrive.getMountPath()
  500.     if diskPath and fs.exists(diskPath .. "disk/credits.txt") then
  501.         local file = fs.open(diskPath .. "disk/credits.txt", "r")
  502.         local credits = tonumber(file.readAll())  -- Read the credits and convert to a number
  503.         file.close()
  504.         return credits
  505.     else
  506.         return 0  -- Default to 0 credits if no file exists
  507.     end
  508. end
  509.  
  510. -- Function to load the username from the floppy disk label
  511. function loadUsernameFromDisk()
  512.     local diskPath = diskDrive.getMountPath()
  513.     if diskPath then
  514.         return diskDrive.getDiskLabel() or "Unknown User"
  515.     else
  516.         return "Unknown User"
  517.     end
  518. end
  519.  
  520. -- Function to draw prompts and keyboard for setting up new player (no clearing topMonitor every time)
  521. function drawSetupScreen(prompt)
  522.     topMonitor.setBackgroundColor(colors.black)
  523.     topMonitor.setTextColor(colors.red)
  524.     topMonitor.setCursorPos(1, 1)
  525.     topMonitor.write(prompt)  -- Display the correct prompt (username, password, or hint)
  526.    
  527.     -- Draw the on-screen keyboard (keep the same for all inputs)
  528.     drawKeyboard()
  529. end
  530.  
  531. -- Function to handle input via on-screen keyboard
  532. function handleKeyboardInputForSetup(prompt, isPassword, hint)
  533.     topMonitor.setBackgroundColor(colors.black)
  534.     topMonitor.setTextColor(colors.red)
  535.     local input = ""  -- To store the input masked if its password
  536.  
  537.     -- Initially display the prompt and input area
  538.     updateSetupDisplay(input, prompt, isPassword)
  539.  
  540.     while true do
  541.         -- Display the password hint below the keyboard if available (during password input)
  542.         if hint and hint ~= "" then
  543.             topMonitor.setCursorPos(1, 11)
  544.             topMonitor.write("Password Hint: " .. hint)
  545.         end
  546.  
  547.         -- Wait for a touch event on the monitor
  548.         local event, side, x, y = os.pullEvent("monitor_touch")
  549.  
  550.         -- Handle letter inputs
  551.         if y >= 5 and y <= 7 then
  552.             local row = y - 4
  553.             local letters = {
  554.                 "qwertyuiop",
  555.                 "asdfghjkl",
  556.                 "zxcvbnm"
  557.             }
  558.             local letterIndex = math.ceil(x / 3)  -- Correct letter position based on new spacing
  559.             local letter = letters[row]:sub(letterIndex, letterIndex)
  560.             if letter and letter ~= "" then
  561.                 input = input .. letter
  562.                 updateSetupDisplay(input, prompt, isPassword)  -- Refresh after adding input
  563.             end
  564.         -- Handle number inputs
  565.         elseif y == 3 then
  566.             local numbers = "1234567890"
  567.             local numberIndex = math.ceil(x / 3)
  568.             local number = numbers:sub(numberIndex, numberIndex)
  569.             if number and number ~= "" then
  570.                 input = input .. number
  571.                 updateSetupDisplay(input, prompt, isPassword)  -- Refresh after adding input
  572.             end
  573.         -- Handle spacebar input
  574.         elseif y == 8 then
  575.             if x >= 2 and x <= 21 then  -- Spacebar spans this range
  576.                 input = input .. " "  -- Add a space character to the input
  577.                 updateSetupDisplay(input, prompt, isPassword)  -- Refresh after adding input
  578.             end
  579.         -- Handle special buttons (Backspace and Submit)
  580.         elseif y == 9 then
  581.             if x >= 1 and x <= 11 then  -- Backspace button
  582.                 input = input:sub(1, -2)
  583.                 updateSetupDisplay(input, prompt, isPassword)  -- Refresh after backspace
  584.             elseif x >= 13 and x <= 20 then  -- Submit button
  585.                 return input  -- Return the entered input
  586.             end
  587.         end
  588.     end
  589. end
  590. -- Update the display for setup input (Username, Password, or Hint)
  591. function updateSetupDisplay(input, prompt, isPassword)
  592.     -- Clear the input area (start after the prompt text)
  593.     topMonitor.setCursorPos(1, 1)
  594.     topMonitor.clearLine()  -- Clear the line before rewriting
  595.     topMonitor.write(prompt)  -- Re-write the prompt every time
  596.  
  597.     -- Set the cursor position for input (right after the prompt)
  598.     topMonitor.setCursorPos(#prompt + 1, 1)
  599.  
  600.     -- Mask the password if its a password input, otherwise display normal input
  601.     if isPassword then
  602.         --topMonitor.write(string.rep("*", #input))  -- Mask the password with *
  603.         topMonitor.write(input)
  604.         print(input)
  605.     else
  606.         topMonitor.write(input)  -- Display the actual input for username or hint
  607.     end
  608.  
  609.     -- Redraw the keyboard so it stays visible
  610.     drawKeyboard()
  611. end
  612.  
  613. -- Setup new user on a new disk using the monitor and keyboard
  614. function setupNewPlayerDisk()
  615.     -- Step 1: Clear the monitor first
  616.     topMonitor.clear()
  617.    
  618.     -- Clear any stored data from previous operations
  619.     username = nil
  620.     password = nil
  621.     hint = nil
  622.     credits = 0
  623.  
  624.     -- Step 2: Get the Username
  625.     local usernamePrompt = "Enter your Username: "
  626.     local username = handleKeyboardInputForSetup(usernamePrompt, false, nil)  -- No hint and not masked
  627.  
  628.     -- Step 3: Get the Password (masked input)
  629.     local passwordPrompt = "Enter your Password: "
  630.     local password = handleKeyboardInputForSetup(passwordPrompt, true, nil)  -- Masked input for password
  631.  
  632.     -- Step 4: Get the Password Hint (optional)
  633.     local hintPrompt = "Enter a Password Hint (optional): "
  634.     local hint = handleKeyboardInputForSetup(hintPrompt, false, nil)  -- No masking for the hint
  635.  
  636.     -- Step 5: Save the credentials and start with 0 credits
  637.     saveCredentials(username, password, hint)
  638.     saveCreditsToDisk(0)
  639.  
  640.     return username
  641. end
  642.  
  643. -- Convert a string to its hexadecimal representation safely
  644. function toHex(str)
  645.     -- Ensure the input is a string and not nil or a number
  646.     if type(str) ~= "string" then
  647.         return "(invalid input)"
  648.     end
  649.     return (str:gsub('.', function(c)
  650.         return string.format('%02X', string.byte(c))
  651.     end))
  652. end
  653.  
  654. --print("Loaded password from disk: ", correctPassword)
  655. --print("Entered password: ", result)
  656.  
  657. -- Validate user disk and password using on-screen keyboard
  658. function validateUserDisk(username)
  659.     local correctPassword, hint = loadCredentials(username)
  660.     local attempts = 0
  661.  
  662.     --print("Loaded correct password from disk: [" .. tostring(correctPassword) .. "]")
  663.  
  664.     while attempts < 3 do
  665.         -- Draw the password keyboard and prompt
  666.         drawKeyboard()
  667.  
  668.         local enteredPassword = nil
  669.  
  670.         -- Parallel process to monitor disk removal while the user inputs the password
  671.         local success = parallel.waitForAny(
  672.             function()
  673.                 enteredPassword = handleKeyboardInput(hint)
  674.             end,
  675.             resetOnDiskRemove  -- Monitor disk removal
  676.         )
  677.  
  678.         if success == 1 then  -- This means the keyboard input was successful
  679.             --print("Entered password: [" .. tostring(enteredPassword) .. "]")
  680.  
  681.             -- Compare entered and stored password after trimming extra characters
  682.             enteredPassword = enteredPassword:match("^%s*(.-)%s*$")  -- Trim any extra spaces or newlines
  683.             correctPassword = correctPassword and correctPassword:match("^%s*(.-)%s*$")
  684.  
  685.             --print("Comparing passwords: [" .. enteredPassword .. "] vs [" .. correctPassword .. "]")
  686.  
  687.             if enteredPassword == correctPassword then
  688.                 return true  -- Access granted
  689.             else
  690.                 attempts = attempts + 1
  691.                 topMonitor.setCursorPos(1, 18)
  692.                 topMonitor.write("Wrong Password, Try Again.")
  693.                 sleep(2)  -- Brief pause
  694.                 if attempts == 3 then
  695.                     topMonitor.setCursorPos(1, 19)
  696.                     topMonitor.write("Too many failed attempts.")
  697.                     sleep(2)
  698.                     topMonitor.clear()
  699.                     return false
  700.                 end
  701.             end
  702.         elseif success == 2 then
  703.             -- Handle disk removal scenario
  704.             return false
  705.         end
  706.     end
  707. end
  708.  
  709. -- Wait for disk to be inserted
  710. function waitForDisk()
  711.     while not diskDrive.isDiskPresent() do
  712.         topMonitor.clear()
  713.         topMonitor.setCursorPos(1, 1)
  714.         topMonitor.write("Please insert your disk...")
  715.         os.pullEvent("disk")
  716.     end
  717.     -- Disk has been inserted, clear any old data
  718.     username = nil
  719.     password = nil
  720.     hint = nil
  721.     credits = 0
  722. end
  723.  
  724. -- Main Program
  725. function main()
  726.     setUpMonitors()
  727.     waitForDisk()
  728.  
  729.     -- Parallel process to monitor disk removal and user actions
  730.     parallel.waitForAny(
  731.         function()
  732.             -- When a disk is inserted, get its label
  733.             local diskLabel = diskDrive.getDiskLabel()
  734.  
  735.             -- If the disk is not labeled (i.e., its a new disk)
  736.             if not diskLabel or diskLabel == "" then
  737.                 -- Clear any lingering data
  738.                 username = nil
  739.                 password = nil
  740.                 hint = nil
  741.                 credits = 0
  742.  
  743.                 -- New disk detected, setup a new player
  744.                 local username = setupNewPlayerDisk()  -- Prompt to enter username, password, and hint
  745.                 -- Initialize credits.txt to 0 for new user
  746.                 saveCreditsToDisk(0)
  747.                 topMonitor.clear()
  748.                 topMonitor.setCursorPos(1, 1)
  749.                 topMonitor.write("Welcome, " .. username)
  750.                 drawMainMenu()
  751.                 handleMainMenuTouch(username)
  752.             else
  753.                 -- Existing disk detected, validate the user with a password
  754.                 local username = diskLabel
  755.                 if validateUserDisk(username) then
  756.                     -- Use loadCreditsFromDisk for consistency
  757.                     displayMain(username)  -- Display the users info on the screen
  758.                     drawMainMenu()  -- Draw the main menu
  759.                     handleMainMenuTouch(username)  -- Handle user input for the menu
  760.                 else
  761.                     -- If validation fails, return to startup
  762.                     os.reboot()
  763.                 end
  764.             end
  765.         end,
  766.         resetOnDiskRemove  -- Monitor for disk ejection and handle accordingly
  767.     )
  768. end
  769. main()
Add Comment
Please, Sign In to add comment