Implemented right-click menu to remove or download loot (files/screenshots).
This commit is contained in:
@@ -59,3 +59,23 @@ proc sendAgentTask*(connection: WsConnection, agentId: string, command: string,
|
||||
}
|
||||
)
|
||||
connection.ws.sendEvent(event, connection.sessionKey)
|
||||
|
||||
proc sendRemoveLoot*(connection: WsConnection, lootId: string) =
|
||||
let event = Event(
|
||||
eventType: CLIENT_LOOT_REMOVE,
|
||||
timestamp: now().toTime().toUnix(),
|
||||
data: %*{
|
||||
"lootId": lootId
|
||||
}
|
||||
)
|
||||
connection.ws.sendEvent(event, connection.sessionKey)
|
||||
|
||||
proc sendDownloadLoot*(connection: WsConnection, lootId: string) =
|
||||
let event = Event(
|
||||
eventType: CLIENT_LOOT_SYNC,
|
||||
timestamp: now().toTime().toUnix(),
|
||||
data: %*{
|
||||
"lootId": lootId
|
||||
}
|
||||
)
|
||||
connection.ws.sendEvent(event, connection.sessionKey)
|
||||
@@ -157,10 +157,18 @@ proc main(ip: string = "localhost", port: int = 37573) =
|
||||
lootDownloads.items.add(lootItem)
|
||||
of SCREENSHOT:
|
||||
lootScreenshots.addItem(lootItem)
|
||||
|
||||
else: discard
|
||||
|
||||
of CLIENT_SYNC_LOOT:
|
||||
of CLIENT_LOOT_SYNC:
|
||||
let path = event.data["path"].getStr()
|
||||
let file = decode(event.data["loot"].getStr())
|
||||
try:
|
||||
# TODO: Using native file dialogs to have the client select the output file path (does not work in WSL)
|
||||
# let outFilePath = callDialogFileSave("Save Payload")
|
||||
writeFile(path & "_download", file)
|
||||
except IOError:
|
||||
discard
|
||||
|
||||
discard
|
||||
|
||||
else: discard
|
||||
@@ -169,8 +177,8 @@ proc main(ip: string = "localhost", port: int = 37573) =
|
||||
if showSessionsTable: sessionsTable.draw(addr showSessionsTable)
|
||||
if showListeners: listenersTable.draw(addr showListeners, connection)
|
||||
if showEventlog: eventlog.draw(addr showEventlog)
|
||||
if showDownloads: lootDownloads.draw(addr showDownloads)
|
||||
if showScreenshots: lootScreenshots.draw(addr showScreenshots)
|
||||
if showDownloads: lootDownloads.draw(addr showDownloads, connection)
|
||||
if showScreenshots: lootScreenshots.draw(addr showScreenshots, connection)
|
||||
|
||||
# Show console windows
|
||||
var newConsoleTable: Table[string, ConsoleComponent]
|
||||
|
||||
@@ -3,7 +3,7 @@ import ../utils/fonticon/IconsFontAwesome6
|
||||
const CONQUEST_ROOT* {.strdefine.} = ""
|
||||
|
||||
const WIDGET_SESSIONS* = " " & ICON_FA_LIST & " " & "Sessions [Table View]"
|
||||
const WIDGET_LISTENERS* = " " & ICON_FA_HEADPHONES & " " & "Listeners"
|
||||
const WIDGET_LISTENERS* = " " & ICON_FA_SATELLITE_DISH & " " & "Listeners"
|
||||
const WIDGET_EVENTLOG* = "Eventlog"
|
||||
const WIDGET_DOWNLOADS* = " " & ICON_FA_DOWNLOAD & " " & "Downloads"
|
||||
const WIDGET_SCREENSHOTS* = " " & ICON_FA_IMAGE & " " & "Screenshots"
|
||||
|
||||
@@ -2,6 +2,7 @@ import strformat, strutils, times, os
|
||||
import imguin/[cimgui, glfw_opengl, simple]
|
||||
import ../../utils/[appImGui, colors]
|
||||
import ../../../common/[types, utils]
|
||||
import ../../core/websocket
|
||||
|
||||
type
|
||||
DownloadsComponent* = ref object of RootObj
|
||||
@@ -16,7 +17,7 @@ proc LootDownloads*(title: string): DownloadsComponent =
|
||||
result.items = @[]
|
||||
result.selectedIndex = -1
|
||||
|
||||
proc draw*(component: DownloadsComponent, showComponent: ptr bool) =
|
||||
proc draw*(component: DownloadsComponent, showComponent: ptr bool, connection: WsConnection) =
|
||||
igBegin(component.title, showComponent, 0)
|
||||
defer: igEnd()
|
||||
|
||||
@@ -61,7 +62,11 @@ proc draw*(component: DownloadsComponent, showComponent: ptr bool) =
|
||||
let isSelected = component.selectedIndex == i
|
||||
if igSelectable_Bool(item.lootId.cstring, isSelected, ImGuiSelectableFlags_SpanAllColumns.int32 or ImGuiSelectableFlags_AllowOverlap.int32, vec2(0, 0)):
|
||||
component.selectedIndex = i
|
||||
igPopID()
|
||||
|
||||
if igIsItemHovered(ImGuiHoveredFlags_None.int32) and igIsMouseClicked_Bool(ImGuiMouseButton_Right.int32, false):
|
||||
component.selectedIndex = i
|
||||
|
||||
igPopID()
|
||||
|
||||
if igTableSetColumnIndex(1):
|
||||
igText(item.agentId)
|
||||
@@ -78,6 +83,23 @@ proc draw*(component: DownloadsComponent, showComponent: ptr bool) =
|
||||
if igTableSetColumnIndex(5):
|
||||
igText($item.size)
|
||||
|
||||
# Handle right-click context menu
|
||||
if component.selectedIndex >= 0 and component.selectedIndex < component.items.len and igBeginPopupContextWindow("Downloads", ImGui_PopupFlags_MouseButtonRight.int32):
|
||||
let item = component.items[component.selectedIndex]
|
||||
|
||||
if igMenuItem("Download", nil, false, true):
|
||||
# Task team server to download file
|
||||
connection.sendDownloadLoot(item.lootId)
|
||||
igCloseCurrentPopup()
|
||||
|
||||
if igMenuItem("Remove", nil, false, true):
|
||||
# Task team server to remove the loot item
|
||||
connection.sendRemoveLoot(item.lootId)
|
||||
component.items.delete(component.selectedIndex)
|
||||
igCloseCurrentPopup()
|
||||
|
||||
igEndPopup()
|
||||
|
||||
igEndTable()
|
||||
|
||||
igEndChild()
|
||||
@@ -93,9 +115,11 @@ proc draw*(component: DownloadsComponent, showComponent: ptr bool) =
|
||||
igSameLine(0.0f, 0.0f)
|
||||
igText(item.path.extractFilename().replace("C_", "C:/").replace("_", "/"))
|
||||
|
||||
igDummy(vec2(0.0f, 5.0f))
|
||||
igSeparator()
|
||||
|
||||
igText(item.data)
|
||||
igDummy(vec2(0.0f, 5.0f))
|
||||
|
||||
igTextUnformatted(item.data, nil)
|
||||
|
||||
else:
|
||||
igText("Select item to preview contents")
|
||||
|
||||
@@ -2,6 +2,7 @@ import strformat, strutils, times, os, tables
|
||||
import imguin/[cimgui, glfw_opengl, simple]
|
||||
import ../../utils/[appImGui, colors]
|
||||
import ../../../common/[types, utils]
|
||||
import ../../core/websocket
|
||||
|
||||
type
|
||||
ScreenshotTexture* = ref object
|
||||
@@ -33,7 +34,7 @@ proc addItem*(component: ScreenshotsComponent, screenshot: LootItem) =
|
||||
height: height
|
||||
)
|
||||
|
||||
proc draw*(component: ScreenshotsComponent, showComponent: ptr bool) =
|
||||
proc draw*(component: ScreenshotsComponent, showComponent: ptr bool, connection: WsConnection) =
|
||||
igBegin(component.title, showComponent, 0)
|
||||
defer: igEnd()
|
||||
|
||||
@@ -43,7 +44,7 @@ proc draw*(component: ScreenshotsComponent, showComponent: ptr bool) =
|
||||
|
||||
# Left panel (file table)
|
||||
let childFlags = ImGui_ChildFlags_ResizeX.int32 or ImGui_ChildFlags_NavFlattened.int32
|
||||
if igBeginChild_Str("##Left", vec2(availableSize.x * 0.66f, 0.0f), childFlags, ImGui_WindowFlags_None.int32):
|
||||
if igBeginChild_Str("##Left", vec2(availableSize.x * 0.5f, 0.0f), childFlags, ImGui_WindowFlags_None.int32):
|
||||
|
||||
let tableFlags = (
|
||||
ImGui_TableFlags_Resizable.int32 or
|
||||
@@ -77,6 +78,10 @@ proc draw*(component: ScreenshotsComponent, showComponent: ptr bool) =
|
||||
let isSelected = component.selectedIndex == i
|
||||
if igSelectable_Bool(item.lootId.cstring, isSelected, ImGuiSelectableFlags_SpanAllColumns.int32 or ImGuiSelectableFlags_AllowOverlap.int32, vec2(0, 0)):
|
||||
component.selectedIndex = i
|
||||
|
||||
if igIsItemHovered(ImGuiHoveredFlags_None.int32) and igIsMouseClicked_Bool(ImGuiMouseButton_Right.int32, false):
|
||||
component.selectedIndex = i
|
||||
|
||||
igPopID()
|
||||
|
||||
if igTableSetColumnIndex(1):
|
||||
@@ -91,6 +96,23 @@ proc draw*(component: ScreenshotsComponent, showComponent: ptr bool) =
|
||||
if igTableSetColumnIndex(4):
|
||||
igText($item.size)
|
||||
|
||||
# Handle right-click context menu
|
||||
if component.selectedIndex >= 0 and component.selectedIndex < component.items.len and igBeginPopupContextWindow("Downloads", ImGui_PopupFlags_MouseButtonRight.int32):
|
||||
let item = component.items[component.selectedIndex]
|
||||
|
||||
if igMenuItem("Download", nil, false, true):
|
||||
# Task team server to download file
|
||||
connection.sendDownloadLoot(item.lootId)
|
||||
igCloseCurrentPopup()
|
||||
|
||||
if igMenuItem("Remove", nil, false, true):
|
||||
# Task team server to remove the loot item
|
||||
connection.sendRemoveLoot(item.lootId)
|
||||
component.items.delete(component.selectedIndex)
|
||||
igCloseCurrentPopup()
|
||||
|
||||
igEndPopup()
|
||||
|
||||
igEndTable()
|
||||
|
||||
igEndChild()
|
||||
@@ -106,5 +128,5 @@ proc draw*(component: ScreenshotsComponent, showComponent: ptr bool) =
|
||||
igImage(ImTextureRef(internal_TexData: nil, internal_TexID: texture.textureId), vec2(texture.width, texture.height), vec2(0, 0), vec2(1, 1))
|
||||
|
||||
else:
|
||||
igText("Select item to preview contents")
|
||||
igText("Select item for preview.")
|
||||
igEndChild()
|
||||
Reference in New Issue
Block a user