summaryrefslogtreecommitdiff
path: root/Presence/XMPPServer.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-11-14 01:28:47 -0500
committerJoe Crayne <joe@jerkface.net>2018-11-14 01:29:41 -0500
commit2049cc83b60dca41f636190f87cb1f21707f3530 (patch)
tree2ef910cdd207229b675a38411abfd47bf074cb6b /Presence/XMPPServer.hs
parent2a0902701e7c806c2cfd2561d8af1f56539e8811 (diff)
MUC: It works.
Diffstat (limited to 'Presence/XMPPServer.hs')
-rw-r--r--Presence/XMPPServer.hs111
1 files changed, 102 insertions, 9 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index e44ae37b..d26e8c03 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -1364,6 +1364,28 @@ monitor sv params xmpp = do
1364 , EventEndElement "{http://jabber.org/protocol/muc#user}x" 1364 , EventEndElement "{http://jabber.org/protocol/muc#user}x"
1365 ] 1365 ]
1366 ioWriteChan replyto stanza 1366 ioWriteChan replyto stanza
1367 Part -> do
1368 stanza <- makePresenceStanzaEx "jabber:client" (Just $ roomjid muckey me rkey cnick) Offline
1369 $ [ EventBeginElement "{http://jabber.org/protocol/muc#user}x" [] ]
1370 ++ (do guard mine
1371 [ EventBeginElement "{http://jabber.org/protocol/muc#user}status"
1372 [ ("code",[ContentText "110"]) -- self-presence code.
1373 ]
1374 , EventEndElement "{http://jabber.org/protocol/muc#user}status" ])
1375 ++ [ EventEndElement "{http://jabber.org/protocol/muc#user}x" ]
1376 ioWriteChan replyto stanza
1377 when mine $ atomically $ do
1378 jrs <- readTVar joined_rooms
1379 let m = Map.findWithDefault Map.empty k jrs
1380 m' = Map.delete (rkey,muckey) m
1381 jrs' = if Map.null m' then Map.delete k jrs
1382 else Map.insert k m' jrs
1383 writeTVar joined_rooms jrs'
1384 Talk talk -> do
1385 them <- xmppTellClientHisName xmpp k
1386 stanza <- makeMessageEx "jabber:client" (roomjid muckey me rkey cnick) them GroupChatMsg talk
1387 ioWriteChan replyto stanza
1388 return ()
1367 _ -> return () 1389 _ -> return ()
1368 ] 1390 ]
1369 action 1391 action
@@ -1409,7 +1431,7 @@ data ServiceMatch a
1409 | TopLevelService -- ^ This server's exact hostname. 1431 | TopLevelService -- ^ This server's exact hostname.
1410 1432
1411 1433
1412lookupService :: Text -> Map.Map Text a -> Text -> (ServiceMatch a) 1434lookupService :: Text {- ^ hostname -} -> Map.Map Text a {- ^ service map -} -> Text {- ^ JID -} -> (ServiceMatch a)
1413lookupService me mucs to = case Text.toLower to of 1435lookupService me mucs to = case Text.toLower to of
1414 nm | nm == Text.toLower me 1436 nm | nm == Text.toLower me
1415 -> TopLevelService 1437 -> TopLevelService
@@ -1432,7 +1454,9 @@ applyStanza :: Server PeerAddress ConnectionData releaseKey Event
1432 -> StanzaWrap (LockedChan Event) 1454 -> StanzaWrap (LockedChan Event)
1433 -> IO () 1455 -> IO ()
1434 1456
1435applyStanza sv joined_rooms quitVar xmpp stanza = case stanzaOrigin stanza of 1457applyStanza sv joined_rooms quitVar xmpp stanza = do
1458 dput XJabber $ "applyStanza: " ++ show (stanzaType stanza)
1459 case stanzaOrigin stanza of
1436 ClientOrigin k replyto -> 1460 ClientOrigin k replyto ->
1437 case stanzaType stanza of 1461 case stanzaType stanza of
1438 RequestResource clientsNameForMe wanted -> do 1462 RequestResource clientsNameForMe wanted -> do
@@ -1479,8 +1503,7 @@ applyStanza sv joined_rooms quitVar xmpp stanza = case stanzaOrigin stanza of
1479 PresenceStatus {} -> do 1503 PresenceStatus {} -> do
1480 let mucs = xmppGroupChat xmpp 1504 let mucs = xmppGroupChat xmpp
1481 me <- xmppTellMyNameToClient xmpp k 1505 me <- xmppTellMyNameToClient xmpp k
1482 if | Available <- presenceShow (stanzaType stanza) 1506 if | Just to <- stanzaTo stanza
1483 , Just to <- stanzaTo stanza
1484 , (Just room,h,mnick) <- splitJID to 1507 , (Just room,h,mnick) <- splitJID to
1485 , let roomjid = unsplitJID ((Just room,h,Nothing)) 1508 , let roomjid = unsplitJID ((Just room,h,Nothing))
1486 , Service (Just _) mucname muc <- lookupService me mucs roomjid 1509 , Service (Just _) mucname muc <- lookupService me mucs roomjid
@@ -1490,13 +1513,34 @@ applyStanza sv joined_rooms quitVar xmpp stanza = case stanzaOrigin stanza of
1490 reply <- makeErrorStanza' stanza JidMalformed 1513 reply <- makeErrorStanza' stanza JidMalformed
1491 [ ("by", [ContentText roomjid]) ] 1514 [ ("by", [ContentText roomjid]) ]
1492 sendReply quitVar (Error JidMalformed (head reply)) reply replyto 1515 sendReply quitVar (Error JidMalformed (head reply)) reply replyto
1493 Just nick -> do 1516 Just nick -> case presenceShow (stanzaType stanza) of
1494 jid <- xmppTellClientHisName xmpp k 1517 Available -> do
1495 r <- mucJoinRoom muc jid nick room k -- stanza 1518 jid <- xmppTellClientHisName xmpp k
1496 atomically $ do 1519 join $ atomically $ do
1497 jrs <- readTVar joined_rooms 1520 jrs <- readTVar joined_rooms
1498 let m = Map.findWithDefault Map.empty k jrs 1521 let m = Map.findWithDefault Map.empty k jrs
1499 writeTVar joined_rooms $ Map.insert k (Map.insert (room,mucname) (replyto,r) m) jrs 1522 case Map.lookup (room,mucname) m of
1523 Nothing -> do r <- mucJoinRoom muc jid nick room k -- stanza
1524 jrs <- readTVar joined_rooms
1525 let m = Map.findWithDefault Map.empty k jrs
1526 writeTVar joined_rooms $ Map.insert k (Map.insert (room,mucname) (replyto,r) m) jrs
1527 return $ return ()
1528 Just r -> return $ dput XJabber "MUC: already joined."
1529 Offline -> do
1530 jid <- xmppTellClientHisName xmpp k
1531 atomically $ do
1532 jrs <- readTVar joined_rooms
1533 let m = Map.findWithDefault Map.empty k jrs
1534 case Map.lookup (room,mucname) m of
1535 Just (_,r) -> do
1536 partRoom r (Just jid) -- joinedNick r == nick
1537 {-
1538 let m' = Map.delete (room,mucname) m
1539 jrs' = if Map.null m' then Map.delete k jrs
1540 else Map.insert k m' jrs
1541 writeTVar joined_rooms jrs'
1542 -}
1543 _ -> return ()
1500 | otherwise -> do 1544 | otherwise -> do
1501 -- Handle presence stanza that is not a chatroom join. 1545 -- Handle presence stanza that is not a chatroom join.
1502 xmppInformClientPresence xmpp k stanza 1546 xmppInformClientPresence xmpp k stanza
@@ -1541,6 +1585,24 @@ applyStanza sv joined_rooms quitVar xmpp stanza = case stanzaOrigin stanza of
1541 let reply = makeNodeInfo (stanzaId stanza) "x-roomuser-item" (room <> "@" <> a <> "." <> me) 1585 let reply = makeNodeInfo (stanzaId stanza) "x-roomuser-item" (room <> "@" <> a <> "." <> me)
1542 (stanzaFrom stanza) n 1586 (stanzaFrom stanza) n
1543 return (Info, reply) 1587 return (Info, reply)
1588 (Service (Just room) a muc) | Just "http://jabber.org/protocol/muc#traffic" <- mnode
1589 -> do
1590 dput XJabber $ "TODO: 18.1.1 Allowable Traffic"
1591 reply <- makeErrorStanza' stanza FeatureNotImplemented
1592 [ ("by", [ContentText (room <> "@" <> a <> "." <> me)]) ]
1593 return (Error FeatureNotImplemented (head reply), reply)
1594 (Service (Just room) a muc) | Just "http://jabber.org/protocol/muc#rooms" <- mnode
1595 -> do
1596 dput XJabber $ "TODO: 6.7 Discovering Client Support for MUC"
1597 reply <- makeErrorStanza' stanza FeatureNotImplemented
1598 [ ("by", [ContentText (room <> "@" <> a <> "." <> me)]) ]
1599 return (Error FeatureNotImplemented (head reply), reply)
1600 (Service (Just room) a muc) | Just nodename <- mnode
1601 -> do
1602 dput XJabber $ "Uknown info node: " ++ Text.unpack nodename
1603 reply <- makeErrorStanza' stanza FeatureNotImplemented
1604 [ ("by", [ContentText (room <> "@" <> a <> "." <> me)]) ]
1605 return (Error FeatureNotImplemented (head reply), reply)
1544 TopLevelService 1606 TopLevelService
1545 -> case mnode of 1607 -> case mnode of
1546 Just _ -> unavail 1608 Just _ -> unavail
@@ -1579,6 +1641,36 @@ applyStanza sv joined_rooms quitVar xmpp stanza = case stanzaOrigin stanza of
1579 me <- xmppTellMyNameToClient xmpp k 1641 me <- xmppTellMyNameToClient xmpp k
1580 let reply = iq_service_unavailable (stanzaId stanza) me query 1642 let reply = iq_service_unavailable (stanzaId stanza) me query
1581 sendReply quitVar (Error ServiceUnavailable (head reply)) reply replyto 1643 sendReply quitVar (Error ServiceUnavailable (head reply)) reply replyto
1644 Message { msgType = GroupChatMsg } -> do
1645 let mucs = xmppGroupChat xmpp
1646 me <- xmppTellMyNameToClient xmpp k
1647 if | Just to <- stanzaTo stanza
1648 , (Just room,h,mnick) <- splitJID to
1649 , let roomjid = unsplitJID ((Just room,h,Nothing))
1650 , Service (Just _) mucname muc <- lookupService me mucs roomjid
1651 -> case mnick of
1652 Nothing -> do
1653 -- Send message.
1654 jid <- xmppTellClientHisName xmpp k -- This should match stanzaFrom
1655 join $ atomically $ do
1656 jrs <- readTVar joined_rooms
1657 let m = Map.findWithDefault Map.empty k jrs
1658 case Map.lookup (room,mucname) m of
1659 Just (_,r) -> do
1660 let RH v = roomHandle r
1661 oldt <- readTVar v
1662 expected <- readTVar (roomFutureSeqNo $ joinedRoom r)
1663 b <- sendChat r (Just jid) $ do
1664 (_,msg) <- msgLangMap (stanzaType stanza)
1665 talk <- maybeToList $ msgBody msg
1666 [ Talk talk ]
1667 return $ dput XJabber $ "sendChat: " ++ show (b,expected,oldt,msgLangMap (stanzaType stanza))
1668 _ -> return $ dput XJabber $ "uknown room" ++ show (room,mucname)
1669 Just nick -> do
1670 -- Private message. TODO
1671 dput XJabber $ "TODO: Private messasge. " ++ show nick
1672
1673 | otherwise -> dput XJabber $ "Failed groupchat parse. to=" ++ show (stanzaTo stanza)
1582 Message {} -> do 1674 Message {} -> do
1583 -- wlog $ "LANGMAP "++show (stanzaId stanza, msgLangMap (stanzaType stanza)) 1675 -- wlog $ "LANGMAP "++show (stanzaId stanza, msgLangMap (stanzaType stanza))
1584 maybe (return ()) (flip cacheMessageId replyto) $ do 1676 maybe (return ()) (flip cacheMessageId replyto) $ do
@@ -1615,6 +1707,7 @@ forwardStanza quitVar xmpp stanza = do
1615 -- let newStream = greet'' "jabber:client" "blackbird" 1707 -- let newStream = greet'' "jabber:client" "blackbird"
1616 -- sendReply quitVar Error newStream replyto 1708 -- sendReply quitVar Error newStream replyto
1617 case stanzaType stanza of 1709 case stanzaType stanza of
1710 Message { msgType = GroupChatMsg } -> return () -- Group chat handled elsewhere.
1618 Message {} -> do 1711 Message {} -> do
1619 case stanzaOrigin stanza of 1712 case stanzaOrigin stanza of
1620 LocalPeer {} -> return () 1713 LocalPeer {} -> return ()