123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- --[[
- Minetest 0.4.16+ mod: chat2
- chat2 is mod for Minetest, created by Andrey. It's purpose is to improve or replace game built-in chat:
- + Higlight some messages in different colors - nearby talk, PM messages, messages with your name in it, shouts(!)
- + Also can show all regular chat messages (use "/chat2 *" command)
- + Switch on/off (use "/chat2" command)
- + Old messages dissapear after some time
- - Problems with unicode symbols on some clients
- This mod is Free and Open Source Software, released under the GNU LGPLv2.1 or later.
- I used this mod:https://github.com/vegasd/minetest-mods/blob/master/kmchat/init.lua as example for how to use hud api.
- --]]
- chat2 = {}
- chat2.speedlimit = {}
- chat2.lastmessagetimes = {} --minetest.get_gametime()
- chat2.users = {}
- chat2.additionalfilters = {} --additional words set by player, which need to be higligted
- chat2.firsthud = {} --to be able to use previously set huds
- chat2.messages_on_screen = 11
- chat2.chat_width = 100 --symbols
- chat2.position_x = 0.01
- chat2.position_y = 0.92
- chat2.line_distance = 15 --it depends on client, 15 is ok for where i have tested.
- chat2.add_message = function(player, new_text, new_color)
- local temp_text
- local temp_color
- local hud
- local name = player:get_player_name()
- local firsthud = chat2.firsthud[name]
- if not player then
- minetest.log("action", "Player "..name.." - chat2 player error")
- end
- if (not chat2.firsthud[name]) or (not player:hud_get(chat2.firsthud[name]) ) then
- minetest.log("action", "Player "..name.." - chat2 no hud yet error")
- return
- end
- for id = firsthud, (firsthud + chat2.messages_on_screen - 1) do
- hud = player:hud_get(id)
- if hud and hud.name == "chat2" then
- temp_text = hud.text
- temp_color = hud.number
- player:hud_change(id, "number", new_color)
- player:hud_change(id, "text", new_text)
- new_text = temp_text
- new_color = temp_color
- end
- end
- end
- chat2.send_message = function(player, message, color)
- local line1 = nil --allow message to span at most to three lines. more is not ok for public chat.
- local line2 = nil
- local line3 = nil
- local symbols = ''
- for i = 1, #message do
- if
- string.byte(message, i) == 32 and --is space symbol
- string.len(symbols) > (chat2.chat_width - 8) and --space have priority for breaking lines
- (
- not line1 or
- not line2 or
- not line3
- )
- then
- if not line1 then
- line1 = symbols
- symbols = ''
- elseif not line2 then
- line2 = symbols
- symbols = ''
- elseif not line3 then
- line3 = symbols
- symbols = ''
- end
- elseif
- (string.byte(message, i) < 128 or string.byte(message, i) >= 192) and --is ascii or first byte of unicode
- string.len(symbols) > (chat2.chat_width - 1) and
- (
- not line1 or
- not line2 or
- not line3
- )
- then
- if not line1 then
- line1 = symbols
- symbols = ''
- elseif not line2 then
- line2 = symbols
- symbols = ''
- elseif not line3 then
- line3 = symbols
- symbols = ''
- end
- elseif line1 and line2 and line3 then --stop when all three lines filled
- break
- end
- symbols = symbols..message:sub(i,i)
- end
- if not line1 and symbols then --when message is shorten than line
- line1 = symbols
- elseif not line2 and symbols then --when message is shorten than line
- line2 = symbols
- elseif not line3 and symbols then --when message is shorten than line
- line3 = symbols
- end
- if line1 then
- chat2.add_message(player, line1, color)
- end
- if line2 then
- chat2.add_message(player, line2, color)
- end
- if line3 then
- chat2.add_message(player, line3, color)
- end
- if message ~= '' then
- chat2.lastmessagetimes[player:get_player_name()] = minetest.get_gametime()
- end
- end
- minetest.register_on_joinplayer(function(player)
- minetest.after(2, function(player)
- local name = player:get_player_name()
- for i = 1, chat2.messages_on_screen do
- local hud_id = player:hud_add({
- hud_elem_type = "text",
- text = "",
- position = {x = chat2.position_x, y = chat2.position_y},
- name = "chat2",
- scale = {x=500, y=50},
- number = 0xCCCCCC,
- alignment = {x=1, y=0},
- offset = {x=0, y= -i * chat2.line_distance}
- })
- if not chat2.firsthud[name] then
- chat2.firsthud[name] = hud_id
- end
- end
- chat2.users[name] = 1
- chat2.send_message(player, 'chat2 activated! Use /chat2 command to switch it off/on. Use /chat2 * to see all chat here.', 0xDDAA55)
- chat2.lastmessagetimes[name] = minetest.get_gametime()
- end, player)
- end)
- minetest.register_on_leaveplayer(function(player)
- local name = player:get_player_name()
- chat2.lastmessagetimes[name] = nil
- chat2.users[name] = nil
- chat2.firsthud[name] = nil
- end)
- minetest.register_on_chat_message(function(name, message)
- local fmt = nil
- local color = nil
- local submes = nil
- local player = minetest.get_player_by_name(name)
- local players = minetest.get_connected_players()
- if chat2.speedlimit[name]==nil then
- chat2.speedlimit[name] = true
- else
- return
- end
- submes = string.match(message, "^/(.+)")
- if submes then
- return
- end
- submes = string.match(message, "^!(.+)")
- if submes then
- fmt = "<%s> %s"
- color = 0xFF0000
- minetest.log("action", "chat2 !:"..string.format(fmt, name, submes))
- end
- local senderpos = player:get_pos()
- for i = 1, #players do
- local fmt_p = fmt
- local color_p = color
- local submes_p = submes
- local name_p = players[i]:get_player_name()
- --if not submes_p and chat2.users[name_p] and string.find(message, name_p, 1, true) ~= nil then
- if not submes_p and chat2.users[name_p] and string.find( string.lower(message), string.lower(name_p), 1, true) ~= nil then
- fmt_p = "<%s> %s"
- color_p = 0x00FF00
- submes_p = message
- end
- if not submes_p and chat2.users[name_p] and chat2.additionalfilters[name_p] then
- local additionalfound = false
- for n = 1, #chat2.additionalfilters[name_p] do
- --if additionalfound or name == chat2.additionalfilters[name_p][n] or string.find(message, chat2.additionalfilters[name_p][n], 1, true) ~= nil then
- if additionalfound or name == chat2.additionalfilters[name_p][n] or string.find( string.lower(message), string.lower(chat2.additionalfilters[name_p][n]), 1, true) ~= nil then
- additionalfound = true
- end
- end
- if additionalfound then
- fmt_p = "<%s> %s"
- color_p = 0x55FF55
- submes_p = message
- end
- end
- if not submes_p and chat2.users[name_p] and name_p ~= name then
- recieverpos = players[i]:get_pos()
- if vector.distance(senderpos, recieverpos) < 12 then
- fmt_p = "<%s> %s"
- color_p = 0x88FFFF
- submes_p = message
- end
- end
- if not submes_p and chat2.users[name_p] == 2 then
- fmt_p = "<%s> %s"
- color_p = 0xFFFFFF
- submes_p = message
- end
- if submes_p and chat2.users[name_p] then
- chat2.send_message(players[i], string.format(fmt_p, name, submes_p), color_p)
- end
- end
- return
- end)
- if minetest.chatcommands["msg"] then
- local old_command = minetest.chatcommands["msg"].func
- minetest.chatcommands["msg"].func = function(name, param)
- local sendto, message = param:match("^(%S+)%s(.+)$")
- -- Check if old /msg was succeful
- local result, msg = old_command(name, param)
- if sendto and message and chat2.users[sendto] then
- local player = minetest.get_player_by_name(sendto)
- local sender = minetest.get_player_by_name(name)
- if result and player and sender then
- chat2.send_message(player, string.format("<%s> %s", name, message), 0xFF00FF)
- chat2.send_message(sender, string.format("<%s> %s", name, message), 0xF000F0)
- minetest.log("action", "chat2 msg:"..string.format("<%s> %s", name, message))
- end
- end
- return result, msg
- end
- end
- minetest.register_chatcommand("chat2", {
- params = "",
- description = "Turn chat2 off/on or add words to monitor or use /chat2 * to see all chat here",
- privs = {shout = true},
- func = function(name, param)
- local player = minetest.get_player_by_name(name)
- if not player then
- return false, "chat2: Player not found."
- end
- if chat2.users[name] == nil and param and #param > 0 then
- minetest.chat_send_player(name, 'First, please turn chat2 on.')
- return
- end
- if param == "*" then
- if chat2.users[name] == 1 then
- chat2.users[name] = 2
- minetest.chat_send_player(name, 'chat2 - receiving all')
- minetest.log("action", "chat2: receiving all "..name)
- else
- chat2.users[name] = 1
- minetest.chat_send_player(name, 'chat2 - receiving only special messages')
- minetest.log("action", "chat2: receiving only special messages "..name)
- end
- return
- end
- --user add additional search strings
- if param and #param > 0 then
- local parameters = {}
- if chat2.additionalfilters[name] and #chat2.additionalfilters[name] > 0 and #chat2.additionalfilters[name] < 14 then
- parameters = chat2.additionalfilters[name]
- end
- for s in string.gmatch(param, "%g+") do
- parameters[#parameters+1] = s:sub(0, 20)
- end
- if #parameters > 0 and #parameters < 15 then
- chat2.additionalfilters[name] = parameters
- minetest.chat_send_player(name, 'chat2 parameters set')
- else
- chat2.additionalfilters[name] = nil
- minetest.chat_send_player(name, 'chat2 parameters removed(too mutch)')
- end
- return
- end
- if chat2.users[name] ~= nil then
- for i = 1, chat2.messages_on_screen do
- chat2.send_message(player, '', 0x000000)
- end
- chat2.lastmessagetimes[name] = nil
- chat2.users[name] = nil
- else
- minetest.chat_send_player(name, 'chat2 activated! Use /chat2 command if you want to switch it off.')
- chat2.send_message(player, 'chat2 activated!', 0xDDAA55)
- chat2.lastmessagetimes[name] = minetest.get_gametime()
- chat2.users[name] = 1
- end
- end,
- })
- -- every 3 seconds clean speedlimit
- local timer = 0
- minetest.register_globalstep(function(dtime)
- timer = timer + dtime;
- if timer >= 3 then
- chat2.speedlimit = {}
- timer = 0
- --clean chat
- local players = minetest.get_connected_players()
- for i = 1, #players do
- local name = players[i]:get_player_name()
- if
- chat2.lastmessagetimes[name] and
- (minetest.get_gametime() - chat2.lastmessagetimes[name]) > 90
- then
- chat2.send_message(players[i], '', 0x000000)
- if (minetest.get_gametime() - chat2.lastmessagetimes[name]) > (90 + chat2.messages_on_screen * 3) then
- chat2.lastmessagetimes[name] = nil
- end
- end
- end
- end
- end)
|