Browse Source

added minitel chat I guess

master
Izaya 2 years ago
parent
commit
230a04f59f
3 changed files with 231 additions and 0 deletions
  1. +110
    -0
      minitel-chat/chat.lua
  2. +94
    -0
      minitel-chat/chatd.lua
  3. +27
    -0
      programs.cfg

+ 110
- 0
minitel-chat/chat.lua View File

@@ -0,0 +1,110 @@
local term = require "term"
local event = require "event"
local process = require "process"
local net = require "net"
local computer = require "computer"
local gpu = term.gpu()

local tArgs = {...}
local server, port = (tArgs[1]:match("(.+):%d+") or tArgs[1]), (tonumber(tArgs[1]:match(".+:(%d+)")) or 194)
local nick = tArgs[2]
local x, y = gpu.getResolution()
local colours = {"37","31","32","34"}
local run = true
local s = false
local ow = process.info().data.window
local nw = term.internal.open(0,0,x,y-1)
term.bind(term.gpu(), nw)

term.clear()

local function gncolour(nick)
local n = 0
for c in nick:gmatch(".") do
n = n + c:byte()
end
n = (n % #colours) + 1
return colours[n]
end
local function colourize(nick)
return "\27["..gncolour(nick).."m"..nick.."\27[0m"
end

local function formatLine(...)
local tA = {...}
return string.format("%s"..("\t%s"):rep(#tA-1).."\n", ...)
end

local function linemsg(message)
process.info().data.window = nw
gpu.copy(1,2,x,y-2,0,-1)
local ox, oy = term.getCursor()
term.setCursor(1,y-1)
term.clearLine()
io.write(message)
term.setCursor(ox,oy)
process.info().data.window = ow
end
local function handlemsg(nick,message)
linemsg("<"..colourize(nick).."> "..message)
end

function connect()
linemsg("Connecting to "..server..":"..tostring(port))
s = net.open(server,port)
linemsg("Connected! Sending nick...")
s:write("nick\t"..nick.."\n")
end

connect()

local function readLoop()
local line = s.rbuffer:match("(.-)\n")
local tCmd = {}
for w in line:gmatch("[^\t]+") do
tCmd[#tCmd+1] = w
end
s:read(line:len()+1)
if tCmd[1] == "msg" and tCmd[2] and tCmd[3] then
handlemsg(tCmd[2], tCmd[3])
elseif tCmd[1] == "topic" then
linemsg("Topic: "..tCmd[2])
elseif tCmd[1] == "nick" then
linemsg(colourize(tCmd[2]).." changed nick to " .. colourize(tCmd[3]))
elseif tCmd[1] == "quit" then
linemsg(colourize(tCmd[2]) .. " has quit.")
elseif tCmd[1] == "join" then
linemsg(colourize(tCmd[2]) .. " has joined.")
end
end

local timer = event.timer(0.5,readLoop,math.huge)

while run do
io.write("\27["..tostring(y)..";1H["..nick.."] ")
msg = term.read({},false):sub(1,-2)
term.clearLine()
if msg:sub(1,1) == "/" then
local cmd = msg:sub(2)
local tCmd = {}
for w in cmd:gmatch("%S+") do
tCmd[#tCmd+1] = w
end
if tCmd[1] == "quit" then
linemsg("Disconnecting from server...")
s:close()
run = false
elseif tCmd[1] == "nick" then
nick = tCmd[2]
s:write(formatLine("nick",nick))
end
else
s:write(formatLine("msg",msg))
end
if s.state ~= "open" then
linemsg("Disconnected from server, exiting")
run = false
end
end

event.cancel(timer)

+ 94
- 0
minitel-chat/chatd.lua View File

@@ -0,0 +1,94 @@
local net = require "net"
local event = require "event"
local syslog = require "syslog"
local serial = require "serialization"

local cfgfile = "/etc/chatd.cfg"
local clients = {}
local cfg = {}
cfg.port = 194
cfg.topic = "Welcome to the "..os.getenv("HOSTNAME").." chat server."
local timer = false

local function saveconfig()
local f = io.open(cfgfile,"wb")
if f then
f:write(serial.serialize(cfg))
f:close()
end
end
local function loadconfig()
local f = io.open(cfgfile,"rb")
if f then
local newcfg = serial.unserialize(f:read("*a"))
f:close()
for k,v in pairs(newcfg) do
cfg[k] = v
end
else
saveconfig()
end
end

local function log(msg,level)
syslog(msg,level,"chatd")
end

local function sendToAll(data)
for k,v in pairs(clients) do
v:write(data)
end
end
local function formatLine(...)
local tA = {...}
return string.format("%s"..("\t%s"):rep(#tA-1).."\n", ...)
end

local function clientLoop()
for sn, socket in pairs(clients) do
local line = socket.rbuffer:match("(.+)\n")
if line then
socket:read(line:len()+1)
local tCmd = {}
for w in line:gmatch("[^\t]+") do
tCmd[#tCmd+1] = w
end
if tCmd[1] == "nick" then
if socket.nick then
sendToAll(formatLine("nick",socket.nick,tCmd[2]))
else
log(tostring(socket.addr)..":"..tostring(socket.port).." connected as "..tCmd[2])
socket:write(formatLine("topic",cfg.topic))
sendToAll(formatLine("join",tCmd[2]))
end
socket.nick = tCmd[2]
elseif tCmd[1] == "msg" and socket.nick then
sendToAll(formatLine("msg",socket.nick,tCmd[2]))
end
end
if socket.state ~= "open" then
log(tostring(socket.addr)..":"..tostring(socket.port).." ("..tostring(socket.nick)..") quit")
clients[sn] = nil
if socket.nick then
sendToAll(formatLine("quit",socket.nick))
end
end
end
end

local function handleSocket(s)
clients[tostring(s.addr)..":"..tostring(s.port)] = s
end

function start()
loadconfig()
net.flisten(cfg.port,handleSocket)
timer = event.timer(1,clientLoop,math.huge)
end
function stop()
event.ignore("net_msg",handleSocket)
event.cancel(timer)
for k,v in pairs(clients) do
v:close()
end
end

+ 27
- 0
programs.cfg View File

@@ -0,0 +1,27 @@
{
["minitel-chat"] = {
files = {
["master/minitel-chat/chat.lua"] = "/bin",
},
dependencies = {
["minitel"] = "",
},
name = "Minitel Chat",
description = "Exceedingly dumb chat client",
authors = "Izaya",
repo = "tree/master/"
},
["minitel-chatd"] = {
files = {
["master/minitel-chat/chatd.lua"] = "//etc/rc.d",
},
dependencies = {
["minitel"] = "",
["libsyslog"] = "",
},
name = "Minitel Chat (Server)",
description = "Exceedingly dumb chat server",
authors = "Izaya",
repo = "tree/master/"
},
}

Loading…
Cancel
Save