Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal

Xlaits

Members
  • Content Count

    10
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Xlaits

  1. After a long debugging process, here is what has become of this code. It is FAR from perfect, but it works. So far, the only bugs I have seen are when sending and receiving, the cursor is super unreliable, and one one of my computers, it sends incomplete or broken messages. The port also remains listening, which I MAY OR MAY NOT have fixed. I'm unsure.

     

    I didn't to any new commenting, and I'll fix that when I have some time on my hands. For now, I'll give you the short of it. The program will first check for a file, /home/.uname.txt and if it exists, reads the first 16 bytes of it for the username. If it's not found, it will create it, and prompt the user for a username, which it writes in the newly created file. It still contains the Encryption methods, however it no longer prints the address of the computer it is receiving from. Instead, it prints a user readable <Username>: "Message" to the channel. I had to edit the quit codes to reflect this. I did realize later on that I would need to separate all the computers on the network, to prevent message feedback. I think I'm going to change that by making the receive event and it's print function check for the username, and refuse to print the feedback messages.

     

    Lemme know what you guys think, or if you can optimize my terrible, buggy code.

     

    local term = require("term")
    local component = require("component")
    local event = require("event")
    local m = component.modem
    local str="0"
    local userfile = "/home/.uname.txt"
    local fs = require("filesystem")
    local uname = fs.exists(userfile)
     
    -- determine what channel people want to listen on
    term.clear()
    if uname then
      local handler = fs.open(userfile)
      user = handler:read(16)
      handler:close()
    else
      term.write("You do not have a user profile. \n")
      term.write("Please enter a 16 character user name: ")
      local handler = fs.open(userfile, "w")
      handler:write(io.read())
      local handler = fs.open(userfile)
      user = handler:read(16)
      term.write("\n Username set to " .. user .. ". \n")
      handler:close()
    end
    term.write("What channel do you want to chat on: ")
    local channel = io.read()
    m.open(tonumber(channel))
    
    -- begin event
    function ModemFunction(_,_,from,port,_,message_)
    event.listen("modem_message", ModemFunction)
    
    -- decipher, and print
    local cipher = "1234567890qwertyuiopasdfghjklzxcvbnm"
    local function decrypt(str)
            str = str:gsub("%d",function(a) return string.char(cipher:find(a,nil,true)+47) end)
            str = str:gsub("%l",function(a) return string.char(cipher:find(a,nil,true)+86) end)
            return str
    end
    if string.sub(tostring(message), 1, 9)=="encrypted" then
    str=tostring(message)
    message=decrypt(str)
    local strlngth=string.len(tostring(message))
    message=string.sub(tostring(message), 10, strlngth)
    print(tostring(message))
     
    else
    print(tostring(message))
    end
    end
     
    -- send a message
    term.write("is this going to be encrypted? (yes/no) \n")
     
    -- register cipher
    local cipher = "1234567890qwertyuiopasdfghjklzxcvbnm"
     
    local function encrypt(str)
      str = str:gsub("%d",function(a) a=a:byte()-47 return cipher:sub(a,a) end)
      str = str:gsub("%l",function(a) a=a:byte()-86 return cipher:sub(a,a) end)
      return str
    end
    
    -- determine whether encryption should be used
    local useEC=io.read()
    if useEC=="yes" then
      term.clear()
      term.write("Encryption activated \n")
      sleep(5)
      term.clear()
    end
    while true do
      str= user .. ": " .. io.read()
      if tostring(str)== user .. ": " .. "endme" then
        term.clear()
        event.ignore("modem_message", ModemFunction)
        os.exit()
      end
      if useEC=="yes" then
        str= user .. ": " .. encrypt(str)
        str="encrypted" .. " " .. str
      end
    
    -- send message
    m.broadcast(tonumber(channel), str)
    end

     

  2. This is almost exactly what I was looking for! However, I'm trying to make it so that a User can enter a username, and have it displayed when sending messages. I'm still a Script Kiddie when it comes to Lua, so I'm not sure how I can get this working easily.

     

    EDIT:

    I'm slowly improving this code into an easy to use, somewhat 'complete' chat program. The one thing I'm not sure how to do is make it so that a user's entered name shows up when a message is sent/received, instead of the computer's address. I may re-write initial questions to include asking for a username, or possibly checking for a file that has the user's set name in it. I will report back with results.

  3. -- Initialize
    local component = require("component")
    local term = require("term")
    local side = require("sides")
    local keyboard = require("keyboard")
    local event = require("event")
    local rs = component.redstone
    local batbox = component.cesu
    local board = component.keyboard
    
    --Toggle reactor
    function toggleBox()
        if rs.getOutput(side.top) > 0 then
            rs.setOutput(side.top, 0)
        else
            rs.setOutput(side.top, 15)
        end
    end
    
    -- main Loop
    local function main()
        --Store string for displaying information
        local info = [[
    CESU Power Levels and Controls
    Energy Stored : %s
    CESU Capacity : %s
    
    Press Enter to toggle reactor.
    Press Back to return to OpenOS.
      ]]
        
        -- Program loop
        while true do
            --Put the cursor top left.
            term.setCursor(1, 1)
            --Retrieve and print information
            print( info:format(batbox.getStored(), batbox.getCapacity()) )
            -- Check for event every second
            local e = table.pack(event.pull(1))
            --Conditional If-Then-Else, Looking for specific keys, or interrupt.
            if e[1] == "key_up" and e[4] == keyboard.keys.enter then 
                toggleBox()
            elseif e[1] == "interrupted" or e[1] == "key_up" and e[4] == keyboard.keys.back then 
                break 
            end
          end
        
        term.clear() -- # clean up after program.
    end
    
    --Start program
    main()

    And THIS is my final code. Love how it works, and seeing that IfThen statement makes me think that I can even expand how this program works! Thank you.

     

    Now... to make a better looking screen for it...

  4. 1 minute ago, Molinko said:

    I wanted to fix a small thing. Before, your program would tick every second with event.pull(1, "key_up"), currently with the code i suggested it will not. try this edit for one that update the batbox info every second..

    
    local function main()
      local time = 0
      local info = [[
      CESU Power Levels and Controls
      Energy Stored : %s
      CESU Capacity : %s
    
      Press Enter to toggle reactor.
      Press Back to return to OpenOS.
      ]]
        
        while true do
          term.setCursor(1, 1)
          print( info:format(batbox.getStored(), batbox.getCapacity()) )
          local e = table.pack(event.pull(1)) -- # resumes at least every second or on any event
          if e[1] == "key_up" and e[4] == keyboard.keys.enter then
            toggleBox()
          elseif e[1] == "interrupted"--[[soft interrupt]] or e[1] == "key_up" and e[4] == keyboard.keys.back then
            break
          end
        end
        
        term.clear() -- clean up after program.
    end

     

    I was JUST about to mention that it wasn't updating on it's own. Thanks for the fix.

  5. 33 minutes ago, Molinko said:

    Sorry for the delay... Yeah, my first example was shit.. Im sorry for that. I've made another (tested) version.

    
    local component = require("component")
    local term = require("term")
    local side = require("sides")
    local keyboard = require("keyboard")
    local event = require("event")
    local rs = component.redstone
    local batbox = component.cesu
    local board = component.keyboard
    
    function toggleBox()
      -- # this was wonky aswell i think. rs usually goes 0 - 15 or maybe RP channels 0 - 255 ??
        if rs.getOutput(side.left) > 0 then
            rs.setOutput(side.left, 0)
        else
            rs.setOutput(side.left, 15)
        end
    end
    
    local function main()
      local info = [[
      CESU Power Levels and Controls
      Energy Stored : %s
      CESU Capacity : %s
    
      Press Enter to toggle reactor.
      Press Back to return to OpenOS.
      ]]
        
        while true do
          term.setCursor(1, 1)
          print( info:format(batbox.getStored(), batbox.getCapacity()) )
          local e = {event.pullMultiple("key_up", "interrupted")}
          if e[1] == "key_up" and e[4] == keyboard.keys.enter then toggleBox()
          elseif e[1] == "interrupted" or e[1] == "key_up" and e[4] == keyboard.keys.back then break end
        end
        
        term.clear() -- # clean up after program.
    end
    
    term.clear() -- # clear screen before start.
    main()

    Sorry for the shit starting advice :P

    No, it's fine. Made me think.

    I like the storing of the printed line as a multi-line quote. And clearing the program's output is a nice touch. The term.clear() above main is NOT NEEDED, as the program will do that once main is run. Yeah, it's one line, but hey, efficiency.

    I also realized my idiotic mistake with the redstone power, and had fixed that while waiting. Great minds think alike, I suppose.

  6. 17 minutes ago, Molinko said:

    From what I can see, when the backspace is hit the program should just end (i.e breaking or ending the 'main loop'). The enter key should update the state of the box or (toggle it :p).

    The loop i made from your code will 1. draw the screen for initialization. 2. wait 1 second and refresh or receive a key up event. 3. depending on the event, toggleBox or set running to false. 4. in the until clause we check if the event was a terminated event (if the user pressed ctrl+C) to terminate the program. Either 'back' or the terminate event will break the loop and leave the main function thus ending the program. I hope I was clear... If not... Ask away

    It's not even reacting to the interrupt (Ctrl+C). It is NOT acting upon any events, at all.

    EDIT:

    Well, I found ONE problem... it's not updating the file when I save it in an external editor...

    Edit edit: 

    Well, it's now producing an error when I Ctrl+Alt+C, but other than that, no change.

    Edit edit edit:

    Well, it DOES INDEED activate toggleBox() now, but that's on ANY key_up event, NOT on ENTER ONLY. 

  7. 28 minutes ago, Molinko said:

    The code looks great.. One problem stands out and that is that your keyChecker coroutine isn't being run. Also, Your main function and the keyCheck function both have a loop that will block one another if keyChecker is run within main. Try this solution out. I believe its what you're going for....

    
    function main()
      local running = true
      local e = nil
    
      repeat
        -- Get the tank information, results are in table format
        local tInfo = batbox
        local cap = tonumber(batbox.getCapacity())
        local fill = tonumber(batbox.getStored())
    
        -- Output as you want... a very simple way:
        print("CESU Power Levels and Controls")
        print("Energy Stored : "..fill)
        print("CESU Capacity : "..cap)
        print("\n Press Enter to toggle reactor.")
        print("Press Back to return to OpenOS.")
        term.setCursor(1,1)
    
        e = event.pull(1, "key_up")
        if e == "key_up" then
          toggleBox()
        elseif e == "back" then
          running = false
        end
    
      until not running or e == "terminated"
    end

     

    If you look at the original code, it is checking for two specific keys. Backspace or "back" and Enter, to do two separate things. Let me see if this works, and how I can tweak it.

    EDIT:

    Swapped out main() with yours, and my functionality is still there, but it is STILL not reacting to key presses or events at all.

  8. I'm working on a small bit of code that reads from a IC2 power storage block and displays it's current and maximum storage. I also want it to toggle a Reactor based on either a keypress or a CLI menu option.

    As the code has to refresh a LOT, I think a keypress option is the easiest way, but I can't, for the life of me, figure it out. Here's what I have so far...

    os.execute("cls")
    
    -- Hook the component
    local component = require("component")
    local term = require("term")
    local side = require("sides")
    local keyboard = require("keyboard")
    local event = require("event")
    local rs = component.redstone
    local batbox = component.cesu
    local board = component.keyboard
    
    function toggleBox()
        if rs.getOutput(side.top) == 18 then
            rs.setOutput(side.top, 0)
        else
            rs.setOutput(side.top, 18)
        end
    end
    
    local function keyCheck()
        while true do
            e = event.pull(1, "key_up")
            if e == "enter" then
                toggleBox()
            elseif e == "back" then
                running = false
            end
        end
    end
    
    keyChecker = coroutine.create(keyCheck)
    
    function main()
        running = true
        while true do
           
            -- Get the tank information, results are in table format
            local tInfo = batbox
            local cap = tonumber(batbox.getCapacity())
            local fill = tonumber(batbox.getStored())
    
            -- Output as you want... a very simple way:
            print("CESU Power Levels and Controls")
            print("Energy Stored : "..fill)
            print("CESU Capacity : "..cap)
            print("\n Press Enter to toggle reactor.")
            print("Press Back to return to OpenOS.")
            term.setCursor(1,1)
        end
    end
    
    main()

    And yes, I now see the redundancy of having "cls" there, when I have 'term.setCursor(1,1)' there...

    What is it that I am missing?

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.