Last active
May 3, 2020 23:02
-
-
Save BenLubar/a966506cb22186ef111c42210537e04e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local dfplex = Proto("dfplex", "Dwarf Fortress Multiplexer") | |
local cmds = { | |
[0x6e] = "update", | |
[0x6f] = "sendKey", | |
[0x73] = "connect", | |
[0x75] = "resize", | |
[0x76] = "requestTurn" | |
} | |
local colors = { | |
[0] = "black", | |
[1] = "blue", | |
[2] = "green", | |
[3] = "cyan", | |
[4] = "red", | |
[5] = "magenta", | |
[6] = "yellow", | |
[7] = "white" | |
} | |
local keys = { | |
[8] = "backspace", | |
[9] = "tab", | |
[12] = "num", | |
[13] = "enter", | |
[19] = "pause", | |
[20] = "caps", | |
[27] = "esc", | |
[32] = "space", | |
[33] = "pgup", | |
[34] = "pgdn", | |
[35] = "end", | |
[36] = "home", | |
[37] = "left", | |
[38] = "up", | |
[39] = "right", | |
[40] = "down", | |
[44] = "print", | |
[45] = "ins", | |
[46] = "del", | |
[48] = "0", | |
[49] = "1", | |
[50] = "2", | |
[51] = "3", | |
[52] = "4", | |
[53] = "5", | |
[54] = "6", | |
[55] = "7", | |
[56] = "8", | |
[57] = "9", | |
[59] = ";", | |
[65] = "a", | |
[66] = "b", | |
[67] = "c", | |
[68] = "d", | |
[69] = "e", | |
[70] = "f", | |
[71] = "g", | |
[72] = "h", | |
[73] = "i", | |
[74] = "j", | |
[75] = "k", | |
[76] = "l", | |
[77] = "m", | |
[78] = "n", | |
[79] = "o", | |
[80] = "p", | |
[81] = "q", | |
[82] = "r", | |
[83] = "s", | |
[84] = "t", | |
[85] = "u", | |
[86] = "v", | |
[87] = "w", | |
[88] = "x", | |
[89] = "y", | |
[90] = "z", | |
[91] = "cmd", | |
[92] = "cmd", | |
[93] = "cmd", | |
[96] = "num_0", | |
[97] = "num_1", | |
[98] = "num_2", | |
[99] = "num_3", | |
[100] = "num_4", | |
[101] = "num_5", | |
[102] = "num_6", | |
[103] = "num_7", | |
[104] = "num_8", | |
[105] = "num_9", | |
[106] = "num_multiply", | |
[107] = "num_add", | |
[108] = "num_enter", | |
[109] = "num_subtract", | |
[110] = "num_decimal", | |
[111] = "num_divide", | |
[124] = "print", | |
[144] = "num", | |
[145] = "scroll", | |
[186] = ";", | |
[187] = "=", | |
[188] = ",", | |
[189] = "-", | |
[190] = ".", | |
[191] = "/", | |
[192] = "`", | |
[219] = "[", | |
[220] = "\\", | |
[221] = "]", | |
[222] = "'", | |
[223] = "`", | |
[224] = "cmd", | |
[225] = "alt" | |
} | |
local modifierMap = { | |
[0] = "", | |
[1] = "shift+", | |
[2] = "ctrl+", | |
[3] = "ctrl+shift+", | |
[4] = "alt+", | |
[5] = "shift+alt+", | |
[6] = "ctrl+alt+", | |
[7] = "ctrl+alt+shift+" | |
} | |
local pf_command = ProtoField.uint8("dfplex.cmd", "Command", base.DEC_HEX, cmds) | |
local pf_sendkey = ProtoField.bytes("dfplex.sendkey", "Send Key") | |
local pf_sendkey_keycode = ProtoField.uint8("dfplex.sendkey.keycode", "Key Code", base.DEC_HEX, keys) | |
local pf_sendkey_charcode = ProtoField.char("dfplex.sendkey.charcode", "Char Code", base.HEX) | |
local pf_sendkey_mod_shift = ProtoField.bool("dfplex.sendkey.mod.shift", "Modifier: shift", 8, nil, 1) | |
local pf_sendkey_mod_ctrl = ProtoField.bool("dfplex.sendkey.mod.ctrl", "Modifier: ctrl", 8, nil, 2) | |
local pf_sendkey_mod_alt = ProtoField.bool("dfplex.sendkey.mod.alt", "Modifier: alt", 8, nil, 4) | |
local pf_resize = ProtoField.bytes("dfplex.resize", "Resize") | |
local pf_resize_gridw = ProtoField.uint8("dfplex.resize.gridw", "Grid Width", base.DEC) | |
local pf_resize_gridh = ProtoField.uint8("dfplex.resize.gridg", "Grid Height", base.DEC) | |
local pf_update = ProtoField.bytes("dfplex.update", "Update") | |
local pf_update_connected_client_count = ProtoField.uint8("dfplex.update.connected_client_count", "Connected Client Count", base.DEC) | |
local pf_update_is_active = ProtoField.bool("dfplex.update.is_active", "Is Active (unused)", base.NONE) | |
local pf_update_load = ProtoField.int32("dfplex.update.load", "Load / Sum of Frames (unused)", base.DEC) | |
local pf_update_dim_x = ProtoField.uint8("dfplex.update.dim_x", "Viewport Width", base.DEC) | |
local pf_update_dim_y = ProtoField.uint8("dfplex.update.dim_y", "Viewport Height", base.DEC) | |
local pf_update_info_len = ProtoField.uint8("dfplex.update.info_len", "Status Information (length)", base.DEC) | |
local pf_update_info = ProtoField.string("dfplex.update.info", "Status Information", base.ASCII) | |
local pf_update_debug_info_len = ProtoField.uint16("dfplex.update.debug_info_len", "Debug Information (length)", base.DEC) | |
local pf_update_debug_info = ProtoField.string("dfplex.update.debug_info", "Debug Information", base.ASCII) | |
local pf_update_modified_tile = ProtoField.bytes("dfplex.update.modified_tile", "Modified Tile") | |
local pf_update_modified_tile_x = ProtoField.uint8("dfplex.update.modified_tile.x", "X coordinate", base.DEC) | |
local pf_update_modified_tile_y = ProtoField.uint8("dfplex.update.modified_tile.y", "Y coordinate", base.DEC) | |
local pf_update_modified_tile_ch = ProtoField.char("dfplex.update.modified_tile.ch", "Tile Symbol", base.HEX) | |
local pf_update_modified_tile_bg = ProtoField.uint8("dfplex.update.modified_tile.bg", "Background Color", base.DEC, colors, 7) | |
local pf_update_modified_tile_bg_bright = ProtoField.bool("dfplex.update.modified_tile.bg_bright", "Background Color Brightness", 8, nil, 8) | |
local pf_update_modified_tile_is_text = ProtoField.bool("dfplex.update.modified_tile.is_text", "Is Text", 8, nil, 64) | |
local pf_update_modified_tile_is_overworld = ProtoField.bool("dfplex.update.modified_tile.is_overworld", "Is Overworld", 8, nil, 128) | |
local pf_update_modified_tile_fg = ProtoField.uint8("dfplex.update.modified_tile.fg", "Foreground Color", base.DEC, colors, 7) | |
local pf_update_modified_tile_fg_bright = ProtoField.bool("dfplex.update.modified_tile.fg_bright", "Foreground Color Brightness", 8, nil, 8) | |
dfplex.fields = { pf_command, pf_sendkey_keycode, pf_sendkey_charcode, | |
pf_sendkey_mod_shift, pf_sendkey_mod_ctrl, pf_sendkey_mod_alt, | |
pf_resize_gridw, pf_resize_gridh, pf_update_connected_client_count, | |
pf_update_is_active, pf_update_load, pf_update_dim_x, pf_update_dim_y, | |
pf_update_info_len, pf_update_info, pf_update_debug_info_len, | |
pf_update_debug_info, pf_update_modified_tile, pf_update_modified_tile_x, | |
pf_update_modified_tile_y, pf_update_modified_tile_ch, | |
pf_update_modified_tile_bg, pf_update_modified_tile_bg_bright, | |
pf_update_modified_tile_is_text, pf_update_modified_tile_is_overworld, | |
pf_update_modified_tile_fg, pf_update_modified_tile_fg_bright, | |
pf_sendkey, pf_resize, pf_update } | |
local command_field = Field.new("dfplex.cmd") | |
function dfplex.dissector(tvbuf, pktinfo, root) | |
pktinfo.cols.protocol:set("dfplex") | |
local pktlen = tvbuf:reported_length_remaining() | |
local tree = root:add(dfplex, tvbuf:range(0, pktlen)) | |
tree:add(pf_command, tvbuf:range(0, 1)) | |
local pos = 1 | |
local cmd = command_field()() | |
if cmd == 0x6e then -- update | |
if pktlen == 1 then | |
pktinfo.cols.info:set("dfplex Update Request") | |
-- client (no payload) | |
else | |
local update = tree:add(pf_update, tvbuf:range(1, pktlen - 1)) | |
-- server | |
update:add(pf_update_connected_client_count, tvbuf:range(1, 1)) | |
update:add(pf_update_is_active, tvbuf:range(2, 1)) | |
update:add(pf_update_load, tvbuf:range(3, 4)) | |
update:add(pf_update_dim_x, tvbuf:range(7, 1)) | |
update:add(pf_update_dim_y, tvbuf:range(8, 1)) | |
local str_len = tvbuf:range(9, 1):uint() | |
update:add(pf_update_info_len, tvbuf:range(9, 1)) | |
update:add(pf_update_info, tvbuf:range(10, str_len)) | |
pos = 10 + str_len | |
str_len = tvbuf:range(pos, 2):uint() | |
update:add(pf_update_debug_info_len, tvbuf:range(pos, 2)) | |
update:add(pf_update_debug_info, tvbuf:range(pos + 2, str_len)) | |
pos = pos + 2 + str_len | |
pktinfo.cols.info:set("dfplex Update ("..((pktlen - pos)/5).." tiles)") | |
while pos + 5 <= pktlen do | |
local tile = update:add(pf_update_modified_tile, tvbuf:range(pos, 5)) | |
tile:add(pf_update_modified_tile_x, tvbuf:range(pos, 1)) | |
tile:add(pf_update_modified_tile_y, tvbuf:range(pos + 1, 1)) | |
tile:add(pf_update_modified_tile_ch, tvbuf:range(pos + 2, 1)) | |
tile:add(pf_update_modified_tile_bg, tvbuf:range(pos + 3, 1)) | |
tile:add(pf_update_modified_tile_bg_bright, tvbuf:range(pos + 3, 1)) | |
tile:add(pf_update_modified_tile_is_text, tvbuf:range(pos + 3, 1)) | |
tile:add(pf_update_modified_tile_is_overworld, tvbuf:range(pos + 3, 1)) | |
tile:add(pf_update_modified_tile_fg, tvbuf:range(pos + 4, 1)) | |
tile:add(pf_update_modified_tile_fg_bright, tvbuf:range(pos + 4, 1)) | |
pos = pos + 5 | |
end | |
end | |
elseif cmd == 0x6f then -- sendKey | |
local keycode = tvbuf:range(1, 1):uint() | |
local charcode = tvbuf:range(2, 1):uint() | |
local modifiers = tvbuf:range(3, 1):uint() | |
if charcode == 0 or modifiers ~= 0 then | |
pktinfo.cols.info:set("dfplex Send Key "..(modifierMap[modifiers] or "ERR+")..(keys[keycode] or keycode)) | |
else | |
pktinfo.cols.info:set("dfplex Send Key '"..chr(charcode).."'") | |
end | |
local sendkey = tree:add(pf_sendkey, tvbuf:range(1, 3)) | |
sendkey:add(pf_sendkey_keycode, tvbuf:range(1, 1)) | |
sendkey:add(pf_sendkey_charcode, tvbuf:range(2, 1)) | |
sendkey:add(pf_sendkey_mod_shift, tvbuf:range(3, 1)) | |
sendkey:add(pf_sendkey_mod_ctrl, tvbuf:range(3, 1)) | |
sendkey:add(pf_sendkey_mod_alt, tvbuf:range(3, 1)) | |
pos = 4 | |
elseif cmd == 0x73 then -- connect | |
pktinfo.cols.info:set("dfplex Connect") | |
-- (no payload) | |
elseif cmd == 0x75 then -- resize | |
pktinfo.cols.info:set("dfplex Resize to "..tvbuf:range(1, 1):uint().."x"..tvbuf:range(2, 1):uint()) | |
local resize = tree:add(pf_resize, tvbuf:range(1, 2)) | |
resize:add(pf_resize_gridw, tvbuf:range(1, 1)) | |
resize:add(pf_resize_gridh, tvbuf:range(2, 1)) | |
pos = 3 | |
elseif cmd == 0x76 then -- requestTurn | |
pktinfo.cols.info:set("dfplex Request Turn") | |
-- (no payload) | |
else | |
-- unknown/malformed | |
end | |
return pos | |
end | |
ws_dissector_table = DissectorTable.get("ws.protocol") | |
ws_dissector_table:add("DFPlex-v0.2", dfplex) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment