local motd = { ' __ ' , ' ___________/__\\___________ ', ' / _ _ -__ - ___ - \\', ' \\__________________________/', ' | | ' , ' | | ' , ' _____| |______ ' , ' ___| | | |___ ' , ' | | | | | | ' , '___|___|____/____\\_____|___|___', '', ' Welcome to Er2Chat!', ' You need to login to continue', } local cls = {} local tmp = {} utf8 = require '.utf8' local back = { tcp = require '.tcp', http = require '.http', -- ws = require '.ws', } local main = { 'tcp', -- 'ws', } function get(v, ...) return back[v.back].get(v, ...) end function close(v, ...) return back[v.back].close(v, ...) end function write(v, ...) return back[v.back].write(v, ...) end function writeln(v, ...) return back[v.back].writeln(v, ...) end function makev(cli, back) if not cli then return end return { cli = cli, st = 0, back = back, } end function init(v) writeln(v, table.unpack(motd)) writeln(v, '') table.insert(tmp, v) end function forc(fn, t, c) if c == nil or c == true then local k = 1 while k <= #cls do local v = cls[k] fn(v, k) if v.closed then table.remove(cls, k) else k = k + 1 end end end if t then local k = 1 while k <= #tmp do local v = tmp[k] fn(v, k) if v.closed then table.remove(tmp, k) else k = k + 1 end end end end local runs = true while runs do for _, v in pairs(main) do local p, w = back[v]._loop(v) if p and back[p] then back[p]._loop(v, w) end end forc(function(v, k) if v.reads then -- nothing elseif v.st == 0 then write (v, 'Do you need input echo? [YNHQ] ') elseif v.st == 1 then write (v, 'Username: ') elseif v.st == 2 then write (v, 'Password: ') elseif v.st == 3 then writeln(v, 'Welcome, '.. v.user ..'!') local us = '' for _, w in pairs(cls) do writeln(w, '', '-- '.. v.user ..' joined --') us = us.. w.user ..', ' end writeln(v, 'Online: '.. us ..v.user) v.st, v.reads = nil, nil table.remove(tmp, k) table.insert(cls, v) end if v.st then v.reads = true local l, err = get(v) if err == 'timeout' then -- nothing elseif err then close(v) --elseif (l or ''):match '^%s*$' then v.reads = false elseif v.st == 0 then v.st, v.reads = 1, false if l:match '[Yy]' then v.le = true; writeln(v, l) elseif l:match '[QqEe]' then close(v) elseif l:match '[Nn]' then -- nothing else v.st = 0 writeln(v, l, 'Say N if you see your input twice.', 'Say Y if not.', 'Say Q to exit.') end elseif v.st == 1 then v.reads = false if #(l:match '^%S+' or '') >= 3 then v.user, v.st = l:match '^%S+', 3 else writeln(v, 'Provide username with length >= 3 symbols') end elseif v.st == 2 then v.st, v.reads = 1, false end end end, true, false) forc(function(v, k) local l, err = get(v) if err and err ~= 'timeout' then close(v) end if l == '/help' then writeln(v, '-- HELP --', '/leave - Close chat' ) elseif l == '/leave' then close(v) elseif (l or ''):sub(1, 1) == '/' then writeln(v, 'Unknown command') end if not (l or ''):match '^%s*$' and (not l:sub(1, 1) == '/' or v.closed) then for j, w in pairs(cls) do if j == k then -- ignore yourself elseif v.closed then writeln(w, '', '-- '.. v.user ..' leaves --') else writeln(w, '', v.user ..': '.. l) end end end end, false, true) end