· 8 years ago · Jun 30, 2018, 12:02 PM
1--[[---------------------------------------------------------------------------------------------
2Written by: Seragorn
3
4USAGE: Demonnic users should have automatic integration, just map your channels to your
5tabs using the gmcpchat.demonnicmap table defined near the top of the script.
6
7USAGE: Non demonnic users find the gmcpchat.textevent near the end of the script...
8this is the event handler, it has an example cecho which will demo the
9script by replicating all comm channels with an echo (if it cant detect ..
10this is where you echo to your chat window instead of the main window..
11
12Eg currently it has:
13decho(gmcpchat.highlight(gmcpchat.escapefix(gmcp.Comm.Channel.Text.text)).."\n")
14
15If you have a simple chat window where the miniconsol reference is stored in "chat" you could do:
16chat:decho(gmcpchat.highlight(gmcpchat.escapefix(gmcp.Comm.Channel.Text.text)).."\n")
17
18It also has a gmcpchat.getchannelname() function which will utilise the table of communications
19channels stored in GMCP to get from the short name to the long/pretty name for each channel.
20This could be used to automate direction of each event to the appropriate tab for YATCO and
21other tabbed chat setups
22
23There is a gmcpchat.disablenamedb setting near the top, set it to true if you want to stop it
24doing namedb highlights into your chat window, some slow pc's with particularly large namedb's
25will suffer for this highlighting.
26
27-------------------------------------------------------------------------------------------------
28*** Disclaimer: Its probably buggy as hell, I've only been using it a short time.. the GMCP color
29*** codes do some wierd things, so there may be combo's of fg/bg that do not translate correctly.
30*** feel free to let me know if you see anything wrong, I dont promise I will care tho.
31-----------------------------------------------------------------------------------------------]]
32
33
34gmcpchat = gmcpchat or {}
35
36-- SETTINGS THAT CAN BE CHANGED...
37
38gmcpchat.disablenamedb = true
39gmcpchat.ignoredenizens = false
40gmcpchat.gagmainwindow = false
41
42-- This is where you map the gmcp based channel names to your demonnic tabs...
43-- Note: this is for example purposes, if you have tabs that match these names it will work, if not
44-- I will check if the demonic tab exists, if not it will send to the All tab.
45-- Clans are a special case, if you do clt<ID> you can create a tab for a specific clan, if I cant
46-- find a specific clan, I will send all clans to the default tab mabbed to by clt
47gmcpchat.demonnicmap = {
48 party = "Party",
49 tell = "Tells",
50 ct = "City",
51 ht = "House",
52 hts = "House",
53 hnt = "House",
54 ot = "Order",
55 newbie = "Newbie",
56 market = "Market",
57 ldt = "Leaders",
58 clt = "Clans",
59 says = "Says",
60 clt99 = "Specific Clan Name"
61}
62
63
64
65
66
67
68
69-- CHANGE NOTHING BELOW THIS POINT (unless you know what your doing)
70
71gmcpchat.enabled = gmcpchat.enabled or false
72
73color_table = color_table or {}
74color_table.a_cyan = color_table.a_cyan or {0,255,255} -- 0;1;36
75color_table.a_darkred = color_table.a_darkred or {128,0,0} -- 0;38
76color_table.a_darkgreen = color_table.a_darkgreen or {0,179,0}
77color_table.a_brown = color_table.a_brown or {128,128,0}
78color_table.a_darkblue = color_table.a_darkblue or {0,0,128}
79color_table.a_darkmagenta = color_table.a_darkmagenta or {128,0,128}
80color_table.a_darkcyan = color_table.a_darkcyan or {0,128,128} -- 0;36
81color_table.a_darkwhite = color_table.a_darkwhite or {192,192,192}
82color_table.a_darkgrey = color_table.a_darkgrey or {128,128,128}
83color_table.a_red = color_table.a_red or {255,0,0}
84color_table.a_green = color_table.a_green or {0,255,0} -- 0;1;32
85color_table.a_yellow = color_table.a_yellow or {255,255,0}
86color_table.a_magenta = color_table.a_magenta or {255,0,255}
87color_table.a_white = color_table.a_white or {255,255,255}
88
89-- Table we use to map the color codes to cecho strings.
90gmcpchat.lookup = { { 0, 0, 0 }, { 128, 0, 0 }, { 0, 179, 0 }, { 128, 128, 0 }, { 0, 0, 128 },
91 { 128, 0, 128 }, { 0, 128, 128 }, { 192, 192, 192 }, { 128, 128, 128 },
92 { 255, 0, 0 }, { 0, 255, 0 }, { 255, 255, 0 }, { 0, 0, 255 }, { 255, 0, 255 },
93 { 0, 255, 255 }, { 255, 255, 255 }, { 0, 0, 0 }, { 0, 0, 95 }, { 0, 0, 135 },
94 { 0, 0, 175 }, { 0, 0, 215 }, { 0, 0, 255 }, { 0, 95, 0 }, { 0, 95, 95 },
95 { 0, 95, 135 }, { 0, 95, 175 }, { 0, 95, 215 }, { 0, 95, 255 }, { 0, 135, 0 },
96 { 0, 135, 95 }, { 0, 135, 135 }, { 0, 135, 175 }, { 0, 135, 215 }, { 0, 135, 255 },
97 { 0, 175, 0 }, { 0, 175, 95 }, { 0, 175, 135 }, { 0, 175, 175 }, { 0, 175, 215 },
98 { 0, 175, 255 }, { 0, 215, 0 }, { 0, 215, 95 }, { 0, 215, 135 }, { 0, 215, 175 },
99 { 0, 215, 215 }, { 0, 215, 255 }, { 0, 255, 0 }, { 0, 255, 95 }, { 0, 255, 135 },
100 { 0, 255, 175 }, { 0, 255, 215 }, { 0, 255, 255 }, { 95, 0, 0 }, { 95, 0, 95 },
101 { 95, 0, 135 }, { 95, 0, 175 }, { 95, 0, 215 }, { 95, 0, 255 }, { 95, 95, 0 },
102 { 95, 95, 95 }, { 95, 95, 135 }, { 95, 95, 175 }, { 95, 95, 215 }, { 95, 95, 255 },
103 { 95, 135, 0 }, { 95, 135, 95 }, { 95, 135, 135 }, { 95, 135, 175 }, { 95, 135, 215 },
104 { 95, 135, 255 }, { 95, 175, 0 }, { 95, 175, 95 }, { 95, 175, 135 }, { 95, 175, 175 },
105 { 95, 175, 215 }, { 95, 175, 255 }, { 95, 215, 0 }, { 95, 215, 95 }, { 95, 215, 135 },
106 { 95, 215, 175 }, { 95, 215, 215 }, { 95, 215, 255 }, { 95, 255, 0 }, { 95, 255, 95 },
107 { 95, 255, 135 }, { 95, 255, 175 }, { 95, 255, 215 }, { 95, 255, 255 }, { 135, 0, 0 },
108 { 135, 0, 95 }, { 135, 0, 135 }, { 135, 0, 175 }, { 135, 0, 215 }, { 135, 0, 255 },
109 { 135, 95, 0 }, { 135, 95, 95 }, { 135, 95, 135 }, { 135, 95, 175 }, { 135, 95, 215 },
110 { 135, 95, 255 }, { 135, 135, 0 }, { 135, 135, 95 }, { 135, 135, 135 }, { 135, 135, 175 },
111 { 135, 135, 215 }, { 135, 135, 255 }, { 135, 175, 0 }, { 135, 175, 95 }, { 135, 175, 135 },
112 { 135, 175, 175 }, { 135, 175, 215 }, { 135, 175, 255 }, { 135, 215, 0 }, { 135, 215, 95 },
113 { 135, 215, 135 }, { 135, 215, 175 }, { 135, 215, 215 }, { 135, 215, 255 }, { 135, 255, 0 },
114 { 135, 255, 95 }, { 135, 255, 135 }, { 135, 255, 175 }, { 135, 255, 215 }, { 135, 255, 255 },
115 { 175, 0, 0 }, { 175, 0, 95 }, { 175, 0, 135 }, { 175, 0, 175 }, { 175, 0, 215 },
116 { 175, 0, 255 }, { 175, 95, 0 }, { 175, 95, 95 }, { 175, 95, 135 }, { 175, 95, 175 },
117 { 175, 95, 215 }, { 175, 95, 255 }, { 175, 135, 0 }, { 175, 135, 95 }, { 175, 135, 135 },
118 { 175, 135, 175 }, { 175, 135, 215 }, { 175, 135, 255 }, { 175, 175, 0 }, { 175, 175, 95 },
119 { 175, 175, 135 }, { 175, 175, 175 }, { 175, 175, 215 }, { 175, 175, 255 }, { 175, 215, 0 },
120 { 175, 215, 95 }, { 175, 215, 135 }, { 175, 215, 175 }, { 175, 215, 215 }, { 175, 215, 255 },
121 { 175, 255, 0 }, { 175, 255, 95 }, { 175, 255, 135 }, { 175, 255, 175 }, { 175, 255, 215 },
122 { 175, 255, 255 }, { 215, 0, 0 }, { 215, 0, 95 }, { 215, 0, 135 }, { 215, 0, 175 },
123 { 215, 0, 215 }, { 215, 0, 255 }, { 215, 95, 0 }, { 215, 95, 95 }, { 215, 95, 135 },
124 { 215, 95, 175 }, { 215, 95, 215 }, { 215, 95, 255 }, { 215, 135, 0 }, { 215, 135, 95 },
125 { 215, 135, 135 }, { 215, 135, 175 }, { 215, 135, 215 }, { 215, 135, 255 }, { 215, 175, 0 },
126 { 215, 175, 95 }, { 215, 175, 135 }, { 215, 175, 175 }, { 215, 175, 215 }, { 215, 175, 255 },
127 { 215, 215, 0 }, { 215, 215, 95 }, { 215, 215, 135 }, { 215, 215, 175 }, { 215, 215, 215 },
128 { 215, 215, 255 }, { 215, 255, 0 }, { 215, 255, 95 }, { 215, 255, 135 }, { 215, 255, 175 },
129 { 215, 255, 215 }, { 215, 255, 255 }, { 255, 0, 0 }, { 255, 0, 95 }, { 255, 0, 135 },
130 { 255, 0, 175 }, { 255, 0, 215 }, { 255, 0, 255 }, { 255, 95, 0 }, { 255, 95, 95 },
131 { 255, 95, 135 }, { 255, 95, 175 }, { 255, 95, 215 }, { 255, 95, 255 }, { 255, 135, 0 },
132 { 255, 135, 95 }, { 255, 135, 135 }, { 255, 135, 175 }, { 255, 135, 215 }, { 255, 135, 255 },
133 { 255, 175, 0 }, { 255, 175, 95 }, { 255, 175, 135 }, { 255, 175, 175 }, { 255, 175, 215 },
134 { 255, 175, 255 }, { 255, 215, 0 }, { 255, 215, 95 }, { 255, 215, 135 }, { 255, 215, 175 },
135 { 255, 215, 215 }, { 255, 215, 255 }, { 255, 255, 0 }, { 255, 255, 95 }, { 255, 255, 135 },
136 { 255, 255, 175 }, { 255, 255, 215 }, { 255, 255, 255 }, { 0, 0, 0 }, { 18, 18, 18 },
137 { 28, 28, 28 }, { 38, 38, 38 }, { 48, 48, 48 }, { 58, 58, 58 }, { 68, 68, 68 },
138 { 78, 78, 78 }, { 88, 88, 88 }, { 98, 98, 98 }, { 108, 108, 108 }, { 118, 118, 118 },
139 { 128, 128, 128 }, { 138, 138, 138 }, { 148, 148, 148 }, { 158, 158, 158 }, { 168, 168, 168 },
140 { 178, 178, 178 }, { 188, 188, 188 }, { 198, 198, 198 }, { 208, 208, 208 }, { 218, 218, 218 },
141 { 228, 228, 228 }, { 238, 238, 238 } }
142
143
144
145-- function to enable GMCP Communications messages
146gmcpchat.enableCommChannel = function ()
147 sendGMCP([[Core.Supports.Add ["Comm.Channel 1"] ]])
148 gmcpchat.enabled = true
149 if gmcpchat.startTrig then
150 killTrigger(gmcpchat.startTrig)
151 end
152end
153
154-- function to disable GMCP Communications messages
155gmcpchat.disableCommChannel = function ()
156 if not gmcpchat.enabled then return end
157 sendGMCP([[Core.Supports.Remove ["Comm.Channel"] ]])
158 gmcpchat.enabled = false
159end
160
161-- Temporary storage for a channel lookup table (auto populated on first use)
162gmcpchat.clanlookup = gmcpchat.clanlookup or {}
163
164gmcpchat.channels = function ()
165 display(gmcp.Comm.Channel.List)
166end
167
168-- Finds the long name for the given channel
169-- if no short name is passed it finds the long name of the last Communication.
170gmcpchat.getchannelname = function (short)
171 if gmcpchat.clanlookup[(short or gmcp.Comm.Channel.Text.channel)] then
172 -- if its already been indexed... just return it
173 return gmcpchat.clanlookup[(short or gmcp.Comm.Channel.Text.channel)]
174 end
175 -- this can happen at startup, or if we did the lookup but then joined a clan..
176 -- redo the lookup table..
177 gmcpchat.clanlookup={}
178 for _,v in ipairs(gmcp.Comm.Channel.List) do
179 gmcpchat.clanlookup[v.name]=v.caption
180 end
181 return gmcpchat.clanlookup[(short or gmcp.Comm.Channel.Text.channel)]
182end
183
184gmcpchat.getcolor = function (index)
185 return table.concat(gmcpchat.lookup[index+1], ",")
186end
187
188gmcpchat.getcolorfromname = function (colorname)
189 return "<"..table.concat(color_table[colorname] or color_table.black, ",")..">"
190end
191
192-- function which we use to translate ascii color codes from in the message using our lookup table
193gmcpchat.translatecode16 = function (highlight, fgnum, bgnum)
194 if tonumber(highlight) == 0 and tonumber(fgnum) == 1 then -- odd highlight bug that puts a 0 in anyway.. bloody IRE..
195 return string.format("<%s:%s>", gmcpchat.getcolor(8+(tonumber(bgnum) or 30)-30), "0,0,0")
196 else
197 return string.format("<%s:%s>", gmcpchat.getcolor(((tonumber(highlight) or 0)*8)+(tonumber(fgnum) or 30)-30), gmcpchat.getcolor((tonumber(bgnum) or 40)-40))
198 end
199end
200
201gmcpchat.translatecode256 = function (fgnum, bgnum)
202 return string.format("<%s:%s>", gmcpchat.getcolor((tonumber(fgnum) or 0)), gmcpchat.getcolor((tonumber(bgnum) or 0)))
203end
204
205-- function which takes the raw data from gmcp.Comm.Channel.Text.text and fixes all the ascii escape codes
206gmcpchat.escapefix = function (text)
207 local result = text:gsub(string.char(27).."%[(%d);(%d+);(%d+)m", gmcpchat.translatecode16)
208 result = result:gsub(string.char(27).."%[(%d);(%d+)m", gmcpchat.translatecode16) -- wierd exception that I Cant explain..
209 result = result:gsub(string.char(27).."%[0;(%d);(%d+);(%d+)m", gmcpchat.translatecode16) -- wierd exception that I Cant explain..
210 result = result:gsub(string.char(27).."%[0;38;5;(%d+);48;5;(%d+)m", gmcpchat.translatecode256)
211 result = result:gsub(string.char(27).."%[0;38;5;(%d+)m", gmcpchat.translatecode256)
212 result = result:gsub(string.char(27).."%[0;38;5;(%d+);48;5;(%d+)m", gmcpchat.translatecode256)
213 result = result:gsub(string.char(27).."%[38;5;(%d+);48;5;(%d+)m", gmcpchat.translatecode256)
214 return result
215end
216
217-- tie in nameDB highlighting.. just because we can.
218-- NOTE: I'm sure theres a better way of doing this, I just couldnt find it in the API.
219-- suprised there wasnt a ndb.highlightnames type function.
220gmcpchat.highlight = function (text)
221
222 -- no namedb, no highlighting..
223 if gmcpchat.disablenamedb or not ndb then return text end
224
225 local names = ndb.findnames(text)
226 -- no names to highlight, just return it as is..
227 if not names then return text end
228
229 -- find our lines base color.. (note this is non greedy so it doesnt match the whole string)
230 -- note: defaults to <reset> if we cant find any color matching for simple white on black clans
231 -- otherwise the namedb highlights wont reset at the end of each name and we get bleeding.
232 local basecolor = string.match(text, "<.->") or "<reset>"
233 local color = nil
234 local result = text
235 for _,v in ipairs(names) do
236 color = ndb.getcolorp(v)
237 if color then
238 -- this is ugly, just required to anchor to non word characters
239 -- this stops us highlighting sub sections of bigger words..
240 result = string.gsub(result, "(%W)("..v..")(%W)", "%1"..(gmcpchat.getcolorfromname(color) or "")..v..(basecolor or "").."%3")
241 end
242 end
243 return result
244end
245
246
247gmcpchat.aminparty = function ()
248 for _,v in ipairs(gmcp.Comm.Channel.List) do
249 if v.name=="party" then
250 return true
251 end
252 end
253 return false
254end
255
256gmcpchat.demonnicredirect = function ()
257 if gmcpchat.demonnicmap[gmcp.Comm.Channel.Text.channel] and table.contains(demonnic.chat.config.channels, gmcpchat.demonnicmap[gmcp.Comm.Channel.Text.channel]) then
258 -- direct map exists... and so does the destination tab
259 demonnic.chat:decho(gmcpchat.demonnicmap[gmcp.Comm.Channel.Text.channel], gmcpchat.highlight(gmcpchat.escapefix(gmcp.Comm.Channel.Text.text)).."\n")
260 elseif gmcp.Comm.Channel.Text.channel:starts("tell") and gmcpchat.demonnicmap.tell and table.contains(demonnic.chat.config.channels, gmcpchat.demonnicmap.tell) then
261 -- this is a tell (they contain the tellers name, so need a special case for them)
262 demonnic.chat:decho(gmcpchat.demonnicmap.tell, gmcpchat.highlight(gmcpchat.escapefix(gmcp.Comm.Channel.Text.text)).."\n")
263 elseif gmcp.Comm.Channel.Text.channel:starts("clt") and gmcpchat.demonnicmap.clt and table.contains(demonnic.chat.config.channels, gmcpchat.demonnicmap.clt) then
264 -- is a clan, and there is a generic clan link that is valid..
265 demonnic.chat:decho(gmcpchat.demonnicmap.clt, gmcpchat.highlight(gmcpchat.escapefix(gmcp.Comm.Channel.Text.text)).."\n")
266 else
267 demonnic.chat:decho("all", gmcpchat.highlight(gmcpchat.escapefix(gmcp.Comm.Channel.Text.text)).."\n")
268 end
269end
270
271-- this is our event handler
272gmcpchat.textevent = function ()
273 -- lazy attempt at ignoring denizen says to cut down on hunting spam...
274 if gmcpchat.ignoredenizens and (gmcp.Comm.Channel.Text.talker:match(" ") or gmcp.Comm.Channel.Text.talker:match("-")) then
275 return
276 end
277 local timestamp = tostring(getTime(true,"hh:mm:ss:zzz")).." "
278 echo("chat",timestamp)
279 local text = gmcpchat.escapefix(gmcp.Comm.Channel.Text.text).."\n"
280 text = text .. "\n"
281 decho("chat",text)
282 local channel = gmcp.Comm.Channel.Text.channel
283 if channel:sub(1,4) == "tell" then
284 echo("Tells",timestamp)
285 decho("Tells",text)
286 end
287 local tab = gmcpchat.ChatTabs[channel]
288 if tab then
289 echo(tab,timestamp)
290 decho(tab,text)
291 end
292end
293gmcpchat.ChatTabs = {
294 ["ht"] = "House",
295 ["hts"] = "House",
296 ["hnt"] = "House",
297 ["ot"] = "Order",
298 ["ct"] = "City"
299}
300-- register our event handler function
301registerAnonymousEventHandler("gmcp.Comm.Channel.Text", "gmcpchat.textevent")
302
303gmcpchat.enabletrigger = function ()
304 gmcpchat.startTrig = tempRegexTrigger("^Your last login was from domain\: .+\.$", [[gmcpchat.enableCommChannel()]])
305end
306
307registerAnonymousEventHandler("sysConnectionEvent", "gmcpchat.enabletrigger")