You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 line
5.2KB

  1. {-# LANGUAGE MultiWayIf #-}
  2. module IrcBot.BotActions where
  3. import Network.Connection
  4. import Network.Socket hiding (send, sendTo, recv, recvFrom)
  5. import qualified Data.ByteString.Char8 as C
  6. import IrcBot.BotNetwork
  7. import IrcBot.BotNetworkCommands
  8. import IrcBot.MessageParser
  9. import IrcBot.BotCustomCommands
  10. import IrcBot.Definitions.ServerResponse
  11. import IrcBot.Definitions.ServerAddress
  12. import qualified Data.ByteString.Lazy as L
  13. import IrcBot.Definitions.Options
  14. import qualified Data.Aeson as A
  15. import Data.Maybe
  16. import qualified Data.List as DL
  17. -- its kind of interface for actionFunctions
  18. callActionFunction :: (IServerResponse -> IO()) -> IServerResponse -> IO ()
  19. callActionFunction myFunc parameter1 = myFunc parameter1
  20. callByMethodDefinition :: MethodDefinition -> Connection -> IServerResponse -> IO ()
  21. callByMethodDefinition methodDefinition sock serverResponse = do
  22. let commandCallerString = (callerString methodDefinition)
  23. let commandMethod = (callableFunction methodDefinition)
  24. if hasStringExist commandCallerString (readDataByteString serverResponse) && (commandType methodDefinition) /= NON_RETURN_ACTION then
  25. do
  26. resultString <- commandMethod serverResponse
  27. writeToSocket sock resultString
  28. else if hasStringExist commandCallerString (C.pack (messageType serverResponse)) && (commandType methodDefinition) == NON_RETURN_ACTION then
  29. do
  30. resultString <- commandMethod serverResponse
  31. writeToSocket sock resultString
  32. else
  33. print "COMMAND DOESNT EXIST"
  34. createServerReponse :: C.ByteString -> IServerAddress -> IO IServerResponse
  35. createServerReponse stringData serverAddress =
  36. do
  37. let unpackedByteString = C.unpack stringData
  38. let debugData = "READ DATA FROM SOCKET: " ++ unpackedByteString
  39. print debugData
  40. let messageParsedMeta = words $ parseMessageMeta unpackedByteString
  41. let messageType = parseMessageType messageParsedMeta
  42. print messageParsedMeta
  43. let userNick = parseNick unpackedByteString
  44. let channelName = parseChannelName unpackedByteString
  45. -- let targetNick = parseMessageTargetFromMeta messageParsedMeta
  46. let messageText = parseMessageText unpackedByteString
  47. let target = targetDeterminer userNick channelName
  48. return $ IServerResponse {
  49. serverName = (server serverAddress),
  50. readDataString = unpackedByteString,
  51. readDataByteString = stringData,
  52. channelName = channelName,
  53. nick = userNick,
  54. messageText = messageText,
  55. messageTarget = target,
  56. messageType = messageType
  57. }
  58. messageParse :: Connection -> C.ByteString -> IServerAddress -> IO()
  59. messageParse sock stringData serverAddress =
  60. do
  61. newServerResponse <- createServerReponse stringData serverAddress
  62. determineSockOutputOperation sock newServerResponse
  63. -- mapM (\x -> callActionFunction (x) newServerResponse) (methods myMethodList)
  64. -- if | hasStringExist "PING " stringData -> pong sock unpackedByteString
  65. -- | hasStringExist ".sup" stringData -> sendMessage sock channelName ("sup " ++ userNick)
  66. -- | hasStringExist " KICK #" stringData -> joinChannel sock channelName >> {-- auto connect in case of kick --} sendMessage sock channelName "fuck you"
  67. -- | hasStringExist ".random" stringData -> basicRandomImplementation unpackedByteString >>= \commandOutput -> sendMessage sock channelName commandOutput
  68. -- | hasStringExist ".quit" stringData -> quitFromServer sock channelName
  69. -- | hasStringExist ".leave" stringData -> disconnectFromChannel sock channelName
  70. -- | otherwise -> print "NO CONDITION FOUND TO PARSE"
  71. determineSockOutputOperation :: Connection -> IServerResponse -> IO ()
  72. determineSockOutputOperation sock newServerResponse = do
  73. output <- L.readFile ".connection.json"
  74. let option = fromJust (A.decode output :: Maybe IOptions)
  75. if elem (nick newServerResponse) (admins option)
  76. then do
  77. mapM (\x -> callByMethodDefinition x sock newServerResponse) (methods myAdminMethodList)
  78. mapM (\x -> callByMethodDefinition x sock newServerResponse) (methods myMethodList)
  79. print "command from admin"
  80. else do
  81. mapM (\x -> callByMethodDefinition x sock newServerResponse) (methods myMethodList)
  82. print "command from normal user"
  83. connectToServer :: String -> PortNumber -> Bool -> IO Connection
  84. connectToServer server port ssl = do
  85. open server port ssl
  86. connectionLoop :: Connection -> IServerAddress -> IO Connection
  87. connectionLoop sock serverAddress =
  88. do
  89. stringData <- readFromSocket sock
  90. messageParse sock stringData serverAddress
  91. case stringData == C.empty of
  92. False -> do
  93. connectionLoop sock serverAddress
  94. True -> do
  95. return sock