Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local width,height=term.getSize()
- local function debug(...)
- term.redirect(term.native)
- print(...)
- os.pullEvent("char")
- term.restore()
- end
- local function printUsage()
- print([[Usage:
- talk <dein name>
- ]])
- error()
- end
- local tArgs={...}
- if #tArgs<1 or #tArgs>2 then
- printUsage()
- end
- --look for a modem
- local modem
- do
- local modemSides={}
- for _,v in pairs(rs.getSides()) do
- if peripheral.getType(v)=="modem" then
- modemSides[#modemSides+1]=v
- end
- end
- if #modemSides==0 then
- print("Du benåB6tigst ein WLAN Modem")
- return
- end
- if #modemSides>1 then
- term.scroll(#modemSides+3)
- local selected=1
- local function printMenu()
- term.setCursorPos(1,height-#modemSides-2)
- for i=1,#modemSides do
- if selected==i then
- term.setTextColor(colors.black)
- term.setBackgroundColor(colors.white)
- end
- print(i..": "..modemSides[i].." - "..(peripheral.call(modemSides[i],"isWireless") and "wireless" or "wired"))
- if selected==i then
- term.setTextColor(colors.white)
- term.setBackgroundColor(colors.black)
- end
- end
- end
- print("select a modem to use:")
- printMenu()
- if term.isColor() then
- write("use arrows and enter, press # to select, or click with mouse to select")
- else
- write("use arrows and enter or press # to select")
- end
- while true do
- local e={os.pullEvent()}
- if e[1]=="key" then
- local key=e[2]
- if key==keys.up then
- selected=selected==1 and #modemSides or selected-1
- printMenu()
- elseif key==keys.down then
- selected=(selected%#modemSides)+1
- printMenu()
- elseif key==keys.enter then
- break
- end
- elseif e[1]=="char" then
- local char=e[2]
- local num=tonumber(char)
- if num and num>0 and num<=#modemSides then
- selected=num
- break
- end
- end
- end
- term.scroll(2)
- modem=peripheral.wrap(modemSides[selected])
- else
- modem=peripheral.wrap(modemSides[1])
- end
- end
- local function parseNick(str)
- local nick=str:match("%s*([%w_]+)%s*")
- return nick and nick:sub(1,12) or nil
- end
- local nick=parseNick(tArgs[1])
- if nick==nil then
- print("Invalid nick! can contain only letters, numbers, and _ and must be no more than 12 characters long.")
- return
- end
- local users={
- [nick]=true
- }
- local channel, frequency="chat",1337
- local function parseChannel(str)
- local chan,freq=str:match("%s*(%w+):(%d+)%s*")
- if not chan then
- freq=frequency
- chan=str:match("(%w+)"):lower():sub(1,16)
- if not chan then
- chan=channel
- end
- else
- chan=chan:lower():sub(1,16)
- freq=tonumber(freq)%65536
- end
- return chan,freq
- end
- if tArgs[2] then
- channel,frequency=parseChannel(tArgs[2])
- end
- modem.open(frequency)
- local inputCurPos={1,2}
- local inputTextColor=colors.white
- local inputBGColor=colors.black
- local inputCursorBlink=false
- local inputBuffer=(""):rep(width)
- local statusLine
- local function rebuildStatus()
- statusLine=" ccchat v1.0 channel: "..channel..":"..frequency
- statusLine=statusLine..(" "):rep(width-#statusLine)
- term.native.setCursorPos(1,height-1)
- term.native.setTextColor(colors.black)
- term.native.setBackgroundColor(colors.white)
- term.native.write(statusLine)
- term.native.setTextColor(colors.white)
- term.native.setBackgroundColor(colors.black)
- end
- local function redrawInput()
- term.redirect(term.native)
- term.setCursorPos(1,height-1)
- term.setTextColor(colors.black)
- term.setBackgroundColor(colors.white)
- term.write(statusLine)
- term.setCursorPos(1,height)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- term.write(inputBuffer)
- term.setCursorPos(unpack(inputCurPos))
- term.restore()
- end
- --input+status redirect
- local inputRedirect = {
- getSize=function() return width,2 end,
- setCursorPos=function(x,y) inputCurPos={x,y} term.native.setCursorPos(x,height) end,
- getCursorPos=function() return unpack(inputCurPos) end,
- setTextColor=function(color) inputTextColor=color term.native.setTextColor(color) end,
- setTextColour=function(color) inputTextColor=color term.native.setTextColor(color) end,
- setBackgroundColor=function(color) inputBGColor=color term.native.setBackgroundColor(color) end,
- setBackgroundColour=function(color) inputBGColor=color term.native.setBackgroundColor(color) end,
- setCursorBlink=function(state) inputCursorBlink=state term.native.setCursorBlink(state) end,
- isColor=function() return term.native.isColor() end,
- isColour=function() return term.native.isColour() end,
- scroll=function() term.clearLine() end,
- write=function(val)
- inputBuffer=inputBuffer:sub(1,inputCurPos[1]-1)..val..inputBuffer:sub(inputCurPos[1]+#val)
- inputCurPos[1]=inputCurPos[1]+#val
- term.native.write(val)
- end,
- clear=function()
- inputBuffer=(""):rep(width)
- end,
- clearLine=function()
- inputBuffer=(""):rep(width)
- end,
- }
- local isNewLogLine=true
- --main log redirect
- local logRedirect = {
- getSize=function() return width,height-1 end,
- setCursorBlink=function() end,
- scroll=function(amt)
- term.native.scroll(amt)
- isNewLogLine=true
- end,
- write=function(text)
- if isNewLogLine then
- term.native.clearLine()
- isNewLogLine=false
- end
- term.native.write(text)
- end,
- }
- for k,v in pairs(term.native) do
- if logRedirect[k]==nil then
- logRedirect[k]=v
- end
- end
- local function printLine(line)
- local x,y=term.getCursorPos()
- term.redirect(logRedirect)
- term.setCursorPos(1,height-1)
- print(line)
- term.restore()
- redrawInput()
- term.setCursorPos(x,y)
- --queue a dummy event to trigger coRead update?
- --os.queueEvent("key")
- end
- local function printHelp()
- printLine([[eXz-Chat 1.0 BETA #13
- /quit [msg] Beendet den Chat mit einer Nachricht
- /join <name>
- and joins <name>. <name> can end
- with :<freq> to change both,
- ex: /join foo:1338
- /freq <freq> switches chat frequencies
- /help displays this help
- /nick <nick>
- /users lists users in channel
- anything typed without a / will be said in the
- channel and heard by all in range on the same
- channel and frequency.]])
- end
- local function sendMsg(msg)
- local out="CHAT "..channel.." "..nick.." "..msg
- modem.transmit(frequency,frequency,out)
- end
- local function showUsers()
- local first=true
- local str="** Benutzer in diesem Channel "..channel..":"
- for k,v in pairs(users) do
- if first then
- first=false
- else
- str=str..","
- end
- str=str.." "..k
- end
- printLine(str)
- end
- local autoUsersTimer
- local function coRead()
- history={}
- while true do
- term.setCursorPos(1,height)
- local input=read(nil,history)
- history[#history+1]=input
- if #history==256 then
- table.remove(history,1)
- end
- if input:sub(1,1)=="/" then
- local cmd,args=input:match("/(%S+) ?(.*)")
- if cmd=="quit" then
- printLine("Exiting chat")
- sendMsg("quit "..args:match("^%s*(.*)%s*$"))
- return
- elseif cmd=="me" then
- printLine("* "..nick.." "..args)
- sendMsg("me "..args)
- elseif cmd=="join" then
- local chan,freq=parseChannel(args)
- if chan then
- if chan==channel then
- printLine("** Yer already in that channel!")
- elseif args~="" then
- printLine("** switching to channel "..chan..(freq==frequency and "" or (":"..freq)))
- sendMsg("quit leftChannel")
- channel=chan
- if frequency~=freq then
- modem.open(freq)
- modem.close(frequency)
- frequency=freq
- end
- sendMsg("join")
- rebuildStatus()
- users={[nick]=true}
- autoUsersTimer=os.startTimer(.25)
- else
- printLine("** invalid channel!")
- end
- else
- printLine("** invalid syntax")
- end
- elseif cmd=="freq" then
- args=tonumber(args)
- if args==nil then
- printLine("** frequency must be a number.")
- elseif frequency~=args then
- printLine("** switching to frequency "..args)
- sendMsg("quit leftChannel")
- modem.open(args)
- modem.close(frequency)
- frequency=args
- sendMsg("join")
- rebuildStatus()
- users={[nick]=true}
- autoUsersTimer=os.startTimer(.25)
- end
- elseif cmd=="help" then
- printHelp()
- elseif cmd=="nick" then
- local newNick=parseNick(args)
- if newNick then
- printLine("** nick changed to "..newNick)
- sendMsg("nick "..nick.." "..newNick)
- nick=newNick
- end
- elseif cmd=="users" then
- showUsers()
- else
- printLine("** Unknown command")
- end
- else
- printLine("<"..nick.."> "..input)
- sendMsg("say "..input)
- end
- end
- end
- local function coMain()
- while true do
- e={os.pullEvent()}
- if e[1]=="modem_message" then
- local msgChannel, msgNick, msgCmd, msgArgs=e[5]:match("CHAT (%S+) (%S+) (%S+) ?(.*)")
- if msgChannel==channel then
- --it's a chat message on the right channel
- if msgCmd=="say" then
- printLine("<"..msgNick.."> "..msgArgs)
- elseif msgCmd=="me" then
- printLine("* "..msgNick.." "..msgArgs)
- elseif msgCmd=="join" then
- printLine("** "..msgNick.." has joined the chat")
- sendMsg("ident")
- elseif msgCmd=="ident" then
- users[msgNick]=true
- elseif msgCmd=="quit" then
- printLine("** "..msgNick.." has left the channel ("..(msgArgs=="" and "quit" or msgArgs)..")")
- elseif msgCmd=="nick" then
- local old, new=msgArgs:match("(%S+) (%S+)")
- users[old]=nil
- users[new]=true
- printLine("** "..old.." now known as "..new)
- end
- end
- elseif e[1]=="timer" and e[2]==autoUsersTimer then
- showUsers()
- end
- end
- end
- sendMsg("join")
- autoUsersTimer=os.startTimer(.25)
- term.clear()
- rebuildStatus()
- term.redirect(inputRedirect)
- printLine([[CCChat v1.0
- /help for a list of commands
- /quit quits
- just type to talk.]])
- parallel.waitForAny(coRead,coMain)
- modem.close(frequency)
- term.restore()
- term.scroll(1)
- print("\ngoodbye!\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement