1. local Players = game:GetService("Players")
  2. local CoreGui = game:GetService("CoreGui")
  3.  
  4. local LocalPlayer = Players.LocalPlayer
  5. local LocalDrawingCanvas = nil
  6.  
  7. local BotConfig = {
  8. Enabled = false,
  9. ImageURL = "",
  10. }
  11.  
  12. -- Variables for libraries
  13. local Unfilter, BinaryReader, Deflate
  14. local chunks = {}
  15. local PNG = {}
  16. PNG.__index = PNG
  17.  
  18. ---------------------------------------------------------------------------------------------
  19. -- [1. GUI INTERFACE]
  20. ---------------------------------------------------------------------------------------------
  21. local ScreenGui = Instance.new("ScreenGui")
  22. ScreenGui.Name = "DrawAndDonateAutoDraw"
  23. ScreenGui.ResetOnSpawn = false
  24. pcall(function() ScreenGui.Parent = CoreGui end)
  25. if not ScreenGui.Parent then ScreenGui.Parent = LocalPlayer:WaitForChild("PlayerGui") end
  26.  
  27. local MainFrame = Instance.new("Frame")
  28. MainFrame.Size = UDim2.new(0, 250, 0, 220) -- Reduced height since button is removed
  29. MainFrame.Position = UDim2.new(0.05, 0, 0.3, 0)
  30. MainFrame.BackgroundColor3 = Color3.fromRGB(24, 24, 28)
  31. MainFrame.BorderSizePixel = 0
  32. MainFrame.Active = true
  33. MainFrame.Draggable = true
  34. MainFrame.Parent = ScreenGui
  35.  
  36. local UICorner = Instance.new("UICorner")
  37. UICorner.CornerRadius = UDim.new(0, 2) -- More rigid corners
  38. UICorner.Parent = MainFrame
  39.  
  40. local Title = Instance.new("TextLabel")
  41. Title.Size = UDim2.new(1, 0, 0, 40)
  42. Title.Text = "Draw & Donate Auto Draw"
  43. Title.TextColor3 = Color3.fromRGB(255, 255, 255)
  44. Title.BackgroundColor3 = Color3.fromRGB(34, 34, 40)
  45. Title.Font = Enum.Font.SourceSans -- Less bold
  46. Title.TextSize = 14
  47. Title.Parent = MainFrame
  48.  
  49. local UTCorner = Instance.new("UICorner")
  50. UTCorner.CornerRadius = UDim.new(0, 2)
  51. UTCorner.Parent = Title
  52.  
  53. local function CreateButton(text, yPos, callback)
  54. local Btn = Instance.new("TextButton")
  55. Btn.Size = UDim2.new(1, -20, 0, 35)
  56. Btn.Position = UDim2.new(0, 10, 0, yPos)
  57. Btn.Text = text
  58. Btn.TextColor3 = Color3.fromRGB(240, 240, 240)
  59. Btn.BackgroundColor3 = Color3.fromRGB(44, 44, 52)
  60. Btn.Font = Enum.Font.SourceSans -- Less bold
  61. Btn.TextSize = 14
  62. Btn.Parent = MainFrame
  63. local c = Instance.new("UICorner")
  64. c.CornerRadius = UDim.new(0, 2) -- More rigid corners
  65. c.Parent = Btn
  66. Btn.MouseButton1Click:Connect(callback)
  67. return Btn
  68. end
  69.  
  70. local ToggleBtn = CreateButton("LOADING...", 50, function() end)
  71. ToggleBtn.BackgroundColor3 = Color3.fromRGB(70, 70, 75)
  72. ToggleBtn.AutoButtonColor = false
  73.  
  74. local TextBox = Instance.new("TextBox")
  75. TextBox.Size = UDim2.new(1, -20, 0, 30)
  76. TextBox.Position = UDim2.new(0, 10, 0, 95)
  77. TextBox.Text = "Insert direct .png URL link"
  78. TextBox.TextColor3 = Color3.fromRGB(200, 200, 200)
  79. TextBox.BackgroundColor3 = Color3.fromRGB(30, 30, 36)
  80. TextBox.Font = Enum.Font.SourceSans
  81. TextBox.TextSize = 12
  82. TextBox.TextWrapped = true
  83. TextBox.ClearTextOnFocus = false
  84. TextBox.Parent = MainFrame
  85. local BoxCorner = Instance.new("UICorner")
  86. BoxCorner.CornerRadius = UDim.new(0, 2)
  87. BoxCorner.Parent = TextBox
  88. TextBox.FocusLost:Connect(function(ep) if ep then BotConfig.ImageURL = TextBox.Text end end)
  89.  
  90. local StatusLabel = Instance.new("TextLabel")
  91. StatusLabel.Size = UDim2.new(1, -20, 0, 40)
  92. StatusLabel.Position = UDim2.new(0, 10, 0, 130)
  93. StatusLabel.Text = "Status: Loading GitHub libraries..."
  94. StatusLabel.TextColor3 = Color3.fromRGB(255, 165, 0)
  95. StatusLabel.BackgroundTransparency = 1
  96. StatusLabel.Font = Enum.Font.SourceSans
  97. StatusLabel.TextSize = 13
  98. StatusLabel.TextWrapped = true
  99. StatusLabel.Parent = MainFrame
  100.  
  101. local AuthorLabel = Instance.new("TextLabel")
  102. AuthorLabel.Size = UDim2.new(1, -20, 0, 20)
  103. AuthorLabel.Position = UDim2.new(0, 10, 0, 175)
  104. AuthorLabel.Text = "Author:@RoogleCreator"
  105. AuthorLabel.TextColor3 = Color3.fromRGB(150, 150, 150)
  106. AuthorLabel.BackgroundTransparency = 1
  107. AuthorLabel.Font = Enum.Font.SourceSans
  108. AuthorLabel.TextSize = 12
  109. AuthorLabel.Parent = MainFrame
  110.  
  111. local ProgressBarBg = Instance.new("Frame")
  112. ProgressBarBg.Size = UDim2.new(1, -20, 0, 6)
  113. ProgressBarBg.Position = UDim2.new(0, 10, 0, 200)
  114. ProgressBarBg.BackgroundColor3 = Color3.fromRGB(45, 45, 55)
  115. ProgressBarBg.BorderSizePixel = 0
  116. ProgressBarBg.Parent = MainFrame
  117. local ProgressBarFill = Instance.new("Frame")
  118. ProgressBarFill.Size = UDim2.new(0, 0, 1, 0)
  119. ProgressBarFill.BackgroundColor3 = Color3.fromRGB(0, 255, 150)
  120. ProgressBarFill.BorderSizePixel = 0
  121. ProgressBarFill.Parent = ProgressBarBg
  122.  
  123. ---------------------------------------------------------------------------------------------
  124. -- [2. OPTIMIZED PNG PARSER FUNCTIONS]
  125. ---------------------------------------------------------------------------------------------
  126. local function getBytesPerPixel(colorType)
  127. if colorType == 0 or colorType == 3 then return 1
  128. elseif colorType == 4 then return 2
  129. elseif colorType == 2 then return 3
  130. elseif colorType == 6 then return 4
  131. else return 0 end
  132. end
  133.  
  134. local function clampInt(value, min, max)
  135. local num = tonumber(value) or 0
  136. num = math.floor(num + 0.5)
  137. return math.clamp(num, min, max)
  138. end
  139.  
  140. local function indexBitmap(file, x, y)
  141. local width = file.Width
  142. local height = file.Height
  143. x = clampInt(x, 1, width)
  144. y = clampInt(y, 1, height)
  145. local bitmap = file.Bitmap
  146. local bpp = file.BytesPerPixel
  147. local i0 = ((x - 1) * bpp) + 1
  148. local i1 = i0 + bpp
  149. return bitmap[y], i0, i1
  150. end
  151.  
  152. function PNG:GetPixel(x, y)
  153. local row, i0, i1 = indexBitmap(self, x, y)
  154. if not row then return Color3.new(1,1,1), 0 end
  155. local colorType = self.ColorType
  156. local color, alpha
  157.  
  158. if colorType == 0 then
  159. local gray = unpack(row, i0, i1)
  160. color = Color3.fromHSV(0, 0, gray or 0)
  161. alpha = 255
  162. elseif colorType == 2 then
  163. local r, g, b = unpack(row, i0, i1)
  164. color = Color3.fromRGB(r or 0, g or 0, b or 0)
  165. alpha = 255
  166. elseif colorType == 3 then
  167. local palette = self.Palette
  168. local alphaData = self.AlphaData
  169. local index = unpack(row, i0, i1)
  170. index = (index or 0) + 1
  171. if palette then color = palette[index] end
  172. if alphaData then alpha = alphaData[index] end
  173. elseif colorType == 4 then
  174. local gray, a = unpack(row, i0, i1)
  175. color = Color3.fromHSV(0, 0, gray or 0)
  176. alpha = a
  177. elseif colorType == 6 then
  178. local r, g, b, a = unpack(row, i0, i1)
  179. color = Color3.fromRGB(r or 0, g or 0, b or 0)
  180. alpha = a
  181. end
  182.  
  183. if not color then color = Color3.new(1, 1, 1) end
  184. if not alpha then alpha = 255 end
  185. return color, alpha
  186. end
  187.  
  188. function PNG.new(buffer)
  189. local reader = BinaryReader.new(buffer)
  190. local file = { Chunks = {}, Metadata = {}, Reading = true, ZlibStream = "" }
  191. local header = reader:ReadString(8)
  192. if header ~= "\137PNG\r\n\26\n" then error("PNG - Input data is not a PNG file.", 2) end
  193.  
  194. while file.Reading do
  195. local length = reader:ReadInt32()
  196. local chunkType = reader:ReadString(4)
  197. local data, crc
  198. if length > 0 then
  199. data = reader:ForkReader(length)
  200. crc = reader:ReadUInt32()
  201. end
  202. local chunk = { Length = length, Type = chunkType, Data = data, CRC = crc }
  203. local handler = chunks[chunkType]
  204. if handler then handler(file, chunk) end
  205. table.insert(file.Chunks, chunk)
  206. end
  207.  
  208. -- ANTI-CRASH INFLATE UNPACK MODIFICATION
  209. local success, response = pcall(function()
  210. local result = {}
  211. local index = 0
  212.  
  213. Deflate:InflateZlib({
  214. Input = BinaryReader.new(file.ZlibStream),
  215. Output = function(byte)
  216. index = index + 1
  217. result[index] = string.char(byte)
  218.  
  219. -- Every 40000 unpacked bytes, yield to let the Roblox engine breathe
  220. if index % 40000 == 0 then
  221. task.wait()
  222. end
  223. end
  224. })
  225. return table.concat(result)
  226. end)
  227.  
  228. if not success then error("PNG - Unable to unpack PNG data. " .. tostring(response), 2) end
  229.  
  230. local width = file.Width
  231. local height = file.Height
  232. local bitDepth = file.BitDepth
  233. local colorType = file.ColorType
  234. local buffer = BinaryReader.new(response)
  235. file.ZlibStream = nil
  236. local bitmap = {}
  237. file.Bitmap = bitmap
  238. local channels = getBytesPerPixel(colorType)
  239. file.NumChannels = channels
  240. local bpp = math.max(1, channels * (bitDepth / 8))
  241. file.BytesPerPixel = bpp
  242.  
  243. for row = 1, height do
  244. -- Smooth scanline reading
  245. if row % 2 == 0 then task.wait() end
  246. local filterType = buffer:ReadByte()
  247. local scanline = buffer:ReadBytes(width * bpp, true)
  248. bitmap[row] = {}
  249.  
  250. if filterType == 0 then Unfilter:None(scanline, bitmap, bpp, row)
  251. elseif filterType == 1 then Unfilter:Sub(scanline, bitmap, bpp, row)
  252. elseif filterType == 2 then Unfilter:Up(scanline, bitmap, bpp, row)
  253. elseif filterType == 3 then Unfilter:Average(scanline, bitmap, bpp, row)
  254. elseif filterType == 4 then Unfilter:Paeth(scanline, bitmap, bpp, row) end
  255. end
  256. return setmetatable(file, PNG)
  257. end
  258.  
  259. ---------------------------------------------------------------------------------------------
  260. -- [3. ASYNCHRONOUS MODULE DOWNLOADING]
  261. ---------------------------------------------------------------------------------------------
  262. task.spawn(function()
  263. getfenv().bit32 = bit
  264.  
  265. local function secureGet(url)
  266. local s, r = pcall(function() return game:HttpGet(url) end)
  267. if s then return loadstring(r)() else return nil end
  268. end
  269.  
  270.  
  271.  
  272. if Unfilter and BinaryReader and Deflate and chunks.IDAT and chunks.IHDR then
  273. StatusLabel.Text = "Status: Modules active! Ready to draw."
  274. StatusLabel.TextColor3 = Color3.fromRGB(0, 200, 100)
  275. ToggleBtn.Text = "START"
  276. ToggleBtn.BackgroundColor3 = Color3.fromRGB(40, 150, 80)
  277. ToggleBtn.AutoButtonColor = true
  278. else
  279. StatusLabel.Text = "Error: GitHub load failed!"
  280. StatusLabel.TextColor3 = Color3.fromRGB(255, 50, 50)
  281. ToggleBtn.Text = "NETWORK ERROR"
  282. end
  283. end)
  284.  
  285. ---------------------------------------------------------------------------------------------
  286. -- [4. CANVAS SEARCH AND VALIDATION]
  287. ---------------------------------------------------------------------------------------------
  288. local function FindLocalDrawingCanvas()
  289. local playerGui = LocalPlayer:FindFirstChild("PlayerGui")
  290. if not playerGui then return nil end
  291. local canvasFrame = nil
  292. for _, v in ipairs(playerGui:GetDescendants()) do
  293. if v:IsA("Frame") and v:FindFirstChild("FastCanvas") then canvasFrame = v break end
  294. end
  295. if not canvasFrame then return nil end
  296.  
  297. local successGC, registry = pcall(getgc, true)
  298. if successGC then
  299. for i = 1, #registry do
  300. local obj = registry[i]
  301. if type(obj) == "table" and rawget(obj, "DrawLine") then
  302. if rawget(obj, "CurrentCanvasFrame") == canvasFrame or tostring(rawget(obj, "CurrentCanvasFrame")) == tostring(canvasFrame) then
  303. return obj
  304. end
  305. end
  306. end
  307. end
  308. return nil
  309. end
  310.  
  311. local drawingThread = nil
  312.  
  313. ToggleBtn.MouseButton1Click:Connect(function()
  314. if not Deflate then return end
  315.  
  316. if BotConfig.Enabled then
  317. BotConfig.Enabled = false
  318. ToggleBtn.Text = "START"
  319. ToggleBtn.BackgroundColor3 = Color3.fromRGB(40, 150, 80)
  320. if drawingThread then task.cancel(drawingThread) end
  321. StatusLabel.Text = "Stopped."
  322. ProgressBarFill.Size = UDim2.new(0, 0, 1, 0)
  323. else
  324. LocalDrawingCanvas = FindLocalDrawingCanvas()
  325. if not LocalDrawingCanvas then StatusLabel.Text = "Error: Open the canvas!" return end
  326. if BotConfig.ImageURL == "" or not string.match(BotConfig.ImageURL, "http") then StatusLabel.Text = "Error: No working URL link!" return end
  327.  
  328. BotConfig.Enabled = true
  329. ToggleBtn.Text = "STOP"
  330. ToggleBtn.BackgroundColor3 = Color3.fromRGB(170, 40, 40)
  331.  
  332. drawingThread = task.spawn(function()
  333. StatusLabel.Text = "Downloading .png..."
  334. local successFetch, resultBuffer = pcall(function() return game:HttpGet(BotConfig.ImageURL) end)
  335. if not successFetch then StatusLabel.Text = "HTTP download error!" BotConfig.Enabled = false ToggleBtn.Text = "START" return end
  336.  
  337. StatusLabel.Text = "Unpacking PNG (Anti-lag)..."
  338. task.wait() -- Yield a frame before heavy parsing
  339.  
  340. local successPng, pngImage = pcall(function() return PNG.new(resultBuffer) end)
  341. if not successPng or not pngImage then
  342. StatusLabel.Text = "Decompression error! File too large or corrupted."
  343. BotConfig.Enabled = false ToggleBtn.Text = "START" return
  344. end
  345.  
  346. local resX = tonumber(LocalDrawingCanvas.CurrentResX or 150)
  347. local resY = tonumber(LocalDrawingCanvas.CurrentResY or 150)
  348.  
  349. StatusLabel.Text = "Drawing on canvas..."
  350.  
  351. for y = 1, resY do
  352. if not BotConfig.Enabled then return end
  353.  
  354. for x = 1, resX do
  355. local srcX = math.clamp(math.floor((x / resX) * pngImage.Width), 1, pngImage.Width)
  356. local srcY = math.clamp(math.floor((y / resY) * pngImage.Height), 1, pngImage.Height)
  357.  
  358. local color, alpha = pngImage:GetPixel(srcX, srcY)
  359.  
  360. if alpha > 15 then
  361. local pPos = Vector2.new(x, y)
  362. LocalDrawingCanvas:DrawLine(pPos, pPos, color, 1)
  363. end
  364. end
  365.  
  366. ProgressBarFill.Size = UDim2.new(y / resY, 0, 1, 0)
  367.  
  368. if y % 3 == 0 then
  369. if LocalDrawingCanvas.Render then LocalDrawingCanvas:Render() end
  370. task.wait()
  371. end
  372. end
  373.  
  374. if LocalDrawingCanvas.Render then LocalDrawingCanvas:Render() end
  375. StatusLabel.Text = "Done!"
  376. BotConfig.Enabled = false
  377. ToggleBtn.Text = "START"
  378. ToggleBtn.BackgroundColor3 = Color3.fromRGB(40, 150, 80)
  379. end)
  380. end
  381. end)