local m_enabled = menu.Switch("Main", "Enabled", false)
local m_outline = menu.Switch("Main", "Outline", false)
local m_gradient_type = menu.Combo("Main", "Gradient type", { "Off", "Fade", "Multi color" }, 0)
local m_background_color = menu.ColorEdit("Colors", "Background color", Color.new(0.0, 0.0, 0.0))
local m_header_color = menu.ColorEdit("Colors", "Header color", Color.new(1.0, 1.0, 1.0))
local m_first_gradient_color = menu.ColorEdit("Colors", "First gradient color", Color.new(1.0, 1.0, 1.0))
local m_second_gradient_color = menu.ColorEdit("Colors", "Second gradient color", Color.new(1.0, 1.0, 1.0))
local m_third_gradient_color = menu.ColorEdit("Colors", "Third gradient color", Color.new(1.0, 1.0, 1.0))
local g_VerdanaFont = g_Render:InitFont("Verdana", 13)
local g_Players = { }
local g_Positions = {
spectators = {
x = menu.SliderInt("Positions", "Spectators: X", 10, 0, 4096),
y = menu.SliderInt("Positions", "Spectators: Y", 10, 0, 4096)
}
}
for k, v in pairs (g_Positions) do
for key, value in pairs (v) do
value:SetVisible(false)
end
end
local g_WindowsOptions = {
[0] = {
["name"] = "spectators",
["position"] = Vector2.new(20, 20),
["size"] = Vector2.new(50, 17),
["items_distance"] = 16,
["item_size"] = 16,
["dragging"] = false,
["buffer"] = { }
},
[1] = {
["dragging"] = false
}
}
local getSteamId64 = function (steamid)
return string.sub(tostring(ffi.new("uint64_t", 76561197960265728) + ffi.new("uint64_t", steamid)), 1, -4)
end
local getWindowItemBox = function (id, element)
local windowOptions = g_WindowsOptions[id]
local windowNameSize = g_Render:CalcTextSize(windowOptions.name, 13, g_VerdanaFont)
return {
[0] = Vector2.new(windowOptions.position.x, windowOptions.position.y + windowOptions.size.y + 6.0 + ((windowOptions.items_distance * element) - 20.0)),
[1] = Vector2.new(windowOptions.position.x + windowOptions.size.x + windowNameSize.x, windowOptions.position.y + windowOptions.size.y + 2.0 + ((windowOptions.items_distance * element) - 20.0) + windowOptions.item_size)
}
end
local drawWindow = function (id)
local windowOptions = g_WindowsOptions[id]
local windowNameSize = g_Render:CalcTextSize(windowOptions.name, 13, g_VerdanaFont)
g_Render:BoxFilled(windowOptions.position, Vector2.new(windowOptions.position.x + windowNameSize.x + windowOptions.size.x, windowOptions.position.y + windowOptions.size.y), m_background_color:GetColor())
if (m_gradient_type:GetInt() == 0) then
g_Render:BoxFilled(windowOptions.position - Vector2.new(0.0, 1.0), Vector2.new(windowOptions.position.x + windowNameSize.x + windowOptions.size.x, windowOptions.position.y), m_header_color:GetColor())
else
if (m_gradient_type:GetInt() == 1) then
g_Render:GradientBoxFilled(windowOptions.position - Vector2.new(0.0, 1.0), windowOptions.position + Vector2.new( ( (windowNameSize.x + windowOptions.size.x) / 2 ), 1.0), Color.new(m_header_color:GetColor():r(), m_header_color:GetColor():g(), m_header_color:GetColor():b(), 0.1), m_header_color:GetColor(), Color.new(m_header_color:GetColor():r(), m_header_color:GetColor():g(), m_header_color:GetColor():b(), 0.1), m_header_color:GetColor())
g_Render:GradientBoxFilled(windowOptions.position + Vector2.new( ( (windowNameSize.x + windowOptions.size.x) / 2 ), -1.0), Vector2.new(windowOptions.position.x + windowNameSize.x + windowOptions.size.x, windowOptions.position.y + 1), m_header_color:GetColor(), Color.new(m_header_color:GetColor():r(), m_header_color:GetColor():g(), m_header_color:GetColor():b(), 0.1), m_header_color:GetColor(), Color.new(m_header_color:GetColor():r(), m_header_color:GetColor():g(), m_header_color:GetColor():b(), 0.1))
else
g_Render:GradientBoxFilled(windowOptions.position - Vector2.new(0.0, 1.0), windowOptions.position + Vector2.new( ( (windowNameSize.x + windowOptions.size.x) / 2 ), 1.0), m_first_gradient_color:GetColor(), m_second_gradient_color:GetColor(), m_first_gradient_color:GetColor(), m_second_gradient_color:GetColor())
g_Render:GradientBoxFilled(windowOptions.position + Vector2.new( ( (windowNameSize.x + windowOptions.size.x) / 2 ), -1.0), Vector2.new(windowOptions.position.x + windowNameSize.x + windowOptions.size.x, windowOptions.position.y + 1), m_second_gradient_color:GetColor(), m_third_gradient_color:GetColor(), m_second_gradient_color:GetColor(), m_third_gradient_color:GetColor())
end
end
g_Render:Text(windowOptions.name, (windowOptions.position + Vector2.new( ( (windowNameSize.x + windowOptions.size.x) / 2 ), windowOptions.size.y / 2)) - Vector2.new(windowNameSize.x / 2, windowNameSize.y / 2), Color.new(1.0, 1.0, 1.0), 13, g_VerdanaFont, m_outline:GetBool())
local mousePosition = cheat.GetMousePos()
local isKeyPressed = cheat.IsKeyDown(0x1)
for k, v in pairs (g_WindowsOptions) do
if v.dragging and k ~= id then return end
end
if isKeyPressed and cheat.IsMenuVisible() then
if not g_WindowsOptions[id].dragging then
if ( mousePosition.x >= windowOptions.position.x and mousePosition.x <= (windowOptions.position.x + windowNameSize.x + windowOptions.size.x) and
mousePosition.y >= windowOptions.position.y and mousePosition.y <= (windowOptions.position.y + windowOptions.size.y) ) then
g_WindowsOptions[id].dragging = true
end
else
if id == 0 then
g_Positions.spectators.x:SetInt(math.floor(mousePosition.x - ((windowNameSize.x + windowOptions.size.x) / 2)))
g_Positions.spectators.y:SetInt(math.floor(mousePosition.y - (windowOptions.size.y / 2)))
else
if id == 1 then
g_Positions.keybinds.x:SetInt(math.floor(mousePosition.x - ((windowNameSize.x + windowOptions.size.x) / 2)))
g_Positions.keybinds.y:SetInt(math.floor(mousePosition.y - (windowOptions.size.y / 2)))
end
end
end
else
g_WindowsOptions[id].dragging = false
end
end
local getPlayerSpectators = function(player)
local buffer = { }
local players = g_EntityList:GetPlayers()
for table_index, player_pointer in pairs(players) do
if player_pointer:EntIndex() ~= player:EntIndex() then
if (player_pointer:GetProp("DT_BasePlayer", "m_lifeState") == true and player_pointer:GetProp("m_iHealth") <= 1) then
local spectatingMode = player_pointer:GetProp("DT_BasePlayer", "m_iObserverMode")
local spectatingPlayer = player_pointer:GetProp("DT_BasePlayer", "m_hObserverTarget")
if spectatingPlayer then
if spectatingMode >= 4 or spectatingMode <= 5 then
local spectatingEntity = g_EntityList:GetClientEntityFromHandle(spectatingPlayer)
if spectatingEntity ~= nil and spectatingEntity:EntIndex() == player:EntIndex() then
local player_info = g_EngineClient:GetPlayerInfo(player_pointer:EntIndex())
if not player_info.fakeplayer then
table.insert(buffer, {
["id"] = player_info.iSteamID,
["id64"] = getSteamId64(player_info.iSteamID),
["name"] = string.len(player_pointer:GetName()) > 12 and string.sub(player_pointer:GetName(), 0, 12) .. "." or player_pointer:GetName()
})
end
end
end
end
end
end
end
return buffer
end
local getSpectators = function ()
local local_player = g_EntityList:GetClientEntity(g_EngineClient:GetLocalPlayer())
if not local_player then return { } end
if (local_player:GetProp("DT_BasePlayer", "m_lifeState") == false) then
return getPlayerSpectators(local_player:GetPlayer())
else
local m_hObserverTarget = local_player:GetProp("DT_BasePlayer", "m_hObserverTarget")
if m_hObserverTarget then
local targetEntity = g_EntityList:GetClientEntityFromHandle(m_hObserverTarget)
if targetEntity ~= nil then
return getPlayerSpectators(targetEntity:GetPlayer())
end
end
end
end
local loadImages = function ()
local players = g_EntityList:GetPlayers()
for table_index, player_pointer in pairs(players) do
local player_info = g_EngineClient:GetPlayerInfo(player_pointer:EntIndex())
if not player_info.fakeplayer then
if g_Players[player_info.iSteamID] == nil then
g_Players[player_info.iSteamID] = {
["downloaded"] = false,
["image"] = nil
}
http.GetAsync("https://www.kibbewater.xyz/interium/getavatar?steamid=" .. getSteamId64(player_info.iSteamID), function(response)
local image = g_Render:LoadImage(response, Vector2.new(12, 12))
g_Players[player_info.iSteamID].downloaded = true
g_Players[player_info.iSteamID].image = image
end)
else
if g_Players[player_info.iSteamID].downloaded and g_Players[player_info.iSteamID].image == nil then
http.GetAsync("https://www.kibbewater.xyz/interium/getavatar?steamid=" .. getSteamId64(player_info.iSteamID), function(response)
local image = g_Render:LoadImage(response, Vector2.new(12, 12))
g_Players[player_info.iSteamID].downloaded = true
g_Players[player_info.iSteamID].image = image
end)
end
end
end
end
end
cheat.RegisterCallback("draw", function()
loadImages()
if m_enabled:GetBool() then
g_WindowsOptions[0].position = Vector2.new(g_Positions.spectators.x:GetInt(), g_Positions.spectators.y:GetInt())
local spectators = getSpectators()
if spectators ~= nil or cheat.IsMenuVisible() then
drawWindow(0)
if spectators ~= nil then
local currentIndex = 1
for k, v in pairs(spectators) do
if g_Players[v.id].downloaded then
local spectatorBox = getWindowItemBox(0, currentIndex)
g_Render:Image(g_Players[v.id].image, spectatorBox[0] + Vector2.new(2.0, (((spectatorBox[1].y - spectatorBox[0].y) - 12) / 2)), Vector2.new(12, 12))
local name_size = g_Render:CalcTextSize(v.name, 12)
g_Render:Text(v.name, Vector2.new(spectatorBox[1].x - name_size.x - 2.0, spectatorBox[0].y + (((spectatorBox[1].y - spectatorBox[0].y) / 2) - (name_size.y / 2)) ), Color.new(1.0, 1.0, 1.0), 12)
currentIndex = currentIndex + 1
end
end
end
end
end
end)
local updateColors = function()
if m_gradient_type:GetInt() == 2 then
m_header_color:SetVisible(false)
m_first_gradient_color:SetVisible(true)
m_second_gradient_color:SetVisible(true)
m_third_gradient_color:SetVisible(true)
else
m_first_gradient_color:SetVisible(false)
m_second_gradient_color:SetVisible(false)
m_third_gradient_color:SetVisible(false)
m_header_color:SetVisible(true)
end
end
m_gradient_type:RegisterCallback(updateColors)
updateColors()