handlers.lua (5257B)
1 local action = require( "action" ) 2 local alias = require( "alias" ) 3 local intercept = require( "intercept" ) 4 local gag = require( "gag" ) 5 local macro = require( "macro" ) 6 local sub = require( "sub" ) 7 local interval = require( "interval" ) 8 9 local GA = "\255\249" 10 11 local bold = false 12 local fg = 7 13 local bg = 0 14 15 local lastWasChat = false 16 local lastWasGA = false 17 18 local receiving = false 19 local showInput = true 20 21 local dataBuffer = "" 22 local pendingInputs = { } 23 24 local function echoOn() 25 showInput = true 26 27 return "" 28 end 29 30 local function echoOff() 31 showInput = true 32 33 return "" 34 end 35 36 local function setFG( colour ) 37 return function() 38 fg = colour 39 end 40 end 41 42 local function setBG( colour ) 43 return function() 44 bg = colour 45 end 46 end 47 48 local Escapes = { 49 m = { 50 [ "0" ] = function() 51 bold = false 52 fg = 7 53 bg = 0 54 end, 55 56 [ "1" ] = function() 57 bold = true 58 end, 59 60 [ "30" ] = setFG( 0 ), 61 [ "31" ] = setFG( 1 ), 62 [ "32" ] = setFG( 2 ), 63 [ "33" ] = setFG( 3 ), 64 [ "34" ] = setFG( 4 ), 65 [ "35" ] = setFG( 5 ), 66 [ "36" ] = setFG( 6 ), 67 [ "37" ] = setFG( 7 ), 68 69 [ "40" ] = setBG( 0 ), 70 [ "41" ] = setBG( 1 ), 71 [ "42" ] = setBG( 2 ), 72 [ "43" ] = setBG( 3 ), 73 [ "44" ] = setBG( 4 ), 74 [ "45" ] = setBG( 5 ), 75 [ "46" ] = setBG( 6 ), 76 [ "47" ] = setBG( 7 ), 77 }, 78 } 79 80 local function printPendingInputs() 81 if lastWasChat then 82 mud.newlineMain() 83 84 lastWasChat = false 85 end 86 87 for i = 1, #pendingInputs do 88 mud.printr( pendingInputs[ i ] ) 89 90 lastWasGA = false 91 end 92 93 pendingInputs = { } 94 end 95 96 local function handleChat( message ) 97 lastWasChat = true 98 lastWasGA = false 99 100 if not message then 101 return 102 end 103 104 local oldFG = fg 105 local oldBG = bg 106 local oldBold = bold 107 108 fg = 1 109 bg = 0 110 bold = true 111 112 local noAnsi = message:gsub( "\27%[[%d;]*%a", "" ) 113 114 action.doChatPreActions( noAnsi ) 115 action.doChatAnsiPreActions( message ) 116 117 mud.newlineMain() 118 mud.newlineChat() 119 120 for line, newLine in message:gmatch( "([^\n]*)(\n?)" ) do 121 for text, opts, escape in ( line .. "\27[m" ):gmatch( "(.-)\27%[([%d;]*)(%a)" ) do 122 if text ~= "" then 123 mud.printMain( text, fg, bg, bold ) 124 mud.printChat( text, fg, bg, bold ) 125 end 126 127 for opt in opts:gmatch( "([^;]+)" ) do 128 if Escapes[ escape ][ opt ] then 129 Escapes[ escape ][ opt ]() 130 end 131 end 132 end 133 134 if newLine == "\n" then 135 mud.newlineMain() 136 mud.newlineChat() 137 end 138 end 139 140 mud.drawMain() 141 mud.drawChat() 142 143 action.doChatActions( noAnsi ) 144 action.doChatAnsiActions( message ) 145 146 fg = oldFG 147 bg = oldBG 148 bold = oldBold 149 end 150 151 local function handleData( data ) 152 receiving = true 153 154 dataBuffer = dataBuffer .. data 155 156 if data:match( GA ) then 157 dataBuffer = dataBuffer:gsub( "\r", "" ) 158 159 dataBuffer = dataBuffer:gsub( "\255\252\1", echoOn ) 160 dataBuffer = dataBuffer:gsub( "\255\251\1", echoOff ) 161 162 dataBuffer = dataBuffer:gsub( "\255\253\24", "" ) 163 dataBuffer = dataBuffer:gsub( "\255\253\31", "" ) 164 dataBuffer = dataBuffer:gsub( "\255\253\34", "" ) 165 166 dataBuffer = dataBuffer .. "\n" 167 168 for line in dataBuffer:gmatch( "([^\n]*)\n" ) do 169 if lastWasGA then 170 if line ~= "" then 171 mud.newlineMain() 172 end 173 174 lastWasGA = false 175 end 176 177 if lastWasChat then 178 mud.newlineMain() 179 180 lastWasChat = false 181 end 182 183 local clean, subs = line:gsub( GA, "" ) 184 local hasGA = subs ~= 0 185 186 local noAnsi = clean:gsub( "\27%[%d*%a", "" ) 187 188 local gagged = gag.doGags( noAnsi ) or gag.doAnsiGags( clean ) 189 190 action.doPreActions( noAnsi ) 191 action.doAnsiPreActions( clean ) 192 193 local subbed = sub.doSubs( clean ) 194 195 for text, opts, escape in ( subbed .. "\27[m" ):gmatch( "(.-)\27%[([%d;]*)(%a)" ) do 196 if text ~= "" and not gagged then 197 mud.printMain( text, fg, bg, bold ) 198 end 199 200 for opt in opts:gmatch( "([^;]+)" ) do 201 if Escapes[ escape ][ opt ] then 202 Escapes[ escape ][ opt ]() 203 end 204 end 205 end 206 207 if hasGA then 208 lastWasGA = true 209 printPendingInputs() 210 else 211 if not gagged then 212 mud.newlineMain() 213 end 214 end 215 216 action.doActions( noAnsi ) 217 action.doAnsiActions( clean ) 218 end 219 220 mud.drawMain() 221 222 dataBuffer = "" 223 receiving = false 224 end 225 end 226 227 local function handleCommand( input, hide ) 228 if not alias.doAlias( input ) then 229 if not mud.connected then 230 mud.print( "\n#s> You're not connected..." ) 231 232 return 233 end 234 235 intercept.doIntercept( input ) 236 237 if not hide and input ~= "" then 238 local toShow = ( showInput and input or ( "*" ):rep( input:len() ) ) .. "\n" 239 240 if receiving then 241 table.insert( pendingInputs, toShow ) 242 else 243 if lastWasChat then 244 mud.newlineMain() 245 246 lastWasChat = false 247 end 248 249 lastWasGA = false 250 251 mud.printr( toShow ) 252 end 253 end 254 255 mud.send( input .. "\n" ) 256 mud.drawMain() 257 end 258 end 259 260 local function handleInput( input, display ) 261 for command in ( input .. ";" ):gmatch( "([^;]*);" ) do 262 handleCommand( command, display ) 263 end 264 end 265 266 mud.input = handleInput 267 268 local function handleMacro( key, shift, ctrl, alt ) 269 if shift then 270 key = "s" .. key 271 end 272 273 if ctrl then 274 key = "c" .. key 275 end 276 277 if alt then 278 key = "a" .. key 279 end 280 281 macro.doMacro( key ) 282 end 283 284 local function handleClose() 285 ev.Loop.default:unloop() 286 287 mud.event( "shutdown" ) 288 end 289 290 return { 291 data = handleData, 292 chat = handleChat, 293 input = handleInput, 294 macro = handleMacro, 295 interval = interval.doIntervals, 296 close = handleClose, 297 }