summaryrefslogtreecommitdiff
path: root/nanochat/pylon.lua
diff options
context:
space:
mode:
Diffstat (limited to 'nanochat/pylon.lua')
-rw-r--r--nanochat/pylon.lua85
1 files changed, 85 insertions, 0 deletions
diff --git a/nanochat/pylon.lua b/nanochat/pylon.lua
new file mode 100644
index 0000000..6fbd725
--- /dev/null
+++ b/nanochat/pylon.lua
@@ -0,0 +1,85 @@
+local cqueues = require 'cqueues'
+local socket = require 'cqueues.socket'
+local class = require 'r.class'
+
+local BasePylon = require 'pylon'
+local Thing = require 'thing'
+
+local Nanochat = class.extend(BasePylon)
+
+function Nanochat:init()
+ self:_check_fields "server port poll"
+end
+
+function Nanochat:_connect()
+ self.sock = socket.connect(self.server, tonumber(self.port))
+ self.sock:write("LAST 0\n")
+ self.sock:read("*l") -- discard count
+ self.lastid = tonumber(assert(self.sock:read("*l")))
+ self.usids = {}
+end
+
+function Nanochat:recving()
+ while true do
+ self.sock:write("SKIP "..self.lastid.."\n")
+ local deliverables = {} -- holey
+ local n = tonumber(assert(self.sock:read("*l")))
+ for i=1,n do
+ local msg = assert(self.sock:read("*l"))
+ local chan, msgi = msg:match("^([^ ]+) ()")
+ if chan then
+ local sender, body = msg:match("^([^:]+): (.+)$", msgi)
+ if sender then
+ deliverables[i] = {
+ pylon=self,
+ channel=Thing(self, chan),
+ author=Thing(self,sender),
+ body=body
+ }
+ else
+ deliverables[i] = {
+ pylon=self,
+ channel=Thing(self, chan),
+ author=Thing(self,""),
+ body=msg:sub(msgi,-1)
+ }
+ end
+ else -- luacheck: ignore 542
+ -- ignore messages without a channel, they stay nanochat-local
+ end
+ end
+ local s = self.sock:read("*l")
+ self.lastid = tonumber(assert(s))
+
+ for i=1,n do
+ local msg = deliverables[i] ; if msg then
+ local id = i - n + self.lastid
+ if self.usids[id] then
+ self.usids[id] = nil
+ else
+ self.log:proto('<', msg.channel.id, msg.author, msg.body)
+ self.wilson:deliver(msg)
+ end
+ end
+ end
+
+ cqueues.sleep(tonumber(self.poll))
+ end
+end
+
+function Nanochat:sending()
+ for dest_channel, message in self.inbox:iter() do
+ self.log:proto('>',dest_channel,message.author,message.body)
+ assert(self.sock:write(
+ "SEND "
+ ..dest_channel.id
+ ..message.author:name_with_shortname()
+ ..": "..message.body
+ .."\n"))
+ local id = tonumber(assert(self.sock:read("*l")))
+ self.usids[id] = true
+ end
+end
+
+
+return Nanochat