Advertisement
mikeyy

chat.lua extensions v1

Jun 13th, 2011
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.59 KB | None | 0 0
  1. --/lua/ui/game/chat.lua hook
  2. --Chat extensions by Mithy
  3. -- * Persistent, preferences-saved ignore list with shortcuts
  4. -- * Overhauled slash command system with several new commands added and easy extensibility
  5. -- * Improved text display for non-chat messages, including wrapping, window size adjustment, etc
  6. --Type '/?' in the chat window for a list of available commands
  7.  
  8.  
  9. local Prefs = import('/lua/ui/prefs.lua')
  10.  
  11.  
  12. --New function for better handling of non-chat message display
  13. --Wraps text, shows history, and adjusts width like ReceiveChat
  14. function DisplayMessage(msg, wrap)
  15.     local textBoxWidth = bg.history.Right() - bg.history.Left()
  16.     local wrappedText = {msg}
  17.     if wrap then
  18.         wrappedText = import('/lua/maui/text.lua').WrapText(msg, textBoxWidth, function(text) return bg.history:GetStringAdvance(text) end)
  19.     end
  20.     for i, textLine in wrappedText do
  21.         bg.history:AddItem(textLine)
  22.     end
  23.     bg.history:ScrollToBottom()
  24.     local numItems = bg.history:GetItemCount()
  25.     local longest = 0
  26.     for i = numItems - 10, numItems do
  27.         if i < 0 or i >= numItems then
  28.             continue
  29.         end
  30.         local textLine = bg.history:GetItem(i)
  31.         local length = import('/lua/maui/text.lua').GetTextWidth(textLine, function(text) return bg.history:GetStringAdvance(text) end)
  32.         if length > longest then
  33.             longest = length
  34.         end
  35.     end
  36.     bg.historyBackMid.Width:Set(longest - 76)
  37.     if bg:IsHidden() then
  38.         ShowHistory()
  39.     end
  40. end
  41.  
  42. --Forked by CreateChat to handle delayed ignore list auto-population
  43. function AutoIgnore()
  44.     WaitSeconds(5)
  45.     --Auto-ignore from preferences
  46.     local ignoreList = IgnoreList:Get()
  47.     for name, val in ignoredPlayers do
  48.         if ignoreList[name] and not val then
  49.             HandleIgnore(name)
  50.         end
  51.     end
  52. end
  53.  
  54.  
  55. local prevCreateChat = CreateChat
  56. function CreateChat()
  57.     prevCreateChat()
  58.     --Override OnEnterPressed to:
  59.     -- allow proper handling of commands without parameters
  60.     -- improve command function table and allow for help text (see ChatCommands table)
  61.     -- show the chat window after performing a command
  62.     -- add commands to the up/down arrow history
  63.     bg.edit.OnEnterPressed = function(self, text)
  64.         if text ~= "" then
  65.             if string.sub(text, 1, 1) == '/' then
  66.                 local a, b, comKey, param = string.find(text, '^/([^%s]+)%s*(.*)$')
  67.                 if comKey and ChatCommands:GetCommand(comKey) then
  68.                     ChatCommands:Execute(comKey, param)
  69.                 else
  70.                     DisplayMessage(LOCF("<LOC chatui_0008>Unknown command: %s", comKey or '?'), true)
  71.                 end
  72.                 table.insert(commandhistory, { text = text })
  73.                 ToggleChat()
  74.                 ShowHistory()
  75.             else
  76.                 msg = { to = chatTo, text = text }
  77.                 if chatTo == 'allies' then
  78.                     SessionSendChatMessage(FindClients(), msg)
  79.                 else
  80.                     SessionSendChatMessage(msg)
  81.                 end
  82.                 table.insert(commandhistory, msg)
  83.                 ToggleChat()
  84.             end
  85.         else
  86.             ToggleChat()
  87.         end
  88.     end
  89.     --Set chat font size from profile
  90.     local fontsize = tonumber(Prefs.GetFromCurrentProfile('chat_font_size'))
  91.     if fontsize and fontsize >= 10 and fontsize <= 24 then
  92.         bg.history:SetFont(UIUtil.bodyFont, fontsize)
  93.     end
  94.     --Set chat inactivity timeout from profile
  95.     local timeout = tonumber(Prefs.GetFromCurrentProfile('chat_inactivity_timeout'))
  96.     if timeout and timeout >= 2 and timeout <= 30 then
  97.         CHAT_INACTIVITY_TIMEOUT = timeout
  98.     end
  99.  
  100.     ForkThread(AutoIgnore)
  101. end
  102.  
  103.  
  104. --Ignore list handling
  105. IgnoreList = {
  106.     Get = function(self)
  107.         return GetPreference('IgnoreList') or {}
  108.     end,
  109.  
  110.     Save = function(self, list)
  111.         SetPreference('IgnoreList', table.copy(list))
  112.         SavePreferences()
  113.     end,
  114.  
  115.     Add = function(self, name)
  116.         local list = self:Get()
  117.         if not list[name] then
  118.             list[name] = true
  119.             self:Save(list)
  120.         end
  121.     end,
  122.  
  123.     Remove = function(self, name)
  124.         local list = self:Get()
  125.         if list[name] then
  126.             list[name] = nil
  127.             self:Save(list)
  128.         end
  129.     end,
  130. }
  131.  
  132.  
  133. --[[ New slash command handling with alias and help text support.
  134.  
  135. To add a new function as a command, use something like the following syntax:
  136.     ChatCommands:AddCommand('name', data)
  137.  
  138. ..where name is the primary command alias, and data is a table containing at least an Action function, e.g.:
  139.     local data = {
  140.         Action = ExampleFunction,
  141.         Aliases = {
  142.             'alias1',
  143.             'alias2',
  144.         },
  145.         HelpText = 'Description of the command',
  146.     }
  147.  
  148. HelpText can be set to false if for whatever reason you don't want the command to show up in the help display at all.
  149.  
  150. Any names in Aliases (optional) can also be used to trigger the command in the chat box, and will be listed in the help display.
  151. Action is a defined function to which a single string parameter (all of the text following the command, minus any leading spaces)
  152. will be passed.  The function does not need to accept use the parameter, and the system now fully supports slash commands without
  153. any following text (this would break the old system).  See the various uses of the system below for examples.
  154.  
  155. Additional aliases for existing commands can be added using the AddAlias and AddAliases methods, e.g.:
  156.     ChatCommands:AddAlias('mycommand', 'myalias')
  157.     -or-
  158.     ChatCommands:AddAliases('mycommand', {'alias1', 'alias2'})
  159.  
  160.  
  161. If you want your mod to work without being dependent on this one, simply do a check for ChatCommands before proceeding.  You can
  162. still support the old system as well, by inserting subtables into specialCommands (which will have no effect with this mod running),
  163. keeping in mind the limitations of the GPG implementation.--]]
  164. ChatCommands = {
  165.     Commands = {},
  166.     HelpText = {},
  167.  
  168.     GetCommand = function(self, name)
  169.         return self.Commands[name]
  170.     end,
  171.  
  172.     Execute = function(self, name, param)
  173.         local command = self:GetCommand(name)
  174.         if command and command.Action then
  175.             command.Action(param)
  176.         end
  177.     end,
  178.  
  179.     AddCommand = function(self, name, data)
  180.         if name and data and type(data) == 'table' and data.Action and type(data.Action) == 'function' then
  181.             if not self.Commands[name] then
  182.                 self.Commands[name] = {
  183.                     Action = data.Action,
  184.                     Name = name,
  185.                 }
  186.                 self:AddAliases(name, data.Aliases or {})
  187.                 self.HelpText[name] = data.HelpText or 'no description'
  188.             end
  189.         else
  190.             WARN("ChatCommands: AddCommand: Incomplete data table for command '"..repr(name).."'; data table must contain at least an Action function")
  191.         end
  192.     end,
  193.  
  194.     AddAlias = function(self, name, alias)
  195.         local cmd = self.Commands[name]
  196.         if cmd then
  197.             if not self.Commands[alias] then
  198.                 self.Commands[alias] = cmd
  199.                 if not cmd.Aliases then
  200.                     cmd.Aliases = {}
  201.                 end
  202.                 table.insert(cmd.Aliases, alias)
  203.             else
  204.                 LOG("ChatCommands: AddAlias: Alias '"..repr(alias).."' already refers to command '"..repr(self.Commands[alias].Name).."'")
  205.             end
  206.         else
  207.             WARN("ChatCommands: AddAlias: Command '"..repr(name).."' not found")
  208.         end
  209.     end,
  210.  
  211.     AddAliases = function(self, name, aliases)
  212.         if self.Commands[name] then
  213.             for k, alias in aliases do
  214.                 self:AddAlias(name, alias)
  215.             end
  216.         else
  217.             WARN("ChatCommands: AddAliases: Command '"..repr(name).."' not found")
  218.         end
  219.     end,
  220.  
  221.     ShowHelp = function(self)
  222.         DisplayMessage('Available commands:')
  223.         local cmds = {}
  224.         for name, text in self.HelpText do
  225.             if text then
  226.                 table.insert(cmds, name)
  227.             end
  228.         end
  229.         table.sort(cmds)
  230.         for _, name in cmds do
  231.             DisplayMessage(' /'..name..':  '..self.HelpText[name])
  232.             if self.Commands[name].Aliases then
  233.                 local msg = '     Aliases: '
  234.                 for k, alias in self.Commands[name].Aliases do
  235.                     msg = msg..'   /'..alias
  236.                 end
  237.                 DisplayMessage(msg)
  238.             end
  239.         end
  240.     end,
  241. }
  242. --Chat command help text
  243. ChatCommands:AddCommand('?', {Action=function() ChatCommands:ShowHelp() end,Aliases={'help'},HelpText='Displays command help'})
  244.  
  245. --Chat history clear
  246. ChatCommands:AddCommand('clear', {Action=function() bg.history:DeleteAllItems() end,Aliases={'cls'},HelpText='Clears chat history'})
  247.  
  248.  
  249.  
  250. --List player indexes for ignore shortcuts
  251. function ListPlayers()
  252.     DisplayMessage('Player indexes:')
  253.     for id, army in GetArmiesTable().armiesTable do
  254.         if army.human and ignoredPlayers[string.lower(army.nickname)] ~= nil then
  255.             DisplayMessage(' '..string.format('%2d', id)..': '..army.nickname)
  256.         end
  257.     end
  258. end
  259. ChatCommands:AddCommand('playerlist', {Action=ListPlayers,Aliases={'pl'},HelpText='Lists player indexes for use with /ignore'})
  260.  
  261.  
  262. --New ignore handling to improve message display and save to preferences
  263. --Also now accepts army indexes
  264. function HandleIgnore(param)
  265.     if param != "" then
  266.         local playerName = string.lower(param)
  267.         local index = tonumber(param)
  268.         if index and index <= 10 then
  269.             local army = GetArmiesTable().armiesTable[index]
  270.             if army and army.human then
  271.                 playerName = string.lower(army.nickname)
  272.             end
  273.         end
  274.         if ignoredPlayers[playerName] != nil then
  275.             ignoredPlayers[playerName] = not ignoredPlayers[playerName]
  276.             if ignoredPlayers[playerName] then
  277.                 DisplayMessage(LOCF("<LOC chatui_0005>Ignoring %s", playerName))
  278.                 IgnoreList:Add(playerName)
  279.             else
  280.                 DisplayMessage(LOCF("<LOC chatui_0006>No longer ignoring %s", playerName))
  281.                 IgnoreList:Remove(playerName)
  282.             end
  283.         else
  284.             DisplayMessage(LOCF("<LOC chatui_0007>Player not found: %s", playerName))
  285.         end
  286.     end
  287. end
  288. ChatCommands:AddCommand('ignore', {Action=HandleIgnore,Aliases={'squelch','s','i'},HelpText='Toggles ignore/squelch for the specified player name or index'})
  289.  
  290.  
  291. --Display ignore list
  292. function DisplayIgnore()
  293.     local ignoreList = IgnoreList:Get()
  294.     if not table.empty(ignoreList) then
  295.         DisplayMessage('Ignored player names:')
  296.     else
  297.         DisplayMessage('Ignore list is empty')
  298.         return
  299.     end
  300.     local ingame = {}
  301.     local saved = {}
  302.     for name, val in ignoreList do
  303.         if ignoredPlayers[name] then
  304.             table.insert(ingame, name)
  305.         else
  306.             table.insert(saved, name)
  307.         end
  308.     end
  309.     --in the current game
  310.     if not table.empty(ingame) then
  311.         for k, name in ingame do
  312.             DisplayMessage('[*]'..name)
  313.         end
  314.     end
  315.     --saved names
  316.     if not table.empty(saved) then
  317.         for k, name in saved do
  318.             DisplayMessage('    '..name)
  319.         end
  320.     end
  321.     if bg:IsHidden() then
  322.         ShowHistory()
  323.     end
  324. end
  325. ChatCommands:AddCommand('ignorelist', {Action=DisplayIgnore,Aliases={'squelchlist','sl','il'},HelpText='Shows squelched/ignored player names'})
  326.  
  327. --Change font size
  328. function FontSize(size)
  329.     size = tonumber(size)
  330.     if size and size >= 10 and size <= 24 then
  331.         bg.history:SetFont(UIUtil.bodyFont, size)
  332.         DisplayMessage('New font size '..size..' saved to profile')
  333.         Prefs.SetToCurrentProfile('chat_font_size', size)
  334.     else
  335.         DisplayMessage('Font size must be between 10 and 24 (default 18)')
  336.     end
  337. end
  338. ChatCommands:AddCommand('size', {Action=FontSize,HelpText='Sets chat history font size (10-24 default 18)'})
  339.  
  340. --Change history window timeout
  341. function HideTime(time)
  342.     time = tonumber(time)
  343.     if time and time >= 2 and time <= 30 then
  344.         CHAT_INACTIVITY_TIMEOUT = time
  345.         DisplayMessage('New chat inactivity timeout '..time..' saved to profile')
  346.         Prefs.SetToCurrentProfile('chat_inactivity_timeout', time)
  347.     else
  348.         DisplayMessage('Chat inactivity timeout must be between 2 and 30 (default 5)')
  349.     end
  350. end
  351. ChatCommands:AddCommand('time', {Action=HideTime,HelpText='Sets chat history timeout in seconds (2-30, default 5)'})
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement