From 1a8b0367d120c1306c31538a4cba0ab2e50f64a6 Mon Sep 17 00:00:00 2001 From: AR2000 Date: Sat, 6 Apr 2024 15:12:26 +0200 Subject: [PATCH] initial commit --- openrgb.lua | 562 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 562 insertions(+) create mode 100755 openrgb.lua diff --git a/openrgb.lua b/openrgb.lua new file mode 100755 index 0000000..ca1bb2f --- /dev/null +++ b/openrgb.lua @@ -0,0 +1,562 @@ +local protoOpenRGB = Proto("openrgb", "OpenRGB SDK") + + +protoOpenRGB.prefs.default_version = Pref.uint("Default protocol version", 4, "The default protocol version assumed when it cannot be determined") + + +local NET_PACKET_ID_REQUEST_CONTROLLER_COUNT = 0 +local NET_PACKET_ID_REQUEST_CONTROLLER_DATA = 1 +local NET_PACKET_ID_REQUEST_PROTOCOL_VERSION = 40 +local NET_PACKET_ID_SET_CLIENT_NAME = 50 +local NET_PACKET_ID_DEVICE_LIST_UPDATED = 100 +local NET_PACKET_ID_REQUEST_PROFILE_LIST = 150 +local NET_PACKET_ID_REQUEST_SAVE_PROFILE = 151 +local NET_PACKET_ID_REQUEST_LOAD_PROFILE = 152 +local NET_PACKET_ID_REQUEST_DELETE_PROFILE = 153 +local NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE = 1000 +local NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS = 1050 +local NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS = 1051 +local NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED = 1052 +local NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE = 1100 +local NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE = 1101 +local NET_PACKET_ID_RGBCONTROLLER_SAVEMODE = 1102 + + +local pID = { + [NET_PACKET_ID_REQUEST_CONTROLLER_COUNT] = "Request RGBController device count from server", + [NET_PACKET_ID_REQUEST_CONTROLLER_DATA] = "Request RGBController data block", + [NET_PACKET_ID_REQUEST_PROTOCOL_VERSION] = "Request OpenRGB SDK protocol version from server", + [NET_PACKET_ID_SET_CLIENT_NAME] = "Send client name string to server", + [NET_PACKET_ID_DEVICE_LIST_UPDATED] = "Indicate to clients that device list has updated", + [NET_PACKET_ID_REQUEST_PROFILE_LIST] = "Request profile list", + [NET_PACKET_ID_REQUEST_SAVE_PROFILE] = "Save current configuration in a new profile", + [NET_PACKET_ID_REQUEST_LOAD_PROFILE] = "Load a given profile", + [NET_PACKET_ID_REQUEST_DELETE_PROFILE] = "Delete a given profile", + [NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE] = "RGBController::ResizeZone()", + [NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS] = "RGBController::UpdateLEDs()", + [NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS] = "RGBController::UpdateZoneLEDs()", + [NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED] = "RGBController::UpdateSingleLED()", + [NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE] = "RGBController::SetCustomMode()", + [NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE] = "RGBController::UpdateMode()", + [NET_PACKET_ID_RGBCONTROLLER_SAVEMODE] = "RGBController::SaveMode()", +} + +local deviceTypes = { + [0] = "MOTHERBOARD", + "DRAM", + "GPU", + "COOLER", + "LEDSTRIP", + "KEYBOARD", + "MOUSE", + "MOUSEMAT", + "HEADSET", + "HEADSET_STAND", + "GAMEPAD", + "LIGHT", + "SPEAKER", + "VIRTUAL", + "STORAGE", + "CASE", + "MICROPHONE", + "ACCESSORY", + "KEYPAD" +} + + +local pf_magic = ProtoField.string("openrgb.magic", "Magic") +local pf_dev_idx = ProtoField.uint32("openrgb.dev_idx", "Device Index") +local pf_id = ProtoField.uint32("openrgb.id", "Packet ID", base.DEC, pID) +local pf_size = ProtoField.uint32("openrgb.size", "Packet Size") +local pf_data = ProtoField.none("openrgb.data", "Data") + +local pf_prot_ver = ProtoField.uint32("openrgb.version", "Protocol version") +local pf_client_name = ProtoField.stringz("openrgb.client_name", "Client name") +local pf_profile = ProtoField.stringz("openrgb.profile", "Profile name") +local pf_zone_idx = ProtoField.uint32("openrgb.zone_idx", "Zone index") +local pf_new_size = ProtoField.uint32("openrgb.new_size", "New size") +local pf_data_size = ProtoField.uint32("openrgb.data_size", "Size of all data") +local pf_num_colors = ProtoField.uint16("openrgb.num_colors", "Number of color") +local pf_led_color = ProtoField.uint32("openrgb.led_color", "LED color", base.HEX) +local pf_led_idx = ProtoField.uint32("openrgb.led_idx", "LED index") + +local pf_type = ProtoField.int32("openrgb.type", "RGBController type", base.DEC, deviceTypes) +local pf_name_len = ProtoField.uint16("openrgb.name_len", "Length of RGBController name") +local pf_name = ProtoField.stringz("openrgb.name", "RGBController name") +local pf_vendor_len = ProtoField.uint16("openrgb.vendor_len", "Length of RGBController vendor") +local pf_vendor = ProtoField.stringz("openrgb.vendor", "RGBController vendor") +local pf_description_len = ProtoField.uint16("openrgb.description_len", "Length of RGBController description") +local pf_description = ProtoField.stringz("openrgb.description", "RGBController description") +local pf_version_len = ProtoField.uint16("openrgb.version_len", "Length of RGBController version") +local pf_version = ProtoField.stringz("openrgb.version", "RGBController version") +local pf_serial_len = ProtoField.uint16("openrgb.serial_len", "Length of RGBController serial") +local pf_serial = ProtoField.stringz("openrgb.serial", "RGBController serial") +local pf_location_len = ProtoField.uint16("openrgb.location_len", "Length of RGBController location") +local pf_location = ProtoField.stringz("openrgb.location", "RGBController location") +local pf_num_modes = ProtoField.uint16("openrgb.num_modes", "Number of modes in RGBController") +local pf_active_mode = ProtoField.int32("openrgb.active_mode", "RGBController active_mode") +local pf_num_zones = ProtoField.uint16("openrgb.num_zones", "Number of zones in RGBController") +local pf_num_leds = ProtoField.uint16("openrgb.num_leds", "Number of LEDs in RGBController") +local pf_colors = ProtoField.uint32("openrgb.colors", "RGBController colors", base.HEX) + +--Mode data +local pf_mode_name_len = ProtoField.uint16("openrgb.mode_name_len", "Length of mode name string") +local pf_mode_name = ProtoField.stringz("openrgb.mode_name", "Mode name") +local pf_mode_value = ProtoField.int32("openrgb.mode_value", "Mode value") +local pf_mode_flags = ProtoField.uint32("openrgb.mode_flags", "Mode flags") +local pf_mode_speed_min = ProtoField.uint32("openrgb.mode_speed_min", "Mode speed_min") +local pf_mode_speed_max = ProtoField.uint32("openrgb.mode_speed_max", "Mode speed_max") +local pf_mode_brightness_min = ProtoField.uint32("openrgb.mode_brightness_min", "Mode brightness_min") +local pf_mode_brightness_max = ProtoField.uint32("openrgb.mode_brightness_max", "Mode brightness_max") +local pf_mode_colors_min = ProtoField.uint32("openrgb.mode_colors_min", "Mode colors_min") +local pf_mode_colors_max = ProtoField.uint32("openrgb.mode_colors_max", "Mode colors_max") +local pf_mode_speed = ProtoField.uint32("openrgb.mode_speed", "Mode speed") +local pf_mode_brightness = ProtoField.uint32("openrgb.mode_brightness", "Mode brightness") +local pf_mode_direction = ProtoField.uint32("openrgb.mode_direction", "Mode direction") +local pf_mode_color_mode = ProtoField.uint32("openrgb.mode_color_mode", "Mode color_mode") +local pf_mode_num_colors = ProtoField.uint16("openrgb.mode_num_colors", "Mode number of colors") +local pf_mode_colors = ProtoField.uint32("openrgb.mode_colors", "Mode color", base.HEX) + +--Zone Data +local pf_zone_name_len = ProtoField.uint16("openrgb.zone_name_len", "Length of zone name string") +local pf_zone_name = ProtoField.stringz("openrgb.zone_name", "Zone name") +local pf_zone_type = ProtoField.int32("openrgb.zone_type", "Zone type value") +local pf_zone_leds_min = ProtoField.uint32("openrgb.zone_leds_min", "Zone leds_min value") +local pf_zone_leds_max = ProtoField.uint32("openrgb.zone_leds_max", "Zone leds_max value") +local pf_zone_leds_count = ProtoField.uint32("openrgb.zone_leds_count", "Zone leds_count value") +local pf_zone_matrix_len = ProtoField.uint16("openrgb.zone_matrix_len", "Zone matrix length") +local pf_zone_matrix_height = ProtoField.uint32("openrgb.zone_matrix_height", "Zone matrix_map height") +local pf_zone_matrix_width = ProtoField.uint32("openrgb.zone_matrix_width", "Zone matrix_map width") +local pf_zone_matrix_data = ProtoField.uint32("openrgb.zone_matrix_data", "Zone matrix_map data", base.HEX) +local pf_zone_segment_number = ProtoField.uint16("openrgb.zone_segment_number", "Number of segments") + +--Segment Data +local pf_segment_name_len = ProtoField.uint16("openrgb.segment_name_len", "Length of segment name") +local pf_segment_name = ProtoField.stringz("openrgb.segment_name", "Segment name") +local pf_segment_type = ProtoField.uint32("openrgb.segment_type", "Zone type the segment is part of") +local pf_segment_start = ProtoField.uint32("openrgb.segment_start", "First LED index") +local pf_segment_led_count = ProtoField.uint32("openrgb.segment_led_count", "Number of LED") + +--Led Data +local pf_led_name_len = ProtoField.uint32("openrgb.led_name_len", "Length of LED name") +local pf_led_name = ProtoField.stringz("openrgb.led_name", "LED name") +local pf_led_value = ProtoField.uint32("openrgb.led_value", "LED value field value") + +local pf_mode_idx = ProtoField.int32("openrgb.mode_idx", "Mode index") +local pf_profile_name_len = ProtoField.uint16("openrgb.profile_name_len", "Profile name length") +local pf_profile_count = ProtoField.uint32("openrgb.profile_count", "Profile count") +local pf_controller_count = ProtoField.uint32("openrgb.controller_count", "Controller count") + +protoOpenRGB.fields = { + --header + pf_magic, pf_dev_idx, pf_id, pf_size, + pf_data, + --misc + pf_prot_ver, pf_client_name, pf_profile, + pf_zone_idx, pf_new_size, pf_colors, + pf_data_size, pf_num_colors, pf_led_color, + pf_led_idx, pf_type, pf_name_len, + pf_name, pf_vendor_len, pf_vendor, + pf_description_len, pf_description, pf_version_len, + pf_version, pf_serial_len, pf_serial, + pf_location_len, pf_location, pf_num_modes, + pf_active_mode, pf_num_zones, pf_num_leds, + pf_mode_idx, pf_profile_name_len, pf_profile_count, + pf_controller_count, + --mode data + pf_mode_name_len, pf_mode_name, pf_mode_value, + pf_mode_flags, pf_mode_speed_min, pf_mode_speed_max, + pf_mode_brightness_min, pf_mode_brightness_max, pf_mode_colors_min, + pf_mode_colors_max, pf_mode_speed, pf_mode_brightness, + pf_mode_direction, pf_mode_color_mode, pf_mode_num_colors, + pf_mode_colors, + --zone data + pf_zone_name_len, pf_zone_name, pf_zone_type, + pf_zone_leds_min, pf_zone_leds_max, pf_zone_leds_count, + pf_zone_matrix_len, pf_zone_matrix_height, pf_zone_matrix_width, + pf_zone_matrix_data, pf_zone_segment_number, + --segment + pf_segment_name_len, pf_segment_name, pf_segment_type, + pf_segment_start, pf_segment_led_count, + --led data + pf_led_name_len, pf_led_name, pf_led_value, +} + + +local num_colors = Field.new("openrgb.num_colors") + +local conversations = {} + +local function getConvID(pktinfo) + local src = string.format("%s:%s", pktinfo.src, pktinfo.src_port) + local dst = string.format("%s:%s", pktinfo.dst, pktinfo.dst_port) + local convID = src .. dst + if (src > dst) then + convID = dst .. src + end + return convID +end + +local function getVersion(pktinfo) + if conversations[getConvID(pktinfo)] then + return conversations[getConvID(pktinfo)].version or protoOpenRGB.prefs.default_version + else + return protoOpenRGB.prefs.default_version + end +end + +local dissectOpenRGB + +function protoOpenRGB.dissector(tvbuf, pktinfo, root) + local pktlen = tvbuf:len() + local bytesConsumed = 0 + while bytesConsumed < pktlen do + local result = dissectOpenRGB(tvbuf, pktinfo, root) + if result > 0 then + bytesConsumed = bytesConsumed + result + elseif result == 0 then + return 0 + else + pktinfo.desegment_offset = bytesConsumed + result = -result + pktinfo.desegment_len = result + end + return pktlen + end + return bytesConsumed +end + +local function dissectorModeData(tvbuf, pktinfo, tree) + local child = tree:add(tvbuf(), "Mode Data") + local offset = 0 + child:add_le(pf_mode_name_len, tvbuf(offset, 2)) + local name_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + child:add_le(pf_mode_name, tvbuf(offset, name_len)) + child:append_text(": " .. tvbuf(offset, name_len):stringz()) + offset = offset + name_len + child:add_le(pf_mode_value, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_mode_flags, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_mode_speed_min, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_mode_speed_max, tvbuf(offset, 4)) + offset = offset + 4 + if (getVersion(pktinfo) >= 3) then + child:add_le(pf_mode_brightness_min, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_mode_brightness_max, tvbuf(offset, 4)) + offset = offset + 4 + end + child:add_le(pf_mode_colors_min, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_mode_colors_max, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_mode_speed, tvbuf(offset, 4)) + offset = offset + 4 + if (getVersion(pktinfo) >= 3) then + child:add_le(pf_mode_brightness, tvbuf(offset, 4)) + offset = offset + 4 + end + child:add_le(pf_mode_direction, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_mode_color_mode, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_mode_num_colors, tvbuf(offset, 2)) + local mode_num_colors = tvbuf(offset, 2):le_uint() + offset = offset + 2 + for i = 1, mode_num_colors do + child:add_le(pf_mode_colors, tvbuf(offset, 4)) + offset = offset + 4 + end + child.len = offset + return offset +end + +local function dissectorSegment(tvbuf, pktinfo, tree) + local child = tree:add(tvbuf(), "Segment Data") + local offset = 0 + child:add_le(pf_segment_name_len, tvbuf(offset, 2)) + local name_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + child:add_le(pf_segment_name, tvbuf(offset, name_len)) + offset = offset + name_len + child:add_le(pf_segment_type, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_segment_start, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_segment_led_count, tvbuf(offset, 4)) + offset = offset + 4 + child.len = offset + return child.len +end + +local function dissectorZoneData(tvbuf, pktinfo, tree) + local child = tree:add(tvbuf(), "Zone Data") + local offset = 0 + child:add_le(pf_zone_name_len, tvbuf(offset, 2)) + local name_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + child:add_le(pf_zone_name, tvbuf(offset, name_len)) + child:append_text(": " .. tvbuf(offset, name_len):stringz()) + offset = offset + name_len + child:add_le(pf_zone_type, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_zone_leds_min, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_zone_leds_max, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_zone_leds_count, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_zone_matrix_len, tvbuf(offset, 2)) + local matrix_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + if (matrix_len == 0) then + child.len = offset + return offset + end + child:add_le(pf_zone_matrix_height, tvbuf(offset, 4)) + offset = offset + 4 + child:add_le(pf_zone_matrix_width, tvbuf(offset, 4)) + offset = offset + 4 + matrix_len = (matrix_len - 8) / 4 + local matrix_data = child:add(tvbuf(offset, matrix_len * 4), "Matrix data [" .. matrix_len .. "]") + for i = 1, matrix_len do + matrix_data:add_le(pf_zone_matrix_data, tvbuf(offset, 4)):append_text(string.format("[%s]", i)) + offset = offset + 4 + end + if (getVersion(pktinfo) >= 4) then + child:add_le(pf_zone_segment_number, tvbuf(offset, 2)) + local segment_number = tvbuf(offset, 2):le_uint() + offset = offset + 2 + for i = 1, segment_number do + offset = offset + dissectorSegment(tvbuf(offset), pktinfo, child) + end + end + child.len = offset + return child.len +end + +local function dissectorLedData(tvbuf, pktinfo, tree) + local child = tree:add(tvbuf(0, 6), "LED Data") + child:add_le(pf_led_name_len, tvbuf(0, 2)) + local name_len = tvbuf(0, 2):le_uint() + child:add(pf_led_name, tvbuf(2, name_len)) + child:append_text(": " .. tvbuf(2, name_len):stringz()) + child:add_le(pf_led_value, tvbuf(2 + name_len, 4)) + child.len = name_len + 6 + return name_len + 6 +end + +local dataDissector = {} + +dataDissector[NET_PACKET_ID_REQUEST_CONTROLLER_COUNT] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_controller_count, tvbuf(0, 4)) +end + +dataDissector[NET_PACKET_ID_REQUEST_CONTROLLER_DATA] = function(tvbuf, pktinfo, tree) + pktinfo.cols.protocol:append(" V" .. getVersion(pktinfo)) + if (tvbuf:len() == 4) then + tree:add_le(pf_prot_ver, tvbuf(0, 4)) + else + local offset = 0 + tree:add_le(pf_data_size, tvbuf(offset, 4)) + offset = offset + 4 + tree:add_le(pf_type, tvbuf(offset, 4)) + offset = offset + 4 + tree:add_le(pf_name_len, tvbuf(offset, 2)) + --name + local name_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + tree:add_le(pf_name, tvbuf(offset, name_len)) + offset = offset + name_len + --vendor + if (getVersion(pktinfo) >= 1) then + tree:add_le(pf_vendor_len, tvbuf(offset, 2)) + local vendor_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + tree:add_le(pf_vendor, tvbuf(offset, vendor_len)) + offset = offset + vendor_len + end + --description + tree:add_le(pf_description_len, tvbuf(offset, 2)) + local description_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + tree:add_le(pf_description, tvbuf(offset, description_len)) + offset = offset + description_len + --version + tree:add_le(pf_version_len, tvbuf(offset, 2)) + local version_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + tree:add_le(pf_version, tvbuf(offset, version_len)) + offset = offset + version_len + --serial + tree:add_le(pf_serial_len, tvbuf(offset, 2)) + local serial_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + tree:add_le(pf_serial, tvbuf(offset, serial_len)) + offset = offset + serial_len + --location + tree:add_le(pf_location_len, tvbuf(offset, 2)) + local location_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + tree:add_le(pf_location, tvbuf(offset, location_len)) + offset = offset + location_len + + --modes + tree:add_le(pf_num_modes, tvbuf(offset, 2)) + local num_modes = tvbuf(offset, 2):le_uint() + offset = offset + 2 + tree:add_le(pf_active_mode, tvbuf(offset, 4)) + offset = offset + 4 + local modes_tree = tree:add(tvbuf(offset), "Modes") + modes_tree.len = 0 + for i = 1, num_modes do + local len = dissectorModeData(tvbuf(offset), pktinfo, modes_tree) + offset = offset + len + modes_tree.len = modes_tree.len + len + end + + --zones + tree:add_le(pf_num_zones, tvbuf(offset, 2)) + local num_zones = tvbuf(offset, 2):le_uint() + offset = offset + 2 + local zones_tree = tree:add(tvbuf(offset), "Zones") + zones_tree.len = 0 + for i = 1, num_zones do + local len = dissectorZoneData(tvbuf(offset), pktinfo, zones_tree) + offset = offset + len + zones_tree.len = zones_tree.len + len + end + + --leds + tree:add_le(pf_num_leds, tvbuf(offset, 2)) + local num_num_leds = tvbuf(offset, 2):le_uint() + offset = offset + 2 + local leds_tree = tree:add(tvbuf(offset), "LEDs") + leds_tree.len = 0 + for i = 1, num_num_leds do + local len = dissectorLedData(tvbuf(offset), pktinfo, leds_tree) + offset = offset + len + leds_tree.len = leds_tree.len + len + end + + --colors + tree:add_le(pf_num_colors, tvbuf(offset, 2)) + local colors_tree = tree:add(tvbuf(offset), "LEDs color") + local num_leds = tvbuf(offset, 2):le_uint() + offset = offset + 2 + for i = 1, num_leds do + colors_tree:add_le(pf_colors, tvbuf(offset, 4)) + offset = offset + 4 + end + end +end + +dataDissector[NET_PACKET_ID_REQUEST_PROTOCOL_VERSION] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_prot_ver, tvbuf(0, 4)) + local convID = getConvID(pktinfo) + conversations[convID] = conversations[convID] or {} + conversations[convID].version = math.min(tvbuf(0, 4):le_uint(), getVersion(pktinfo)) +end + +dataDissector[NET_PACKET_ID_SET_CLIENT_NAME] = function(tvbuf, pktinfo, tree) + tree:add(pf_client_name, tvbuf()) +end + +dataDissector[NET_PACKET_ID_REQUEST_PROFILE_LIST] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_data_size, tvbuf(0, 4)) + tree:add_le(pf_profile_count, tvbuf(4, 2)) + local profile_count = tvbuf(4, 2):le_uint() + local offset = 6 + for i = 1, profile_count do + tree:add_le(pf_profile_name_len, tvbuf(offset, 2)) + local profile_name_len = tvbuf(offset, 2):le_uint() + offset = offset + 2 + tree:add_le(pf_profile, tvbuf(offset, profile_name_len)) + offset = offset + profile_name_len + end +end + +dataDissector[NET_PACKET_ID_REQUEST_SAVE_PROFILE] = function(tvbuf, pktinfo, tree) + tree:add(pf_profile, tvbuf()) +end + +dataDissector[NET_PACKET_ID_REQUEST_LOAD_PROFILE] = function(tvbuf, pktinfo, tree) + tree:add(pf_profile, tvbuf()) +end + +dataDissector[NET_PACKET_ID_REQUEST_DELETE_PROFILE] = function(tvbuf, pktinfo, tree) + tree:add(pf_profile, tvbuf()) +end + +dataDissector[NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_zone_idx, tvbuf(0, 4)) + tree:add_le(pf_new_size, tvbuf(4, 4)) +end + +dataDissector[NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_data_size, tvbuf(0, 4)) + tree:add_le(pf_num_colors, tvbuf(4, 2)) + local offset = 6 + local child = tree:add(tvbuf(offset, num_colors()()), "LEDs") + for i = 0, num_colors()() - 1 do + child:add(pf_led_color, tvbuf(offset + 4 * i, 4)) + end +end + +dataDissector[NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_data_size, tvbuf(0, 4)) + tree:add_le(pf_zone_idx, tvbuf(4, 4)) + tree:add_le(pf_num_colors, tvbuf(8, 2)) + local offset = 10 + local child = tree:add(tvbuf(offset, num_colors()()), "LEDs") + for i = 0, num_colors()() - 1 do + child:add(pf_led_color, tvbuf(offset + 4 * i, 4)) + end +end + +dataDissector[NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_led_idx, tvbuf(0, 4)) + tree:add(pf_led_color, tvbuf(4, 4)) +end + +--dataDissector[NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE] = function(tvbuf, pktinfo, tree) end + +dataDissector[NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_data_size, tvbuf(0, 4)) + tree:add_le(pf_mode_idx, tvbuf(4, 4)) + dissectorModeData(tvbuf(8), pktinfo, tree) +end + +dataDissector[NET_PACKET_ID_RGBCONTROLLER_SAVEMODE] = function(tvbuf, pktinfo, tree) + tree:add_le(pf_data_size, tvbuf(0, 4)) + tree:add_le(pf_mode_idx, tvbuf(4, 4)) + dissectorModeData(tvbuf(8), pktinfo, tree) +end + +function dissectOpenRGB(tvbuf, pktinfo, root) + if (tvbuf(0, 4):string() ~= "ORGB") then return 0 end + if (16 + tvbuf(12, 4):le_uint() > tvbuf:len()) then return tvbuf:len() - (16 + tvbuf(12, 4):le_uint()) end + pktinfo.cols.protocol:set("OPENRGB") + local tree = root:add(protoOpenRGB, tvbuf()) + tree:add(pf_magic, tvbuf(0, 4)) + tree:add_le(pf_dev_idx, tvbuf(4, 4)) + tree:add_le(pf_id, tvbuf(8, 4)) + pktinfo.cols.info:set(pID[tvbuf(8, 4):le_uint()] or "Unkown") + tree:append_text(": " .. (pID[tvbuf(8, 4):le_uint()] or "Unkown")) + tree:add_le(pf_size, tvbuf(12, 4)) + if (tvbuf(12, 4):le_uint() > 0) then + if (dataDissector[tvbuf(8, 4):le_uint()]) then + dataDissector[tvbuf(8, 4):le_uint()](tvbuf(16), pktinfo, tree) + else + tree:add(pf_data, tvbuf(16)) + end + end + + pktinfo.cols.protocol:set("OPENRGB V" .. getVersion(pktinfo)) + return tvbuf:len() +end + +DissectorTable.get("tcp.port"):add(6742, protoOpenRGB)