Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function widget:GetInfo()
- return {
- name = "Red Console (knorke mute test)", --version 4
- desc = "Requires Red UI Framework",
- author = "Regret",
- date = "August 13, 2009", --last change September 10,2009
- license = "GNU GPL, v2 or later",
- layer = 0,
- enabled = true, --enabled by default
- handler = true, --can use widgetHandler:x()
- }
- end
- local NeededFrameworkVersion = 8
- local CanvasX,CanvasY = 1272,734 --resolution in which the widget was made (for 1:1 size)
- --1272,734 == 1280,768 windowed
- --todo: dont cut words apart when clipping text
- local Config = {
- console = {
- px = 300,py = 34+5, --default start position
- sx = 605, --background size
- fontsize = 12,
- minlines = 1, --minimal number of lines to display
- maxlines = 10,
- maxage = 15, --max time for a message to be displayed, in seconds
- margin = 5, --distance from background border
- fadetime = 0.25, --fade effect time, in seconds
- fadedistance = 100, --distance from cursor at which console shows up when empty
- filterduplicates = true, --group identical lines, f.e. ( 5x Nickname: blahblah)
- --note: transparency for text not supported yet
- cothertext = {1,1,1,1}, --normal chat color
- callytext = {0,1,0,1}, --ally chat
- cspectext = {1,1,0,1}, --spectator chat
- cotherallytext = {1,0.5,0.5,1}, --enemy ally messages (seen only when spectating)
- cmisctext = {0.78,0.78,0.78,1}, --everything else
- cgametext = {0.4,1,1,1}, --server (autohost) chat
- cbackground = {0,0,0,0.1},
- cborder = {0,0,0,0.5},
- dragbutton = {2}, --middle mouse button
- tooltip = {
- background ="Hold \255\255\255\1middle mouse button\255\255\255\255 to drag the console around.\n\n"..
- "Press \255\255\255\1CTRL\255\255\255\255 while mouse is above the console to activate chatlog viewing.\n"..
- "Use mousewheel (+hold \255\255\255\1SHIFT\255\255\255\255 for speedup) to scroll through the chatlog.",
- },
- },
- }
- local clock = os.clock
- local slen = string.len
- local ssub = string.sub
- local sfind = string.find
- local sformat = string.format
- local schar = string.char
- local sgsub = string.gsub
- local mfloor = math.floor
- local sbyte = string.byte
- local mmax = math.max
- local glGetTextWidth = gl.GetTextWidth
- local sGetPlayerRoster = Spring.GetPlayerRoster
- local sGetTeamColor = Spring.GetTeamColor
- local sGetMyAllyTeamID = Spring.GetMyAllyTeamID
- local sGetModKeyState = Spring.GetModKeyState
- local function IncludeRedUIFrameworkFunctions()
- New = WG.Red.New(widget)
- Copy = WG.Red.Copytable
- SetTooltip = WG.Red.SetTooltip
- GetSetTooltip = WG.Red.GetSetTooltip
- Screen = WG.Red.Screen
- GetWidgetObjects = WG.Red.GetWidgetObjects
- end
- local function RedUIchecks()
- local color = "\255\255\255\1"
- local passed = true
- if (type(WG.Red)~="table") then
- Spring.Echo(color..widget:GetInfo().name.." requires Red UI Framework.")
- passed = false
- elseif (type(WG.Red.Screen)~="table") then
- Spring.Echo(color..widget:GetInfo().name..">> strange error.")
- passed = false
- elseif (WG.Red.Version < NeededFrameworkVersion) then
- Spring.Echo(color..widget:GetInfo().name..">> update your Red UI Framework.")
- passed = false
- end
- if (not passed) then
- widgetHandler:ToggleWidget(widget:GetInfo().name)
- return false
- end
- IncludeRedUIFrameworkFunctions()
- return true
- end
- local function AutoResizeObjects() --autoresize v2
- if (LastAutoResizeX==nil) then
- LastAutoResizeX = CanvasX
- LastAutoResizeY = CanvasY
- end
- local lx,ly = LastAutoResizeX,LastAutoResizeY
- local vsx,vsy = Screen.vsx,Screen.vsy
- if ((lx ~= vsx) or (ly ~= vsy)) then
- local objects = GetWidgetObjects(widget)
- local scale = vsy/ly
- local skippedobjects = {}
- for i=1,#objects do
- local o = objects[i]
- local adjust = 0
- if ((o.movableslaves) and (#o.movableslaves > 0)) then
- adjust = (o.px*scale+o.sx*scale)-vsx
- if (((o.px+o.sx)-lx) == 0) then
- o._moveduetoresize = true
- end
- end
- if (o.px) then o.px = o.px * scale end
- if (o.py) then o.py = o.py * scale end
- if (o.sx) then o.sx = o.sx * scale end
- if (o.sy) then o.sy = o.sy * scale end
- if (o.fontsize) then o.fontsize = o.fontsize * scale end
- if (adjust > 0) then
- o._moveduetoresize = true
- o.px = o.px - adjust
- for j=1,#o.movableslaves do
- local s = o.movableslaves[j]
- s.px = s.px - adjust/scale
- end
- elseif ((adjust < 0) and o._moveduetoresize) then
- o._moveduetoresize = nil
- o.px = o.px - adjust
- for j=1,#o.movableslaves do
- local s = o.movableslaves[j]
- s.px = s.px - adjust/scale
- end
- end
- end
- LastAutoResizeX,LastAutoResizeY = vsx,vsy
- end
- end
- local function createconsole(r)
- local vars = {}
- local lines = {"text",
- px=r.px+r.margin,py=r.py+r.margin,
- fontsize=r.fontsize,
- caption="",
- options="o", --black outline
- }
- local activationarea = {"area",
- px=r.px-r.fadedistance,py=r.py-r.fadedistance,
- sx=r.sx+r.fadedistance*2,sy=0,
- mousewheel=function(up,mx,my,self)
- if (vars.browsinghistory) then
- local alt,ctrl,meta,shift = Spring.GetModKeyState()
- local step = 1
- if (shift) then
- step = 5
- end
- if (vars.historyoffset == nil) then
- vars.historyoffset = 0
- end
- if (up) then
- vars.historyoffset = vars.historyoffset + step
- vars._forceupdate = true
- else
- vars.historyoffset = vars.historyoffset - step
- vars._forceupdate = true
- end
- if (vars.historyoffset > (#vars.consolehistory - r.maxlines)) then
- vars.historyoffset = #vars.consolehistory - r.maxlines
- elseif (vars.historyoffset < 0) then
- vars.historyoffset = 0
- end
- end
- end,
- }
- local background = {"rectangle",
- px=r.px,py=r.py,
- sx=r.sx,sy=r.maxlines*r.fontsize+r.margin*2,
- color=r.cbackground,
- border=r.cborder,
- movable=r.dragbutton,
- obeyscreenedge = true,
- overrideclick = {2},
- movableslaves={lines,activationarea},
- effects = {
- fadein_at_activation = r.fadetime,
- fadeout_at_deactivation = r.fadetime,
- },
- }
- activationarea.onupdate=function(self)
- local fadedistance = (self.sx-background.sx)/2
- self.sy = background.sy+fadedistance*2
- self.px = background.px-fadedistance
- self.py = background.py-fadedistance
- if (not self._mousenotover) then
- background.active = nil --activate
- if (vars._empty) then
- background.sy = r.minlines*lines.fontsize + (lines.px-background.px)*2
- end
- local alt,ctrl,meta,shift = Spring.GetModKeyState()
- if (ctrl and not vars.browsinghistory) then
- if (vars._skipagecheck == nil) then
- vars._forceupdate = true
- vars.nextupdate = -1
- vars.browsinghistory = true
- vars.historyoffset = 0
- self.overridewheel = true
- end
- vars._skipagecheck = true
- vars._usecounters = false
- end
- else
- if (vars._skipagecheck ~= nil) then
- vars._forceupdate = true
- vars.browsinghistory = nil
- vars.historyoffset = 0
- self.overridewheel = nil
- vars._skipagecheck = nil
- vars._usecounters = nil
- end
- end
- self._mousenotover = nil
- end
- activationarea.mousenotover=function(mx,my,self)
- self._mousenotover = true
- if (vars._empty) then
- background.active = false
- end
- end
- New(activationarea)
- New(background)
- New(lines)
- local counters = {}
- for i=1,r.maxlines do
- local b = New(lines)
- b.onupdate = function(self)
- self.px = background.px - self.getwidth() - (lines.px-background.px)
- end
- b._count = 0
- b.active = false
- b.py = b.py+(i-1)*r.fontsize
- counters[#counters+1] = b
- table.insert(background.movableslaves,b)
- end
- --tooltip
- background.mouseover = function(mx,my,self) SetTooltip(r.tooltip.background) end
- background.active = nil
- return {
- ["background"] = background,
- ["lines"] = lines,
- ["counters"] = counters,
- ["vars"] = vars
- }
- end
- local function clipLine(line,fontsize,maxwidth)
- local clipped = {}
- local firstclip = line:len()
- local firstpass = true
- while (1) do
- local linelen = slen(line)
- local i=1
- while (1) do
- if (glGetTextWidth(ssub(line,1,i+1))*fontsize > maxwidth) then
- if (firstpass) then
- firstclip = i
- firstpass = nil
- end
- local test = line
- clipped[#clipped+1] = ssub(test,1,i)
- line = ssub(line,i+1)
- break
- end
- i=i+1
- if (i > linelen) then
- break
- end
- end
- local width = glGetTextWidth(line)*fontsize
- if (width <= maxwidth) then
- break
- end
- end
- clipped[#clipped+1] = line
- return clipped,firstclip
- end
- local function clipHistory(g,oneline)
- local history = g.vars.consolehistory
- local maxsize = g.background.sx - (g.lines.px-g.background.px)
- local fontsize = g.lines.fontsize
- if (oneline) then
- local line = history[#history]
- local lines,firstclip = clipLine(line[1],fontsize,maxsize)
- line[1] = ssub(line[1],1,firstclip)
- for i=1,#lines do
- if (i>1) then
- history[#history+1] = {line[4]..lines[i],line[2],line[3],line[4],line[5]}
- end
- end
- else
- local clippedhistory = {}
- for i=1,#history do
- local line = history[i]
- local lines,firstclip = clipLine(line[1],fontsize,maxsize)
- lines[1] = ssub(line[1],1,firstclip)
- for i=1,#lines do
- if (i>1) then
- clippedhistory[#clippedhistory+1] = {line[4]..lines[i],line[2],line[3],line[4],line[5]}
- else
- clippedhistory[#clippedhistory+1] = {lines[i],line[2],line[3],line[4],line[5]}
- end
- end
- end
- g.vars.consolehistory = clippedhistory
- end
- end
- local function convertColor(r,g,b)
- return schar(255, (r*255), (g*255), (b*255))
- end
- local function processLine(line,g,cfg,newlinecolor)
- if (g.vars.browsinghistory) then
- if (g.vars.historyoffset == nil) then
- g.vars.historyoffset = 0
- end
- g.vars.historyoffset = g.vars.historyoffset + 1
- end
- g.vars.nextupdate = 0
- local roster = sGetPlayerRoster()
- local names = {}
- for i=1,#roster do
- names[roster[i][1]] = {roster[i][4],roster[i][5],roster[i][3]}
- end
- local name = ""
- local text = ""
- local linetype = 0 --other
- if (not newlinecolor) then
- if (names[ssub(line,2,(sfind(line,"> ") or 1)-1)] ~= nil) then
- linetype = 1 --playermessage
- name = ssub(line,2,sfind(line,"> ")-1)
- text = ssub(line,slen(name)+4)
- elseif (names[ssub(line,2,(sfind(line,"] ") or 1)-1)] ~= nil) then
- linetype = 2 --spectatormessage
- name = ssub(line,2,sfind(line,"] ")-1)
- text = ssub(line,slen(name)+4)
- elseif (names[ssub(line,2,(sfind(line,"(replay)") or 3)-3)] ~= nil) then
- linetype = 2 --spectatormessage
- name = ssub(line,2,sfind(line,"(replay)")-3)
- text = ssub(line,slen(name)+13)
- elseif (names[ssub(line,1,(sfind(line," added point: ") or 1)-1)] ~= nil) then
- linetype = 3 --playerpoint
- name = ssub(line,1,sfind(line," added point: ")-1)
- text = ssub(line,slen(name.." added point: ")+1)
- elseif (ssub(line,1,1) == ">") then
- linetype = 4 --gamemessage
- text = ssub(line,3)
- end
- end
- --mute--
- local ignoreThisMessage = false
- if (name == "offlinetester") then ignoreThisMessage = true end
- if (mutedPlayers[name]) then
- ignoreThisMessage = true
- --Spring.Echo ("blocked message by " .. name)
- end
- local MyAllyTeamID = sGetMyAllyTeamID()
- local textcolor = nil
- if (linetype==1) then --playermessage
- local c = cfg.cothertext
- local misccolor = convertColor(c[1],c[2],c[3])
- if (sfind(text,"Allies: ") == 1) then
- text = ssub(text,9)
- if (names[name][1] == MyAllyTeamID) then
- c = cfg.callytext
- else
- c = cfg.cotherallytext
- end
- elseif (sfind(text,"Spectators: ") == 1) then
- text = ssub(text,13)
- c = cfg.cspectext
- end
- textcolor = convertColor(c[1],c[2],c[3])
- local r,g,b,a = sGetTeamColor(names[name][3])
- local namecolor = convertColor(r,g,b)
- line = namecolor..name..misccolor..": "..textcolor..text
- elseif (linetype==2) then --spectatormessage
- local c = cfg.cothertext
- local misccolor = convertColor(c[1],c[2],c[3])
- if (sfind(text,"Allies: ") == 1) then
- text = ssub(text,9)
- c = cfg.cspectext
- elseif (sfind(text,"Spectators: ") == 1) then
- text = ssub(text,13)
- c = cfg.cspectext
- end
- textcolor = convertColor(c[1],c[2],c[3])
- c = cfg.cspectext
- local namecolor = convertColor(c[1],c[2],c[3])
- line = namecolor.."(s) "..name..misccolor..": "..textcolor..text
- elseif (linetype==3) then --playerpoint
- local c = cfg.cspectext
- local namecolor = convertColor(c[1],c[2],c[3])
- local spectator = 1
- if (names[name] ~= nil) then
- spectator = names[name][2]
- end
- if (spectator == 0) then
- local r,g,b,a = sGetTeamColor(names[name][3])
- namecolor = convertColor(r,g,b)
- elseif (spectator == 1) then
- name = "(s) "..name
- end
- c = cfg.cotherallytext
- if (spectator == 1) then
- c = cfg.cspectext
- elseif (names[name][1] == MyAllyTeamID) then
- c = cfg.callytext
- end
- textcolor = convertColor(c[1],c[2],c[3])
- c = cfg.cothertext
- local misccolor = convertColor(c[1],c[2],c[3])
- line = namecolor..name..misccolor.." * "..textcolor..text
- elseif (linetype==4) then --gamemessage
- local c = cfg.cgametext
- textcolor = convertColor(c[1],c[2],c[3])
- line = textcolor.."> "..text
- else --every other message
- local c = cfg.cmisctext
- textcolor = newlinecolor or convertColor(c[1],c[2],c[3])
- line = textcolor..line
- end
- if (g.vars.consolehistory == nil) then
- g.vars.consolehistory = {}
- end
- local history = g.vars.consolehistory
- if (not ignoreThisMessage) then --mute--
- local lineID = #history+1
- history[#history+1] = {line,clock(),lineID,textcolor,linetype}
- end
- return history[#history]
- end
- local function updateconsole(g,cfg)
- local forceupdate = g.vars._forceupdate
- local justforcedupdate = g.vars._justforcedupdate
- if (forceupdate and (not justforcedupdate)) then
- g.vars._justforcedupdate = true
- g.vars._forceupdate = nil
- else
- g.vars._justforcedupdate = nil
- g.vars._forceupdate = nil
- if (g.vars.nextupdate == nil) then
- g.vars.nextupdate = 0
- end
- if ((g.vars.nextupdate < 0) or (clock() < g.vars.nextupdate)) then
- return
- end
- end
- local skipagecheck = g.vars._skipagecheck
- local usecounters = g.vars._usecounters
- local historyoffset = 0
- if (g.vars.browsinghistory) then
- if (g.vars.historyoffset == nil) then
- g.vars.historyoffset = 0
- end
- historyoffset = g.vars.historyoffset
- end
- if (usecounters == nil) then
- usecounters = cfg.filterduplicates
- end
- local maxlines = cfg.maxlines
- local counters = {}
- for i=1,maxlines do
- counters[i] = 1
- g.counters[i].active = false
- g.counters[i].caption = ""
- end
- local maxage = cfg.maxage
- local display = ""
- local count = 0
- local i=0
- local lastID = 0
- local lastLine = ""
- local history = g.vars.consolehistory or {}
- while (count < maxlines) do
- if (history[#history-i-historyoffset]) then
- local line = history[#history-i-historyoffset]
- if (skipagecheck or ((clock()-line[2]) <= maxage)) then
- if (count == 0) then
- count = count + 1
- display = line[1]
- else
- if (usecounters and (lastID > 0) and (lastID~=line[3]) and (line[1] == lastLine)) then
- counters[count] = counters[count] + 1
- else
- count = count + 1
- display = line[1].."\n"..display
- end
- end
- lastLine = line[1]
- lastID = line[3]
- if (skipagecheck) then
- g.vars.nextupdate = -1
- else
- g.vars.nextupdate = line[2]+maxage
- end
- else
- break
- end
- i=i+1
- else
- break
- end
- end
- if (usecounters) then
- for i=1,#counters do
- if (counters[i] ~= 1) then
- local counter = count-i+1
- g.counters[counter].active = nil
- g.counters[counter].caption = counters[i].."x"
- end
- end
- end
- if (count == 0) then
- g.vars.nextupdate = -1 --no update until new console line
- g.background.active = false
- g.lines.active = false
- g.vars._empty = true
- g.background.sy = cfg.minlines*g.lines.fontsize + (g.lines.px-g.background.px)*2
- else
- g.background.active = nil --activate
- g.lines.active = nil --activate
- g.vars._empty = nil
- g.background.sy = count*g.lines.fontsize + (g.lines.px-g.background.px)*2
- end
- g.lines.caption = display
- end
- function widget:Initialize()
- PassedStartupCheck = RedUIchecks()
- if (not PassedStartupCheck) then return end
- console = createconsole(Config.console)
- Spring.SendCommands("console 0")
- AutoResizeObjects()
- end
- function widget:Shutdown()
- Spring.SendCommands("console 1")
- end
- function widget:AddConsoleLine(lines,priority)
- lines = lines:match('^\[f=[0-9]+\] (.*)$') or lines
- local textcolor
- for line in lines:gmatch("[^\n]+") do
- textcolor = processLine(line, console, Config.console, textcolor)[4]
- end
- clipHistory(console,true)
- end
- function widget:Update()
- updateconsole(console,Config.console)
- AutoResizeObjects()
- end
- --save/load stuff
- --currently only position
- function widget:GetConfigData() --save config
- if (PassedStartupCheck) then
- local vsy = Screen.vsy
- local unscale = CanvasY/vsy --needed due to autoresize, stores unresized variables
- Config.console.px = console.background.px * unscale
- Config.console.py = console.background.py * unscale
- return {Config=Config}
- end
- end
- function widget:SetConfigData(data) --load config
- if (data.Config ~= nil) then
- Config.console.px = data.Config.console.px
- Config.console.py = data.Config.console.py
- end
- end
- --mute--
- function widget:TextCommand(s)
- local token = {}
- local n = 0
- --for w in string.gmatch(s, "%a+") do
- for w in string.gmatch(s, "%S+") do
- n = n +1
- token[n] = w
- end
- --for i = 1,n do Spring.Echo (token[i]) end
- if (token[1] == "mute") then
- --Spring.Echo ("geht ums muten")
- for i = 2,n do
- mutePlayer (token[i])
- Spring.Echo ("muted " .. token[i])
- end
- end
- if (token[1] == "unmute") then
- --Spring.Echo ("geht ums UNmuten")
- for i = 2,n do
- unmutePlayer (token[i])
- Spring.Echo ("unmuted " .. token[i])
- end
- if (n==1) then unmuteAll() Spring.Echo ("unmuted everybody") end
- end
- end
- --mute
- mutedPlayers = {}
- function mutePlayer (playername)
- mutedPlayers[playername] = true
- end
- function unmutePlayer (playername)
- mutedPlayers[playername] = nil
- end
- function unmuteAll ()
- mutedPlayers = {}
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement