Don't like ads? PRO users don't see any ads ;-)
Guest

knorke mute test

By: a guest on Apr 11th, 2012  |  syntax: Lua  |  size: 18.24 KB  |  hits: 33  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. function widget:GetInfo()
  2.         return {
  3.         name      = "Red Console (knorke mute test)", --version 4
  4.         desc      = "Requires Red UI Framework",
  5.         author    = "Regret",
  6.         date      = "August 13, 2009", --last change September 10,2009
  7.         license   = "GNU GPL, v2 or later",
  8.         layer     = 0,
  9.         enabled   = true, --enabled by default
  10.         handler   = true, --can use widgetHandler:x()
  11.         }
  12. end
  13. local NeededFrameworkVersion = 8
  14. local CanvasX,CanvasY = 1272,734 --resolution in which the widget was made (for 1:1 size)
  15. --1272,734 == 1280,768 windowed
  16.  
  17. --todo: dont cut words apart when clipping text
  18.  
  19. local Config = {
  20.         console = {
  21.                 px = 300,py = 34+5, --default start position
  22.                 sx = 605, --background size
  23.                
  24.                 fontsize = 12,
  25.                
  26.                 minlines = 1, --minimal number of lines to display
  27.                 maxlines = 10,
  28.                
  29.                 maxage = 15, --max time for a message to be displayed, in seconds
  30.                
  31.                 margin = 5, --distance from background border
  32.                
  33.                 fadetime = 0.25, --fade effect time, in seconds
  34.                 fadedistance = 100, --distance from cursor at which console shows up when empty
  35.                
  36.                 filterduplicates = true, --group identical lines, f.e. ( 5x Nickname: blahblah)
  37.                
  38.                 --note: transparency for text not supported yet
  39.                 cothertext = {1,1,1,1}, --normal chat color
  40.                 callytext = {0,1,0,1}, --ally chat
  41.                 cspectext = {1,1,0,1}, --spectator chat
  42.                
  43.                 cotherallytext = {1,0.5,0.5,1}, --enemy ally messages (seen only when spectating)
  44.                 cmisctext = {0.78,0.78,0.78,1}, --everything else
  45.                 cgametext = {0.4,1,1,1}, --server (autohost) chat
  46.                
  47.                 cbackground = {0,0,0,0.1},
  48.                 cborder = {0,0,0,0.5},
  49.                
  50.                 dragbutton = {2}, --middle mouse button
  51.                 tooltip = {
  52.                         background ="Hold \255\255\255\1middle mouse button\255\255\255\255 to drag the console around.\n\n"..
  53.                         "Press \255\255\255\1CTRL\255\255\255\255 while mouse is above the console to activate chatlog viewing.\n"..
  54.                         "Use mousewheel (+hold \255\255\255\1SHIFT\255\255\255\255 for speedup) to scroll through the chatlog.",
  55.                 },
  56.         },
  57. }
  58.  
  59. local clock = os.clock
  60. local slen = string.len
  61. local ssub = string.sub
  62. local sfind = string.find
  63. local sformat = string.format
  64. local schar = string.char
  65. local sgsub = string.gsub
  66. local mfloor = math.floor
  67. local sbyte = string.byte
  68. local mmax = math.max
  69. local glGetTextWidth = gl.GetTextWidth
  70. local sGetPlayerRoster = Spring.GetPlayerRoster
  71. local sGetTeamColor = Spring.GetTeamColor
  72. local sGetMyAllyTeamID = Spring.GetMyAllyTeamID
  73. local sGetModKeyState = Spring.GetModKeyState
  74.  
  75. local function IncludeRedUIFrameworkFunctions()
  76.         New = WG.Red.New(widget)
  77.         Copy = WG.Red.Copytable
  78.         SetTooltip = WG.Red.SetTooltip
  79.         GetSetTooltip = WG.Red.GetSetTooltip
  80.         Screen = WG.Red.Screen
  81.         GetWidgetObjects = WG.Red.GetWidgetObjects
  82. end
  83.  
  84. local function RedUIchecks()
  85.         local color = "\255\255\255\1"
  86.         local passed = true
  87.         if (type(WG.Red)~="table") then
  88.                 Spring.Echo(color..widget:GetInfo().name.." requires Red UI Framework.")
  89.                 passed = false
  90.         elseif (type(WG.Red.Screen)~="table") then
  91.                 Spring.Echo(color..widget:GetInfo().name..">> strange error.")
  92.                 passed = false
  93.         elseif (WG.Red.Version < NeededFrameworkVersion) then
  94.                 Spring.Echo(color..widget:GetInfo().name..">> update your Red UI Framework.")
  95.                 passed = false
  96.         end
  97.         if (not passed) then
  98.                 widgetHandler:ToggleWidget(widget:GetInfo().name)
  99.                 return false
  100.         end
  101.         IncludeRedUIFrameworkFunctions()
  102.         return true
  103. end
  104.  
  105. local function AutoResizeObjects() --autoresize v2
  106.         if (LastAutoResizeX==nil) then
  107.                 LastAutoResizeX = CanvasX
  108.                 LastAutoResizeY = CanvasY
  109.         end
  110.         local lx,ly = LastAutoResizeX,LastAutoResizeY
  111.         local vsx,vsy = Screen.vsx,Screen.vsy
  112.         if ((lx ~= vsx) or (ly ~= vsy)) then
  113.                 local objects = GetWidgetObjects(widget)
  114.                 local scale = vsy/ly
  115.                 local skippedobjects = {}
  116.                 for i=1,#objects do
  117.                         local o = objects[i]
  118.                         local adjust = 0
  119.                         if ((o.movableslaves) and (#o.movableslaves > 0)) then
  120.                                 adjust = (o.px*scale+o.sx*scale)-vsx
  121.                                 if (((o.px+o.sx)-lx) == 0) then
  122.                                         o._moveduetoresize = true
  123.                                 end
  124.                         end
  125.                         if (o.px) then o.px = o.px * scale end
  126.                         if (o.py) then o.py = o.py * scale end
  127.                         if (o.sx) then o.sx = o.sx * scale end
  128.                         if (o.sy) then o.sy = o.sy * scale end
  129.                         if (o.fontsize) then o.fontsize = o.fontsize * scale end
  130.                         if (adjust > 0) then
  131.                                 o._moveduetoresize = true
  132.                                 o.px = o.px - adjust
  133.                                 for j=1,#o.movableslaves do
  134.                                         local s = o.movableslaves[j]
  135.                                         s.px = s.px - adjust/scale
  136.                                 end
  137.                         elseif ((adjust < 0) and o._moveduetoresize) then
  138.                                 o._moveduetoresize = nil
  139.                                 o.px = o.px - adjust
  140.                                 for j=1,#o.movableslaves do
  141.                                         local s = o.movableslaves[j]
  142.                                         s.px = s.px - adjust/scale
  143.                                 end
  144.                         end
  145.                 end
  146.                 LastAutoResizeX,LastAutoResizeY = vsx,vsy
  147.         end
  148. end
  149.  
  150. local function createconsole(r)
  151.         local vars = {}
  152.        
  153.         local lines = {"text",
  154.                 px=r.px+r.margin,py=r.py+r.margin,
  155.                 fontsize=r.fontsize,
  156.                 caption="",
  157.                 options="o", --black outline
  158.         }
  159.        
  160.         local activationarea = {"area",
  161.                 px=r.px-r.fadedistance,py=r.py-r.fadedistance,
  162.                 sx=r.sx+r.fadedistance*2,sy=0,
  163.                
  164.                 mousewheel=function(up,mx,my,self)
  165.                         if (vars.browsinghistory) then
  166.                                 local alt,ctrl,meta,shift = Spring.GetModKeyState()
  167.                                 local step = 1
  168.                                 if (shift) then
  169.                                         step = 5
  170.                                 end
  171.                                 if (vars.historyoffset == nil) then
  172.                                         vars.historyoffset = 0
  173.                                 end
  174.                                 if (up) then
  175.                                         vars.historyoffset = vars.historyoffset + step
  176.                                         vars._forceupdate = true
  177.                                 else
  178.                                         vars.historyoffset = vars.historyoffset - step
  179.                                         vars._forceupdate = true
  180.                                 end
  181.                                 if (vars.historyoffset > (#vars.consolehistory - r.maxlines)) then
  182.                                         vars.historyoffset = #vars.consolehistory - r.maxlines
  183.                                 elseif (vars.historyoffset < 0) then
  184.                                         vars.historyoffset = 0
  185.                                 end
  186.                         end
  187.                 end,
  188.         }
  189.  
  190.         local background = {"rectangle",
  191.                 px=r.px,py=r.py,
  192.                 sx=r.sx,sy=r.maxlines*r.fontsize+r.margin*2,
  193.                 color=r.cbackground,
  194.                 border=r.cborder,
  195.                 movable=r.dragbutton,
  196.                
  197.                 obeyscreenedge = true,
  198.                 overrideclick = {2},
  199.                
  200.                 movableslaves={lines,activationarea},
  201.                
  202.                 effects = {
  203.                         fadein_at_activation = r.fadetime,
  204.                         fadeout_at_deactivation = r.fadetime,
  205.                 },
  206.         }
  207.        
  208.         activationarea.onupdate=function(self)
  209.                 local fadedistance = (self.sx-background.sx)/2
  210.                 self.sy = background.sy+fadedistance*2
  211.                 self.px = background.px-fadedistance
  212.                 self.py = background.py-fadedistance
  213.                
  214.                 if (not self._mousenotover) then
  215.                         background.active = nil --activate
  216.                         if (vars._empty) then
  217.                                 background.sy = r.minlines*lines.fontsize + (lines.px-background.px)*2
  218.                         end
  219.                         local alt,ctrl,meta,shift = Spring.GetModKeyState()
  220.                         if (ctrl and not vars.browsinghistory) then
  221.                                 if (vars._skipagecheck == nil) then
  222.                                         vars._forceupdate = true
  223.                                         vars.nextupdate = -1
  224.                                         vars.browsinghistory = true
  225.                                         vars.historyoffset = 0
  226.                                        
  227.                                         self.overridewheel = true
  228.                                 end
  229.                                 vars._skipagecheck = true
  230.                                 vars._usecounters = false
  231.                         end
  232.                 else
  233.                         if (vars._skipagecheck ~= nil) then
  234.                                 vars._forceupdate = true
  235.                                 vars.browsinghistory = nil
  236.                                 vars.historyoffset = 0
  237.                                
  238.                                 self.overridewheel = nil
  239.                                 vars._skipagecheck = nil
  240.                                 vars._usecounters = nil
  241.                         end
  242.                 end
  243.                
  244.                 self._mousenotover = nil
  245.         end
  246.         activationarea.mousenotover=function(mx,my,self)
  247.                 self._mousenotover = true
  248.                 if (vars._empty) then
  249.                         background.active = false
  250.                 end
  251.         end
  252.        
  253.         New(activationarea)
  254.         New(background)
  255.         New(lines)
  256.        
  257.         local counters = {}
  258.         for i=1,r.maxlines do
  259.                 local b = New(lines)
  260.                 b.onupdate = function(self)
  261.                         self.px = background.px - self.getwidth() - (lines.px-background.px)
  262.                 end
  263.                 b._count = 0
  264.                 b.active = false
  265.                 b.py = b.py+(i-1)*r.fontsize
  266.                 counters[#counters+1] = b
  267.                 table.insert(background.movableslaves,b)
  268.         end
  269.        
  270.         --tooltip
  271.         background.mouseover = function(mx,my,self) SetTooltip(r.tooltip.background) end
  272.        
  273.         background.active = nil
  274.        
  275.         return {
  276.                 ["background"] = background,
  277.                 ["lines"] = lines,
  278.                 ["counters"] = counters,
  279.                 ["vars"] = vars
  280.         }
  281. end
  282.  
  283. local function clipLine(line,fontsize,maxwidth)
  284.         local clipped = {}
  285.                
  286.         local firstclip = line:len()
  287.         local firstpass = true
  288.         while (1) do
  289.                 local linelen = slen(line)
  290.                 local i=1
  291.                 while (1) do
  292.                         if (glGetTextWidth(ssub(line,1,i+1))*fontsize > maxwidth) then
  293.                                 if (firstpass) then
  294.                                         firstclip = i
  295.                                         firstpass = nil
  296.                                 end
  297.                                 local test = line
  298.                                 clipped[#clipped+1] = ssub(test,1,i)
  299.                                 line = ssub(line,i+1)
  300.                                 break
  301.                         end
  302.                         i=i+1
  303.                         if (i > linelen) then
  304.                                 break
  305.                         end
  306.                 end
  307.                
  308.                 local width = glGetTextWidth(line)*fontsize
  309.                 if (width <= maxwidth) then
  310.                         break
  311.                 end
  312.         end
  313.         clipped[#clipped+1] = line
  314.         return clipped,firstclip
  315. end
  316.  
  317. local function clipHistory(g,oneline)
  318.         local history = g.vars.consolehistory
  319.         local maxsize = g.background.sx - (g.lines.px-g.background.px)
  320.         local fontsize = g.lines.fontsize
  321.        
  322.         if (oneline) then
  323.                 local line = history[#history]
  324.                 local lines,firstclip = clipLine(line[1],fontsize,maxsize)     
  325.                 line[1] = ssub(line[1],1,firstclip)
  326.                 for i=1,#lines do
  327.                         if (i>1) then
  328.                                 history[#history+1] = {line[4]..lines[i],line[2],line[3],line[4],line[5]}
  329.                         end
  330.                 end
  331.         else
  332.                 local clippedhistory = {}
  333.                 for i=1,#history do
  334.                         local line = history[i]
  335.                         local lines,firstclip = clipLine(line[1],fontsize,maxsize)
  336.                         lines[1] = ssub(line[1],1,firstclip)
  337.                         for i=1,#lines do
  338.                                 if (i>1) then
  339.                                         clippedhistory[#clippedhistory+1] = {line[4]..lines[i],line[2],line[3],line[4],line[5]}
  340.                                 else
  341.                                         clippedhistory[#clippedhistory+1] = {lines[i],line[2],line[3],line[4],line[5]}
  342.                                 end
  343.                         end
  344.                 end
  345.                 g.vars.consolehistory = clippedhistory
  346.         end
  347. end
  348.  
  349. local function convertColor(r,g,b)
  350.         return schar(255, (r*255), (g*255), (b*255))
  351. end
  352.  
  353. local function processLine(line,g,cfg,newlinecolor)
  354.         if (g.vars.browsinghistory) then
  355.                 if (g.vars.historyoffset == nil) then
  356.                         g.vars.historyoffset = 0
  357.                 end
  358.                 g.vars.historyoffset = g.vars.historyoffset + 1
  359.         end
  360.        
  361.         g.vars.nextupdate = 0
  362.  
  363.         local roster = sGetPlayerRoster()
  364.         local names = {}
  365.         for i=1,#roster do
  366.                 names[roster[i][1]] = {roster[i][4],roster[i][5],roster[i][3]}
  367.         end
  368.        
  369.         local name = ""
  370.         local text = ""
  371.         local linetype = 0 --other
  372.        
  373.         if (not newlinecolor) then
  374.                 if (names[ssub(line,2,(sfind(line,"> ") or 1)-1)] ~= nil) then
  375.                         linetype = 1 --playermessage
  376.                         name = ssub(line,2,sfind(line,"> ")-1)
  377.                         text = ssub(line,slen(name)+4)
  378.                 elseif (names[ssub(line,2,(sfind(line,"] ") or 1)-1)] ~= nil) then
  379.                         linetype = 2 --spectatormessage
  380.                         name = ssub(line,2,sfind(line,"] ")-1)
  381.                         text = ssub(line,slen(name)+4)
  382.                 elseif (names[ssub(line,2,(sfind(line,"(replay)") or 3)-3)] ~= nil) then
  383.                         linetype = 2 --spectatormessage
  384.                         name = ssub(line,2,sfind(line,"(replay)")-3)
  385.                         text = ssub(line,slen(name)+13)
  386.                 elseif (names[ssub(line,1,(sfind(line," added point: ") or 1)-1)] ~= nil) then
  387.                         linetype = 3 --playerpoint
  388.                         name = ssub(line,1,sfind(line," added point: ")-1)
  389.                         text = ssub(line,slen(name.." added point: ")+1)
  390.                 elseif (ssub(line,1,1) == ">") then
  391.                         linetype = 4 --gamemessage
  392.                         text = ssub(line,3)
  393.                 end            
  394.         end
  395.         --mute--
  396.         local ignoreThisMessage = false
  397.         if (name == "offlinetester") then ignoreThisMessage = true end
  398.         if (mutedPlayers[name]) then
  399.                 ignoreThisMessage = true
  400.                 --Spring.Echo ("blocked message by " .. name)
  401.         end
  402.        
  403.         local MyAllyTeamID = sGetMyAllyTeamID()
  404.         local textcolor = nil
  405.        
  406.         if (linetype==1) then --playermessage
  407.                 local c = cfg.cothertext
  408.                 local misccolor = convertColor(c[1],c[2],c[3])
  409.                 if (sfind(text,"Allies: ") == 1) then
  410.                         text = ssub(text,9)
  411.                         if (names[name][1] == MyAllyTeamID) then
  412.                                 c = cfg.callytext
  413.                         else
  414.                                 c = cfg.cotherallytext
  415.                         end
  416.                 elseif (sfind(text,"Spectators: ") == 1) then
  417.                         text = ssub(text,13)
  418.                         c = cfg.cspectext
  419.                 end
  420.                
  421.                 textcolor = convertColor(c[1],c[2],c[3])
  422.                 local r,g,b,a = sGetTeamColor(names[name][3])
  423.                 local namecolor = convertColor(r,g,b)
  424.                
  425.                 line = namecolor..name..misccolor..": "..textcolor..text
  426.                
  427.         elseif (linetype==2) then --spectatormessage
  428.                 local c = cfg.cothertext
  429.                 local misccolor = convertColor(c[1],c[2],c[3])
  430.                 if (sfind(text,"Allies: ") == 1) then
  431.                         text = ssub(text,9)
  432.                         c = cfg.cspectext
  433.                 elseif (sfind(text,"Spectators: ") == 1) then
  434.                         text = ssub(text,13)
  435.                         c = cfg.cspectext
  436.                 end
  437.                 textcolor = convertColor(c[1],c[2],c[3])
  438.                 c = cfg.cspectext
  439.                 local namecolor = convertColor(c[1],c[2],c[3])
  440.                
  441.                 line = namecolor.."(s) "..name..misccolor..": "..textcolor..text
  442.                
  443.         elseif (linetype==3) then --playerpoint
  444.                 local c = cfg.cspectext
  445.                 local namecolor = convertColor(c[1],c[2],c[3])
  446.                
  447.                 local spectator = 1
  448.                 if (names[name] ~= nil) then
  449.                         spectator = names[name][2]
  450.                 end
  451.                 if (spectator == 0) then
  452.                         local r,g,b,a = sGetTeamColor(names[name][3])
  453.                         namecolor =  convertColor(r,g,b)
  454.                 elseif (spectator == 1) then
  455.                         name = "(s) "..name
  456.                 end
  457.                
  458.                 c = cfg.cotherallytext
  459.                 if (spectator == 1) then
  460.                         c = cfg.cspectext
  461.                 elseif (names[name][1] == MyAllyTeamID) then
  462.                         c = cfg.callytext
  463.                 end
  464.                 textcolor = convertColor(c[1],c[2],c[3])
  465.                 c = cfg.cothertext
  466.                 local misccolor = convertColor(c[1],c[2],c[3])
  467.                
  468.                 line = namecolor..name..misccolor.." * "..textcolor..text
  469.                
  470.         elseif (linetype==4) then --gamemessage
  471.                 local c = cfg.cgametext
  472.                 textcolor = convertColor(c[1],c[2],c[3])
  473.                
  474.                 line = textcolor.."> "..text
  475.         else --every other message
  476.                 local c = cfg.cmisctext
  477.                 textcolor = newlinecolor or convertColor(c[1],c[2],c[3])
  478.                
  479.                 line = textcolor..line
  480.         end
  481.        
  482.         if (g.vars.consolehistory == nil) then
  483.                 g.vars.consolehistory = {}
  484.         end
  485.         local history = g.vars.consolehistory  
  486.        
  487.         if (not ignoreThisMessage) then         --mute--
  488.                 local lineID = #history+1      
  489.                 history[#history+1] = {line,clock(),lineID,textcolor,linetype}
  490.         end
  491.  
  492.         return history[#history]
  493. end
  494.  
  495. local function updateconsole(g,cfg)
  496.         local forceupdate = g.vars._forceupdate
  497.         local justforcedupdate = g.vars._justforcedupdate
  498.        
  499.         if (forceupdate and (not justforcedupdate)) then
  500.                 g.vars._justforcedupdate = true
  501.                 g.vars._forceupdate = nil
  502.         else
  503.                 g.vars._justforcedupdate = nil
  504.                 g.vars._forceupdate = nil
  505.                
  506.                 if (g.vars.nextupdate == nil) then
  507.                         g.vars.nextupdate = 0
  508.                 end
  509.                 if ((g.vars.nextupdate < 0) or (clock() < g.vars.nextupdate)) then
  510.                         return
  511.                 end
  512.         end
  513.        
  514.         local skipagecheck = g.vars._skipagecheck
  515.         local usecounters = g.vars._usecounters
  516.        
  517.         local historyoffset = 0
  518.         if (g.vars.browsinghistory) then
  519.                 if (g.vars.historyoffset == nil) then
  520.                         g.vars.historyoffset = 0
  521.                 end
  522.                 historyoffset = g.vars.historyoffset
  523.         end
  524.        
  525.         if (usecounters == nil) then
  526.                 usecounters = cfg.filterduplicates
  527.         end
  528.  
  529.         local maxlines = cfg.maxlines
  530.        
  531.         local counters = {}
  532.         for i=1,maxlines do
  533.                 counters[i] = 1
  534.                 g.counters[i].active = false
  535.                 g.counters[i].caption = ""
  536.         end
  537.        
  538.         local maxage = cfg.maxage
  539.         local display = ""
  540.         local count = 0
  541.         local i=0
  542.         local lastID = 0
  543.         local lastLine = ""
  544.        
  545.         local history = g.vars.consolehistory or {}
  546.  
  547.         while (count < maxlines) do
  548.                 if (history[#history-i-historyoffset]) then
  549.                         local line = history[#history-i-historyoffset]
  550.                         if (skipagecheck or ((clock()-line[2]) <= maxage)) then
  551.                                 if (count == 0) then
  552.                                         count = count + 1
  553.                                         display = line[1]
  554.                                 else
  555.                                         if (usecounters and (lastID > 0) and (lastID~=line[3]) and (line[1] == lastLine)) then
  556.                                                 counters[count] = counters[count] + 1
  557.                                         else
  558.                                                 count = count + 1
  559.                                                 display = line[1].."\n"..display
  560.                                         end
  561.                                 end
  562.                                
  563.                                 lastLine = line[1]
  564.                                 lastID = line[3]
  565.                                
  566.                                 if (skipagecheck) then
  567.                                         g.vars.nextupdate = -1
  568.                                 else
  569.                                         g.vars.nextupdate = line[2]+maxage
  570.                                 end
  571.                         else
  572.                                 break
  573.                         end
  574.                         i=i+1
  575.                 else
  576.                         break
  577.                 end
  578.         end
  579.        
  580.         if (usecounters) then
  581.                 for i=1,#counters do
  582.                         if (counters[i] ~= 1) then
  583.                                 local counter = count-i+1
  584.                                 g.counters[counter].active = nil
  585.                                 g.counters[counter].caption = counters[i].."x"
  586.                         end
  587.                 end
  588.         end
  589.        
  590.         if (count == 0) then
  591.                 g.vars.nextupdate = -1 --no update until new console line
  592.                 g.background.active = false
  593.                 g.lines.active = false
  594.                 g.vars._empty = true
  595.                 g.background.sy = cfg.minlines*g.lines.fontsize + (g.lines.px-g.background.px)*2
  596.         else
  597.                 g.background.active = nil --activate
  598.                 g.lines.active = nil --activate
  599.                 g.vars._empty = nil
  600.                 g.background.sy = count*g.lines.fontsize + (g.lines.px-g.background.px)*2
  601.         end
  602.        
  603.         g.lines.caption = display
  604. end
  605.  
  606. function widget:Initialize()
  607.         PassedStartupCheck = RedUIchecks()
  608.         if (not PassedStartupCheck) then return end
  609.        
  610.         console = createconsole(Config.console)
  611.         Spring.SendCommands("console 0")
  612.         AutoResizeObjects()
  613. end
  614.  
  615. function widget:Shutdown()
  616.         Spring.SendCommands("console 1")
  617. end
  618.  
  619. function widget:AddConsoleLine(lines,priority)
  620.         lines = lines:match('^\[f=[0-9]+\] (.*)$') or lines
  621.         local textcolor
  622.         for line in lines:gmatch("[^\n]+") do
  623.                 textcolor = processLine(line, console, Config.console, textcolor)[4]
  624.         end
  625.         clipHistory(console,true)
  626. end
  627.  
  628. function widget:Update()
  629.         updateconsole(console,Config.console)
  630.         AutoResizeObjects()
  631. end
  632.  
  633. --save/load stuff
  634. --currently only position
  635. function widget:GetConfigData() --save config
  636.         if (PassedStartupCheck) then
  637.                 local vsy = Screen.vsy
  638.                 local unscale = CanvasY/vsy --needed due to autoresize, stores unresized variables
  639.                 Config.console.px = console.background.px * unscale
  640.                 Config.console.py = console.background.py * unscale
  641.                 return {Config=Config}
  642.         end
  643. end
  644. function widget:SetConfigData(data) --load config
  645.         if (data.Config ~= nil) then
  646.                 Config.console.px = data.Config.console.px
  647.                 Config.console.py = data.Config.console.py
  648.         end
  649. end
  650.  
  651. --mute--
  652. function widget:TextCommand(s)    
  653.      local token = {}
  654.          local n = 0
  655.          --for w in string.gmatch(s, "%a+") do
  656.          for w in string.gmatch(s, "%S+") do
  657.                 n = n +1
  658.                 token[n] = w           
  659.      end
  660.          
  661.         --for i = 1,n do Spring.Echo (token[i]) end
  662.          
  663.          if (token[1] == "mute") then
  664.                 --Spring.Echo ("geht ums muten")
  665.                  for i = 2,n do
  666.                         mutePlayer (token[i])
  667.                         Spring.Echo ("muted " .. token[i])
  668.                 end
  669.         end
  670.        
  671.         if (token[1] == "unmute") then
  672.                 --Spring.Echo ("geht ums UNmuten")
  673.                  for i = 2,n do
  674.                         unmutePlayer (token[i])
  675.                         Spring.Echo ("unmuted " .. token[i])
  676.                 end
  677.                 if (n==1) then unmuteAll() Spring.Echo ("unmuted everybody") end
  678.         end
  679.        
  680. end
  681.  
  682. --mute
  683. mutedPlayers = {}
  684. function mutePlayer (playername)
  685.         mutedPlayers[playername] = true
  686. end
  687.  
  688. function unmutePlayer (playername)
  689.         mutedPlayers[playername] = nil
  690. end
  691.  
  692. function unmuteAll ()
  693.         mutedPlayers = {}
  694. end