init.lua 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. -- chat3/init.lua
  2. chat3 = {}
  3. chat3.settings = {}
  4. chat3.storage = minetest.get_mod_storage()
  5. local modpath = minetest.get_modpath("chat3")
  6. local prot = {} -- Table of protocol versions - to be used later
  7. ---
  8. --- Handle Settings
  9. ---
  10. -- [function] Get float setting
  11. function chat3.settings.get_int(key)
  12. local res = minetest.settings:get(key)
  13. if res then
  14. return tonumber(res)
  15. end
  16. end
  17. -- [function] Get boolean setting
  18. function chat3.settings.get_bool(key, default)
  19. local retval = minetest.settings:get_bool(key)
  20. if default and retval == nil then
  21. retval = default
  22. end
  23. return retval
  24. end
  25. local bell = chat3.settings.get_bool("chat3.bell")
  26. local shout = chat3.settings.get_bool("chat3.shout")
  27. local prefix = minetest.settings:get("chat3.shout_prefix") or "!"
  28. local near = chat3.settings.get_int("chat3.near") or 12
  29. local ignore = chat3.settings.get_bool("chat3.ignore", true)
  30. local alt = chat3.settings.get_bool("chat3.alt_support", true)
  31. if prefix:len() > 1 then
  32. prefix = "!"
  33. end
  34. ---
  35. --- Load Features
  36. ---
  37. if ignore then dofile(modpath.."/ignore.lua") end -- Load ignore
  38. if alt then dofile(modpath.."/alt.lua") end -- Load alt
  39. ---
  40. --- Helpers
  41. ---
  42. local function cache_protocal_version(name)
  43. local info = minetest.get_player_information(name)
  44. -- if info is not nil, cache the player's protocol version
  45. if info ~= nil then
  46. prot[name] = info.protocol_version
  47. -- else, if info is nil, the player doesn't exist yet for some reason and
  48. -- caching will occur the first time the information is requested.
  49. end
  50. end
  51. local function get_protocal_version(name)
  52. -- if version is cached, return it
  53. if prot[name] then
  54. return prot[name]
  55. end
  56. -- otherwise, retrive and cache it
  57. cache_protocal_version(name)
  58. end
  59. ---
  60. --- Exposed Functions (API)
  61. ---
  62. -- [function] Colorize
  63. function chat3.colorize(name, colour, msg)
  64. local vers = get_protocal_version(name)
  65. if vers and vers >= 27 then
  66. return minetest.colorize(colour, msg)
  67. else
  68. return msg
  69. end
  70. end
  71. -- [function] Check if mentioned (should highlight or not)
  72. function chat3.is_mentioned(name, msg)
  73. name, msg = name:lower(), msg:lower()
  74. -- Direct mentions
  75. local direct_mention = msg:find(name, 1, true)
  76. -- Alt mentions
  77. local alt_mention
  78. if alt then
  79. local list = chat3.alt.get(name)
  80. for alt, i in pairs(list) do
  81. alt_mention = msg:find(alt, 1, true) or alt_mention
  82. end
  83. end
  84. return direct_mention or alt_mention
  85. end
  86. -- [function] Process
  87. function chat3.send(name, msg, prefix, source)
  88. if not minetest.check_player_privs(name, "shout")
  89. or minetest.get_modpath("ranks") and source ~= "ranks" then
  90. return
  91. end
  92. local sender = minetest.get_player_by_name(name)
  93. for _, player in pairs(minetest.get_connected_players()) do
  94. local rname = player:get_player_name()
  95. local colour = "#ffffff"
  96. local vers = prot[rname]
  97. if (not vers or (vers and (vers >= 29 or (vers < 29 and name ~= rname))))
  98. and (not ignore or not chat3.ignore.is(rname, name) and not chat3.ignore.is(name, rname)) then
  99. -- Check for near
  100. if near ~= 0 then -- and name ~= rname then
  101. if vector.distance(sender:get_pos(), player:get_pos()) <= near then
  102. colour = "#88ffff"
  103. end
  104. end
  105. -- Check for mentions
  106. if chat3.is_mentioned(rname, msg) then
  107. colour = "#00ff00"
  108. -- Chat bell
  109. if bell and name ~= rname then
  110. local pbell = player:get_attribute("chat3:bell")
  111. if pbell ~= "false" then
  112. minetest.sound_play("chat3_bell", {
  113. gain = 4,
  114. to_player = rname,
  115. })
  116. end
  117. end
  118. end
  119. -- Check for shout
  120. if shout and msg:sub(1, 1) == prefix then
  121. colour = "#ff0000"
  122. -- Chat bell
  123. if bell and name ~= rname then
  124. local pbell = player:get_attribute("chat3:bell")
  125. if pbell ~= "false" then
  126. minetest.sound_play("chat3_bell", {
  127. gain = 4,
  128. to_player = rname,
  129. })
  130. end
  131. end
  132. end
  133. -- if same player, set to white
  134. if name == rname then
  135. colour = "#ffffff"
  136. end
  137. -- Send message
  138. local send = chat3.colorize(rname, colour, "<"..name.."> "..msg)
  139. if prefix then
  140. send = prefix..send
  141. end
  142. minetest.chat_send_player(rname, send)
  143. end
  144. end
  145. -- Log message
  146. minetest.log("action", "CHAT: ".."<"..name.."> "..msg)
  147. -- Prevent from sending normally
  148. return true
  149. end
  150. ---
  151. --- Events/Definitions
  152. ---
  153. -- [event] On join player
  154. minetest.register_on_joinplayer(function(player)
  155. local name = player:get_player_name()
  156. cache_protocal_version(name)
  157. end)
  158. -- [event] On chat message
  159. minetest.register_on_chat_message(function(name, msg)
  160. return chat3.send(name, msg)
  161. end)
  162. -- [redefine] /msg
  163. if minetest.chatcommands["msg"] then
  164. local old_command = minetest.chatcommands["msg"].func
  165. minetest.override_chatcommand("msg", {
  166. func = function(name, param)
  167. local sendto, message = param:match("^(%S+)%s(.+)$")
  168. if not sendto then
  169. return false, "Invalid usage, see /help msg."
  170. end
  171. if not minetest.get_player_by_name(sendto) then
  172. return false, "The player " .. sendto
  173. .. " is not online."
  174. end
  175. if ignore and chat3.ignore.is(sendto, name) then
  176. return false, chat3.colorize(name, "red",
  177. "Could not send message, you are on "..sendto.."'s ignore list.")
  178. else
  179. minetest.log("action", "PM from " .. name .. " to " .. sendto
  180. .. ": " .. message)
  181. minetest.chat_send_player(sendto, chat3.colorize(sendto, '#00ff00',
  182. "PM from " .. name .. ": ".. message))
  183. if bell then
  184. local player = minetest.get_player_by_name(sendto)
  185. local pbell = player:get_attribute("chat3:bell")
  186. if pbell ~= "false" then
  187. minetest.sound_play("chat3_bell", {
  188. gain = 4,
  189. to_player = sendto,
  190. })
  191. end
  192. end
  193. if ignore and chat3.ignore.is(name, sendto) then
  194. return true, "Message sent.\n"..chat3.colorize(name, "red",
  195. "Warning: "..sendto.." will not be able to respond to this"
  196. .." message unless you remove them from your ignore list.")
  197. else
  198. return true, "Message sent."
  199. end
  200. end
  201. end,
  202. })
  203. end
  204. -- [redefine] /me
  205. if minetest.chatcommands["me"] then
  206. local old_command = minetest.chatcommands["me"]
  207. minetest.override_chatcommand("me", {
  208. func = function(name, param)
  209. minetest.chat_send_player(name, '* '..name..' '..param)
  210. --[[for _, player in pairs(minetest.get_connected_players()) do
  211. local rname = player:get_player_name()
  212. if not ignore or not chat3.ignore.is(rname, name) then
  213. minetest.chat_send_player(rname, "* "..name.." "..param)
  214. end
  215. end
  216. --]]
  217. end,
  218. })
  219. end
  220. -- [chatcommand] Chatbell
  221. if bell then
  222. minetest.register_chatcommand("chatbell", {
  223. description = "Enable/disable chatbell when you are mentioned in the chat",
  224. func = function(name)
  225. local player = minetest.get_player_by_name(name)
  226. if player then
  227. local bell = player:get_attribute("chat3:bell")
  228. if not bell or bell == "" or bell == "true" then
  229. player:set_attribute("chat3:bell", "false")
  230. return true, "Disabled Chatbell"
  231. else
  232. player:set_attribute("chat3:bell", "true")
  233. return true, "Enabled Chatbell"
  234. end
  235. end
  236. end,
  237. })
  238. end