diff options
-rw-r--r-- | examples/dhtd.hs | 90 | ||||
-rw-r--r-- | src/Network/Tox/Crypto/Handlers.hs | 13 |
2 files changed, 103 insertions, 0 deletions
diff --git a/examples/dhtd.hs b/examples/dhtd.hs index ce1e1b16..291d0530 100644 --- a/examples/dhtd.hs +++ b/examples/dhtd.hs | |||
@@ -35,6 +35,7 @@ import Data.Function | |||
35 | import Data.Hashable | 35 | import Data.Hashable |
36 | import Data.List | 36 | import Data.List |
37 | import Data.Word | 37 | import Data.Word |
38 | import Data.InOrOut | ||
38 | import qualified Data.IntMap.Strict as IntMap | 39 | import qualified Data.IntMap.Strict as IntMap |
39 | import qualified Data.Map.Strict as Map | 40 | import qualified Data.Map.Strict as Map |
40 | import Data.Maybe | 41 | import Data.Maybe |
@@ -122,10 +123,15 @@ showColumns rows = do | |||
122 | _ <- take 1 fs -- Guard against empty rows so that 'last' is safe. | 123 | _ <- take 1 fs -- Guard against empty rows so that 'last' is safe. |
123 | " " ++ concat (zipWith (printf "%-*s") (init ws) (init fs)) ++ last fs ++ "\n" | 124 | " " ++ concat (zipWith (printf "%-*s") (init ws) (init fs)) ++ last fs ++ "\n" |
124 | 125 | ||
126 | pshow :: Show a => a -> B.ByteString | ||
127 | pshow = B.pack . show | ||
125 | 128 | ||
126 | marshalForClient :: String -> String | 129 | marshalForClient :: String -> String |
127 | marshalForClient s = show (length s) ++ ":" ++ s | 130 | marshalForClient s = show (length s) ++ ":" ++ s |
128 | 131 | ||
132 | marshalForClientB :: B.ByteString -> B.ByteString | ||
133 | marshalForClientB s = B.concat [pshow (B.length s),":",s] | ||
134 | |||
129 | data ClientHandle = ClientHandle Handle (MVar Int) | 135 | data ClientHandle = ClientHandle Handle (MVar Int) |
130 | 136 | ||
131 | -- | Writes a message and signals ready for next command. | 137 | -- | Writes a message and signals ready for next command. |
@@ -135,6 +141,13 @@ hPutClient (ClientHandle h hstate) s = do | |||
135 | hPutStr h ('.' : marshalForClient s) | 141 | hPutStr h ('.' : marshalForClient s) |
136 | putMVar hstate 1 -- ready for input | 142 | putMVar hstate 1 -- ready for input |
137 | 143 | ||
144 | -- | Writes a message and signals ready for next command. | ||
145 | hPutClientB :: ClientHandle -> B.ByteString -> IO () | ||
146 | hPutClientB (ClientHandle h hstate) s = do | ||
147 | st <- takeMVar hstate | ||
148 | B.hPutStr h ('.' `B.cons` marshalForClientB s) | ||
149 | putMVar hstate 1 -- ready for input | ||
150 | |||
138 | -- | Writes message, but signals there is more to come. | 151 | -- | Writes message, but signals there is more to come. |
139 | hPutClientChunk :: ClientHandle -> String -> IO () | 152 | hPutClientChunk :: ClientHandle -> String -> IO () |
140 | hPutClientChunk (ClientHandle h hstate) s = do | 153 | hPutClientChunk (ClientHandle h hstate) s = do |
@@ -730,6 +743,41 @@ clientSession s@Session{..} sock cnum h = do | |||
730 | else do | 743 | else do |
731 | rows <- sessionsReport | 744 | rows <- sessionsReport |
732 | hPutClient h (showColumns (headers:rows)) | 745 | hPutClient h (showColumns (headers:rows)) |
746 | -- session <N> tail | ||
747 | -- show context (latest lossless messages) | ||
748 | ("session", s) | (idStr,tailcmd,unstripped) <- twoWords s | ||
749 | , "" <- strp unstripped | ||
750 | , tailcmd `elem` ["tail","context"] | ||
751 | -> cmd0 $ do | ||
752 | lrSession <- strToSession idStr | ||
753 | case lrSession of | ||
754 | Left s -> hPutClient h s | ||
755 | Right session -> do | ||
756 | msgs <- atomically $ CB.cyclicBufferViewList (Tox.ncLastNMsgs session) | ||
757 | hPutClientB h (B.unlines (map showMsg msgs)) | ||
758 | -- session <N> me | ||
759 | -- display information about how you look to that session | ||
760 | ("session", s) | (idStr,"me",unstripped) <- twoWords s | ||
761 | , "" <- strp unstripped | ||
762 | -> cmd0 $ do | ||
763 | lrSession <- strToSession idStr | ||
764 | case lrSession of | ||
765 | Left s -> hPutClient h s | ||
766 | Right session -> do | ||
767 | view <- atomically (readTVar (Tox.ncView session) >>= Tox.viewSnapshot) | ||
768 | hPutClientB h (vShowMe view 0) | ||
769 | -- session <N> them | ||
770 | -- display information about the person on the other end of the session | ||
771 | ("session", s) | (idStr,them,unstripped) <- twoWords s | ||
772 | , "" <- strp unstripped | ||
773 | , them `elem` ["them","you"] | ||
774 | -> cmd0 $ do | ||
775 | lrSession <- strToSession idStr | ||
776 | case lrSession of | ||
777 | Left s -> hPutClient h s | ||
778 | Right session -> do | ||
779 | view <- atomically (readTVar (Tox.ncView session) >>= Tox.viewSnapshot) | ||
780 | hPutClientB h (vShowThem view 0) | ||
733 | -- session <N> online | 781 | -- session <N> online |
734 | -- send ONLINE packet to session N | 782 | -- send ONLINE packet to session N |
735 | ("session", s) | (idStr,"online",unstripped) <- twoWords s | 783 | ("session", s) | (idStr,"online",unstripped) <- twoWords s |
@@ -833,6 +881,20 @@ clientSession s@Session{..} sock cnum h = do | |||
833 | Just tox-> do | 881 | Just tox-> do |
834 | Tox.setStatusMsg (Tox.toxCryptoKeys tox) session (B.pack statusmsg) | 882 | Tox.setStatusMsg (Tox.toxCryptoKeys tox) session (B.pack statusmsg) |
835 | hPutClient h "sent STATUSMESSAGE" | 883 | hPutClient h "sent STATUSMESSAGE" |
884 | -- session <N> c <MSG> | ||
885 | -- send MESSAGE packet to session N (send chat message MSG) | ||
886 | ("session", s) | (idStr,msgcmd,msg) <- twoWords s | ||
887 | , msgcmd `elem` ["c","msg","send"] | ||
888 | -> cmd0 $ do | ||
889 | lrSession <- strToSession idStr | ||
890 | case lrSession of | ||
891 | Left s -> hPutClient h s | ||
892 | Right session -> do | ||
893 | case mbTox of | ||
894 | Nothing -> hPutClient h "Requires Tox enabled." | ||
895 | Just tox-> do | ||
896 | Tox.sendChatMsg (Tox.toxCryptoKeys tox) session (B.pack msg) | ||
897 | hPutClient h "sent MESSAGE" | ||
836 | 898 | ||
837 | ("onion", s) -> cmd0 $ join $ atomically $ do | 899 | ("onion", s) -> cmd0 $ join $ atomically $ do |
838 | rm <- readTVar $ routeMap onionRouter | 900 | rm <- readTVar $ routeMap onionRouter |
@@ -1432,6 +1494,34 @@ announceToxJabberPeer echan laddr saddr pingflag tsrc tsnk | |||
1432 | 1494 | ||
1433 | #endif | 1495 | #endif |
1434 | 1496 | ||
1497 | vShowMe :: Tox.ViewSnapshot -> Int -> B.ByteString | ||
1498 | vShowMe (Tox.ViewSnapshot { vNick, vStatus, vStatusMsg, vTyping }) indent | ||
1499 | = B.unlines | ||
1500 | . map doRow $ [ ["Nick: ", vNick ] | ||
1501 | , ["Status: ", "(" <> pshow vStatus <> ") " <> vStatusMsg ] | ||
1502 | , ["Typing: ", pshow vTyping ] | ||
1503 | ] | ||
1504 | where (<>) = B.append | ||
1505 | space = B.replicate indent ' ' | ||
1506 | doRow = B.append space . B.concat | ||
1507 | |||
1508 | vShowThem :: Tox.ViewSnapshot -> Int -> B.ByteString | ||
1509 | vShowThem (Tox.ViewSnapshot { vTheirNick, vTheirStatus, vTheirStatusMsg, vTheirTyping }) indent | ||
1510 | = B.unlines | ||
1511 | . map doRow $ [ ["Nick: ", vTheirNick ] | ||
1512 | , ["Status: ", "(" <> pshow vTheirStatus <> ") " <> vTheirStatusMsg ] | ||
1513 | , ["Typing: ", pshow vTheirTyping ] | ||
1514 | ] | ||
1515 | where (<>) = B.append | ||
1516 | space = B.replicate indent ' ' | ||
1517 | doRow = B.append space . B.concat | ||
1518 | |||
1519 | showMsg ::(Word32, (Bool,(Tox.ViewSnapshot, InOrOut Tox.CryptoMessage))) -> B.ByteString | ||
1520 | showMsg (n,(flg,(snapshot,iocm))) = B.concat [bool " " "h " flg, showmsg' (snapshot,iocm)] | ||
1521 | where | ||
1522 | showmsg' (snapshot,In cm) = B.concat [Tox.vNick snapshot,"> ", pshow cm] | ||
1523 | showmsg' (snapshot,Out cm) = B.concat [utf8boldify (Tox.vNick snapshot),": ",pshow cm] | ||
1524 | utf8boldify s = s | ||
1435 | 1525 | ||
1436 | main :: IO () | 1526 | main :: IO () |
1437 | main = runResourceT $ liftBaseWith $ \resT -> do | 1527 | main = runResourceT $ liftBaseWith $ \resT -> do |
diff --git a/src/Network/Tox/Crypto/Handlers.hs b/src/Network/Tox/Crypto/Handlers.hs index 92cb19b8..2902685c 100644 --- a/src/Network/Tox/Crypto/Handlers.hs +++ b/src/Network/Tox/Crypto/Handlers.hs | |||
@@ -806,6 +806,19 @@ setStatusMsg crypto session msg = do | |||
806 | addMsgToLastN False (cm ^. messageType) session (Out cm) | 806 | addMsgToLastN False (cm ^. messageType) session (Out cm) |
807 | sendCrypto crypto session updateLocal cm | 807 | sendCrypto crypto session updateLocal cm |
808 | 808 | ||
809 | sendChatMsg :: TransportCrypto -> NetCryptoSession -> ByteString -> IO (Either String ()) | ||
810 | sendChatMsg crypto session msg = do | ||
811 | let Just (_,maxlen) = msgSizeParam MESSAGE | ||
812 | if B.length msg > maxlen | ||
813 | then return (Left $ "status message must not exceed " ++ show maxlen ++ " bytes.") | ||
814 | else do | ||
815 | let updateLocal = do | ||
816 | view <- readTVar (ncView session) | ||
817 | writeTVar (svStatusMsg view) msg | ||
818 | let cm = UpToN MESSAGE msg | ||
819 | addMsgToLastN False (cm ^. messageType) session (Out cm) | ||
820 | sendCrypto crypto session updateLocal cm | ||
821 | |||
809 | -- | handles nothings | 822 | -- | handles nothings |
810 | defaultCryptoDataHooks :: Map.Map MessageType [NetCryptoHook] | 823 | defaultCryptoDataHooks :: Map.Map MessageType [NetCryptoHook] |
811 | defaultCryptoDataHooks | 824 | defaultCryptoDataHooks |