Advertisement
Doyousketch2

friend_chat for Minetest

Mar 22nd, 2018
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.71 KB | None | 0 0
  1.  
  2. print('[friend_chat]  CSM loading...')
  3. --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4.  
  5. local joinColor    = {'#00DD00', '#008800'}  -- friend, normal  (Green)
  6. local exitColor    = {'#DD0000', '#880000'}  --   "   ,   "     (Red)
  7. local timeoutColor = {'#880000', '#660000'}  --   "   ,   "     (Dark Red)
  8.  
  9. local adminColor  = {'#FFFF00', '#BBBB00'}  -- chat, /me   (Yellow)
  10. local modColor    = {'#0055DD', '#003388'}  --  "  ,  "    (Blue)
  11. local myColor     = {'#00DDDD', '#008888'}  --  "  ,  "    (Diamond Blue)
  12. local friendColor = {'#3399FF', '#0055FF'}  --  "  ,  "    (Light Blue)
  13. local enemyColor  = {'#FF0066', '#800033'}  --  "  ,  "    (Magenta)
  14. local otherColor  = {'#6600CC', '#400080'}  --  "  ,  "    (Purple)
  15.  
  16. local serverColor  = {'#EE9900', '#CC3300'}  -- playernames, server messages  (Orange)
  17. local elseColor    = {'#DDDDDD', '#000000'}  -- normal text, ignore           (White)
  18.  
  19. local tier  = ''
  20. local colortext
  21. local shown  = false
  22. local player_names = {}
  23. local player1name = ''
  24. local selected_player  = ''
  25.  
  26. --=========================================================
  27. --  Note to self:     use  :set_string()  &  :get_string()  because
  28. --  the command names for  :from_table()  &  :to_table()  appear to be reversed...
  29.  
  30. local mod_storage  = minetest .get_mod_storage()
  31.  
  32. --  uncomment the next line to completely clear [friend_chat] mod_storage, if need be.
  33. --mod_storage :from_table()
  34.  
  35. --  uncomment next line to print out the contents of [friend_chat] mod_storage.
  36. --print( dump( mod_storage :to_table() ))
  37.  
  38. --=========================================================
  39. -- Note to self:  don't use spaces in formspec,
  40. -- or else you'll need to pad corresponding commands w/ spaces as well...
  41.  
  42. local function show_main_dialog()
  43.   local compare  = function( a,b ) return string.lower(a) < string.lower(b) end
  44.     table .sort( player_names,  compare )
  45.  
  46.     local size  = 'size[5,7.1]'
  47.     if selected_player ~= '' and selected_player ~= player1name then
  48.  
  49.     xpcall(  function() tier  = mod_storage :get_string( selected_player ) end,
  50.              function() tier  = '' end  )
  51.  
  52.     if tier == 'admin' then
  53.       colortext  = minetest .colorize( adminColor[1],  tier )
  54.     elseif tier == 'mod' then
  55.       colortext  = minetest .colorize( modColor[1],  tier )
  56.     elseif tier == 'friend' then
  57.       colortext  = minetest .colorize( friendColor[1],  tier )
  58.     elseif tier == 'enemy' then
  59.       colortext  = minetest .colorize( enemyColor[1],  tier )
  60.     elseif tier == 'ignore' then
  61.       colortext  = minetest .colorize( enemyColor[2], tier )
  62.     elseif tier == 'other' then
  63.       colortext  = minetest .colorize( otherColor[2], tier )
  64.     else
  65.       colortext  = tier
  66.     end  -- if...elseif tier
  67.  
  68.         size  = 'size[6.5,7.1]'
  69.         ..'label[5.1,5.85;' ..colortext ..']'
  70.     end -- increase formspec size and print tier if selected_player isn't you
  71.  
  72.     local formspec  = size
  73.         ..'bgcolor[#080808BB;true]'
  74.         ..'background[5,5;1,1;gui_formbg.png;true]'
  75.         ..'button_exit[0,6.9;1.5,0.2;close;Close]'
  76.  
  77.     if #player_names < 2 then
  78.       formspec  = formspec
  79.           ..'label[0.1,0;Single Player]'
  80.       else  -- .is_singleplayer()
  81.       formspec  = formspec
  82.           ..'label[0.1,0;' ..#player_names ..'  Players]'
  83.     end  -- #player_names
  84.  
  85.     formspec  = formspec
  86.         ..'tableoptions[background=#314D4F]'
  87.         ..'tablecolumns[color;text,align=center,width=10]'
  88.         ..'table[0,0.6;4.8,6;player_list;'
  89.  
  90.     local formspec_table  = {}
  91.  
  92.     for index, playername in ipairs(player_names) do
  93.  
  94.     xpcall(  function() tier  = mod_storage :get_string( playername ) end,
  95.              function() tier  = '' end  )
  96.  
  97.         if playername == player1name then
  98.             formspec_table[index]  = myColor[2] ..',' ..playername
  99.  
  100.         elseif tier == 'admin' then
  101.             formspec_table[index]  = adminColor[2] ..',' ..playername
  102.  
  103.         elseif tier == 'mod' then
  104.             formspec_table[index]  = modColor[2] ..',' ..playername
  105.  
  106.         elseif tier == 'friend' then
  107.             formspec_table[index]  = friendColor[2] ..',' ..playername
  108.  
  109.         elseif tier == 'enemy' then
  110.             formspec_table[index]  = enemyColor[2] ..',' ..playername
  111.  
  112.         elseif tier == 'ignore' then
  113.             formspec_table[index]  = elseColor[2] ..',' ..playername
  114.  
  115.         elseif tier == 'other' then
  116.             formspec_table[index]  = otherColor[2] ..',' ..playername
  117.  
  118.         else
  119.             formspec_table[index]  = elseColor[1] ..',' ..playername
  120.         end
  121.     end
  122.  
  123.     formspec  = formspec ..table .concat( formspec_table, ',' ) ..';]'
  124.  
  125.     if selected_player ~= '' and selected_player ~= player1name then
  126.       formspec  = formspec
  127.         ..'button[5.05,0.6;1.5,0.25;admin;Admin]'
  128.           ..'button[5.05,1.5;1.5,0.25;mod;Mod]'
  129.         ..'button[5.05,2.4;1.5,0.25;friend;Friend]'
  130.           ..'button[5.05,3.3;1.5,0.25;enemy;Enemy]'
  131.           ..'button[5.05,4.2;1.5,0.25;ignore;Ignore]'
  132.           ..'button[5.05,5.1;1.5,0.25;other;Other]'
  133.           ..'button[4.925,6.9;1.75,0.25;clear;' ..minetest .colorize( exitColor[2], 'CLEAR' ) ..']'
  134.     end
  135.  
  136.     minetest .show_formspec( 'friend_chat:player_list', formspec )
  137. end
  138.  
  139. --=========================================================
  140.  
  141. minetest .register_on_receiving_chat_messages(  function(message)
  142.   local msg  = minetest .strip_colors(message)
  143.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  144.   if msg :sub(1, 1) == '<' then  -- Normal messages
  145.     local playername  = msg :sub(2, msg:find('>') -1 )  -- after '<' up to, not including '>'
  146.  
  147.     xpcall(  function() tier  = mod_storage :get_string( playername ) end,
  148.              function() tier  = '' end  )
  149.  
  150.     if playername == player1name then
  151.       colortext  = minetest .colorize( myColor[1],  msg )
  152.     -- in case someone decides to use '__fake_' prefix in their name
  153.     elseif playername :sub(1, 7) == '__fake_' then
  154.       colortext  = minetest .colorize( enemyColor[2], 'fake message deleted' )
  155.       print( '[friend_chat]  fake message deleted: ' ..msg )
  156.     elseif tier == 'admin' then
  157.       colortext  = minetest .colorize( adminColor[1],  msg )
  158.     elseif tier == 'mod' then
  159.       colortext  = minetest .colorize( modColor[1],  msg )
  160.     elseif tier == 'friend' then
  161.       colortext  = minetest .colorize( friendColor[1],  msg )
  162.     elseif tier == 'enemy' then
  163.       colortext  = minetest .colorize( enemyColor[1],  msg )
  164.     elseif tier == 'ignore' then
  165.       colortext  = minetest .colorize( enemyColor[2], 'message deleted' )
  166.       print( '[friend_chat]  deleted: ' ..msg )
  167.     elseif tier == 'other' then
  168.       colortext  = minetest .colorize( otherColor[1],  msg )
  169.     elseif msg == '<invalid mulibyte string>' then
  170.       colortext  = minetest .colorize( exitColor[2],  msg )
  171.     else
  172.       colortext  = message
  173.     end  -- .playername
  174.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  175.   elseif msg :sub(1, 4) == '*** ' then  -- join/leave messages
  176.     local playername  = msg :sub(  5,  msg:find( ' ', 5 ) -1  )  -- after '*** ' up to not including ' '
  177.  
  178.     xpcall(  function() tier  = mod_storage :get_string( playername ) end,
  179.              function() tier  = '' end  )
  180.  
  181.     if msg :sub(-16, -1) == 'joined the game.' then  -- join
  182.  
  183.       if playername ~= player1name then
  184.         local found  = false  -- find out if name is already in list
  185.         for i = 1, #player_names do
  186.           if player_names[i] == playername then
  187.             found  = true
  188.             break
  189.           end  -- if == playername
  190.         end  -- iterate through player_names
  191.  
  192.         if not found then  -- if not, add name to list
  193.           table.insert( player_names, playername )
  194.           print( '[friend_chat]  added: ' ..playername )
  195.           if shown then  -- if formspec is currently showing,
  196.             show_main_dialog()  -- refresh it with new playername.
  197.           end  -- shown
  198.         end  -- not found
  199.       end  -- not player1name
  200.  
  201.       if tier == 'admin' or tier == 'mod' or tier == 'friend' then
  202.         colortext  = minetest .colorize( joinColor[1],  msg )
  203.       else
  204.         colortext  = minetest .colorize( joinColor[2],  msg )
  205.       end
  206.  
  207.     elseif msg :sub(-14, -1) == 'left the game.' then  -- leave
  208.       if tier == 'admin' or tier == 'mod' or tier == 'friend' then
  209.         colortext  = minetest .colorize( exitColor[1],  msg )
  210.       else
  211.         colortext  = minetest .colorize( exitColor[2],  msg )
  212.       end
  213.  
  214.     else                                           -- timed out
  215.       if tier == 'admin' or tier == 'mod' or tier == 'friend' then
  216.         colortext  = minetest .colorize( timeoutColor[1],  msg )
  217.       else
  218.         colortext  = minetest .colorize( timeoutColor[2],  msg )
  219.       end
  220.     end  -- .playername
  221.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  222.   elseif msg :sub(1, 2) == '* ' then  -- /me messages
  223.     local playername  = msg :sub(3, msg:find(' ') -1 )
  224.  
  225.     xpcall(  function() tier  = mod_storage :get_string( playername ) end,
  226.              function() tier  = '' end  )
  227.  
  228.     if playername == player1name then
  229.       colortext  = minetest .colorize( myColor[2],  msg )
  230.     elseif tier == 'admin' then
  231.       colortext  = minetest .colorize( adminColor[2],  msg )
  232.     elseif tier == 'mod' then
  233.       colortext  = minetest .colorize( modColor[2],  msg )
  234.     elseif tier == 'friend' then
  235.       colortext  = minetest .colorize( friendColor[2],  msg )
  236.     elseif tier == 'enemy' then
  237.       colortext  = minetest .colorize( enemyColor[2],  msg )
  238.     elseif tier == 'ignore' then
  239.       colortext  = minetest .colorize( enemyColor[2], 'action deleted' )
  240.       print( '[friend_chat]  action deleted: ' ..msg )
  241.     elseif tier == 'other' then
  242.       colortext  = minetest .colorize( otherColor[2],  msg )
  243.     else
  244.       colortext  = message
  245.     end  -- .playername
  246.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  247.   elseif msg :sub(1, 1) == '[' then  -- server messages
  248.     colortext  = minetest .colorize( serverColor[2],  msg )
  249.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  250.   elseif msg :sub(1, 3) == '-!-' then  -- error messages
  251.     colortext  = minetest .colorize( serverColor[1],  msg )
  252.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  253.   elseif msg :sub(1, 2) == '# ' then  -- announce messages
  254.  
  255.     if msg:find('clients={') then
  256.       local alpha, beta  = msg:find( 'clients={' )  -- beta = where '{' is.
  257.  
  258.       local pre  = msg :sub( 1, beta )  -- block of text, up to, and including 'clients={'
  259.       local online  = msg :sub(  beta +1,  msg:find('}') -1  )
  260.       local post  = msg :sub(  msg:find('}'),  -1  )  -- text after '}'
  261.       --~~~~~~~~~~~~~~~~~~~~~
  262.       -- if name isn't in player_list
  263.       for name in string.gmatch( online, '%S+' ) do  -- select word, up to space
  264.         if name:find(',') then  -- if trailing comma
  265.           name = name:sub(  1,  name:find(',') -1  )  -- strip it
  266.         end  -- comma
  267.  
  268.         local found  = false
  269.         for i = 1, #player_names do
  270.           if player_names[i] == name then
  271.             found  = true
  272.             break
  273.           end  -- if == name
  274.         end  -- iterate through player_names
  275.  
  276.         if not found then  -- add it to list
  277.           table.insert( player_names, name )
  278.         end  -- not found
  279.       end -- name in ( online )
  280.       --~~~~~~~~~~~~~~~~~~~~~
  281.       -- pretty-print players
  282.       local M1 = minetest .colorize( serverColor[2],  pre )
  283.       local M2 = minetest .colorize( serverColor[1],  online )
  284.       local M3 = minetest .colorize( serverColor[2],  post )
  285.       colortext  = M1..M2..M3
  286.     else
  287.       colortext  = minetest .colorize( serverColor[2],  msg )
  288.     end  -- if online
  289.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  290.   elseif msg :sub(1, 3) == 'PM ' then  -- private messages
  291.     colortext  = message  -- don't change the color
  292.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  293.   else
  294.     local playername  = msg :sub( 1,  msg:find(' ')  )
  295.  
  296.     xpcall(  function() tier  = mod_storage :get_string( playername ) end,
  297.              function() tier  = '' end  )
  298.  
  299.     if msg :sub( 1, 7 ) == 'Player ' or msg :sub( 1, 5 ) == 'Jail 'then
  300.       colortext  = minetest .colorize( exitColor[1],  msg )
  301.     elseif tier == 'admin' then
  302.       colortext  = minetest .colorize( adminColor[2],  msg )
  303.     elseif tier == 'mod' then
  304.       colortext  = minetest .colorize( modColor[2],  msg )
  305.     elseif tier == 'friend' then
  306.       colortext  = minetest .colorize( friendColor[2],  msg )
  307.     elseif tier == 'enemy' then
  308.       colortext  = minetest .colorize( enemyColor[2],  msg )
  309.     elseif tier == 'ignore' then
  310.       colortext  = minetest .colorize( enemyColor[2], 'occurrence deleted' )
  311.       print( '[friend_chat]  deleted: ' ..msg )
  312.     elseif tier == 'other' then
  313.       colortext  = minetest .colorize( otherColor[2],  msg )    
  314.     elseif playername :find(player1name) then
  315.       colortext  = minetest .colorize( myColor[2],  msg )
  316.     else
  317.       colortext  = minetest .colorize( serverColor[2],  msg )
  318.     end  -- playername
  319.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  320.   -- possibly put in block of code here to color IRC chat.
  321.   -- will need to see a few examples first.
  322.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  323.   end  -- if...elseif msg :sub()
  324.   --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  325.   minetest .display_chat_message(colortext)
  326.   return true
  327. end  -- function(message)
  328. )  -- register_on_receiving_chat_messages
  329.  
  330. --=========================================================
  331.  
  332. minetest .register_on_formspec_input(  function(formname, fields)
  333.   if formname ~= 'friend_chat:player_list' then return false
  334.  
  335.   elseif fields .quit then
  336.       selected_player  = ''
  337.       shown  = false
  338.       return true
  339.  
  340.   elseif fields .player_list then
  341.       local selected  = fields .player_list
  342.       if selected :sub(1,3) == 'CHG' then  -- example: CHG:1:2
  343.         -- get # from first ':'  @ pos 5.  Up to, but not including second ':'
  344.           local index  = selected :sub( 5,  selected :find(':', 5) -1 )
  345.           selected_player  = player_names[ tonumber(index) ]
  346.           show_main_dialog()
  347.       end  -- 'CHG'
  348.       return true
  349.  
  350.   elseif fields .admin then
  351.     print( '[friend_chat]  clicked admin on ' ..selected_player )
  352.     mod_storage :set_string( selected_player, 'admin' )
  353.       show_main_dialog()
  354.       return true
  355.  
  356.   elseif fields .mod then
  357.     print( '[friend_chat]  clicked mod on ' ..selected_player )
  358.     mod_storage :set_string( selected_player, 'mod' )
  359.       show_main_dialog()
  360.       return true
  361.  
  362.   elseif fields .friend then
  363.     print( '[friend_chat]  clicked friend on ' ..selected_player )
  364.     mod_storage :set_string( selected_player, 'friend' )
  365.       show_main_dialog()
  366.       return true
  367.  
  368.   elseif fields .enemy then
  369.     print( '[friend_chat]  clicked enemy on ' ..selected_player )
  370.     mod_storage :set_string( selected_player, 'enemy' )
  371.       show_main_dialog()
  372.       return true
  373.  
  374.   elseif fields .ignore then
  375.     print( '[friend_chat]  clicked ignore on ' ..selected_player )
  376.     mod_storage :set_string( selected_player, 'ignore' )
  377.       show_main_dialog()
  378.       return true
  379.  
  380.   elseif fields .other then
  381.     print( '[friend_chat]  clicked other on ' ..selected_player )
  382.     mod_storage :set_string( selected_player, 'other' )
  383.       show_main_dialog()
  384.       return true
  385.  
  386.     elseif fields .clear then
  387.     print( '[friend_chat]  clicked clear on ' ..selected_player )
  388.     mod_storage :set_string( selected_player, '' )
  389.       show_main_dialog()
  390.       return true
  391.   end  -- .other
  392.  
  393. end  -- function(formname, fields)
  394. )  -- register_on_formspec_input()
  395.  
  396. --=========================================================
  397. --  Note:  I would rather this block of code be at the beginning, right after variable declaration,
  398. --  however, it uses  show_main_dialog()  to refresh formspec,
  399. --  in case the player happens to type in  .l  before initialized,
  400. --  so that has to be defined first.
  401.  
  402. minetest .register_on_connect(  function()
  403.   -- delay a moment for Minetest to initialize player, and have a chance to count player_names
  404.   minetest .after( 2,  function()
  405.     player1name  = minetest .localplayer :get_name()
  406.  
  407.     local found  = false
  408.     for i = 1, #player_names do
  409.       if player_names[i] == player1name then
  410.         found  = true
  411.         break
  412.       end  -- if == player1name
  413.     end  -- iterate through player_names
  414.  
  415.     if not found then  -- add it to list
  416.       table.insert( player_names, player1name )
  417.     end  -- not found
  418.  
  419.     -- minetest.is_singleplayer()  seems to crash Minetest.  thanks LaCosa
  420.     if #player_names < 2 then
  421.       table.insert( player_names, '__fake_admin' )
  422.       mod_storage :set_string( '__fake_admin', 'admin' )
  423.  
  424.       table.insert( player_names, '__fake_moderator' )
  425.       mod_storage :set_string( '__fake_moderator', 'mod' )
  426.  
  427.       table.insert( player_names, '__fake_friend' )
  428.       mod_storage :set_string( '__fake_friend', 'friend' )
  429.  
  430.       table.insert( player_names, '__fake_name' )
  431.  
  432.       table.insert( player_names, '__fake_enemy' )
  433.       mod_storage :set_string( '__fake_enemy', 'enemy' )
  434.      
  435.       table.insert( player_names, '__fake_ignore' )
  436.       mod_storage :set_string( '__fake_ignore', 'ignore' )
  437.  
  438.       table.insert( player_names, '__fake_other' )
  439.       mod_storage :set_string( '__fake_other', 'other' )
  440.     end
  441.  
  442.     local M1  = minetest .colorize( '#BBBBBB', 'friend_chat loaded, type ' )
  443.     local M2  = minetest .colorize( '#FFFFFF', '.l ' )
  444.     local M3  = minetest .colorize( '#BBBBBB', 'or ' )
  445.     local M4  = minetest .colorize( '#FFFFFF', '.list ' )
  446.     local M5  = minetest .colorize( '#BBBBBB', "to list players you've seen." )
  447.     minetest .display_chat_message( M1..M2..M3..M4..M5 )
  448.  
  449.     if shown then
  450.       show_main_dialog()  -- refresh
  451.     end
  452.   end  -- function()
  453.   )  -- .after(1)
  454.  
  455. end  -- function()
  456. )  -- .register_on_connect()
  457.  
  458. --=========================================================
  459.  
  460. minetest .register_chatcommand( 'l',
  461.   {
  462.       func  = function(param)
  463.         shown  = true
  464.           show_main_dialog()
  465.       end,
  466.   }
  467. )
  468.  
  469. minetest .register_chatcommand( 'list',
  470.   {
  471.       func  = function(param)
  472.         shown  = true
  473.           show_main_dialog()
  474.       end,
  475.   }
  476. )
  477.  
  478. --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement