Created
July 26, 2026 01:01
-
-
Save DuyNgao2306/6fb2dc28efb3b3903d5c8d7fd4f0b94c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- [[ VISUAL AUTO CLICKER - FINAL MASTER PATCHED EDITION ]] -- | |
| local Players = game:GetService("Players") | |
| local UserInputService = game:GetService("UserInputService") | |
| local VirtualInputManager = game:GetService("VirtualInputManager") | |
| local HttpService = game:GetService("HttpService") | |
| local LocalPlayer = Players.LocalPlayer | |
| local PlayerGui = LocalPlayer:WaitForChild("PlayerGui") | |
| -- Xóa UI cũ nếu có để tránh trùng lặp | |
| if PlayerGui:FindFirstChild("MacroSystemGui") then | |
| PlayerGui.MacroSystemGui:Destroy() | |
| end | |
| local pointsData = {} | |
| local MAX_CLICKS = 100 | |
| local currentMode = "None" | |
| local isRunning = false | |
| local connections = {} | |
| local currentlyEditingPoint = nil | |
| local SAVE_FILE_NAME = "AutoClicker_MacroSave.json" | |
| -- Biến quản lý kéo thả chung toàn cục | |
| local activeDraggingData = nil | |
| local dragStartPoint, startPosPoint | |
| -- ========================================== | |
| -- 1. HÀM HỖ TRỢ THỜI GIAN (Phần 1 - Nâng cấp chuẩn Regex) | |
| -- ========================================== | |
| local function parseTimeString(str) | |
| if type(str) ~= "string" then | |
| return 0.1 | |
| end | |
| str = str:lower():gsub("%s+", "") | |
| local number = str:match("^%d*%.?%d+") | |
| if not number then | |
| return 0.1 | |
| end | |
| local value = tonumber(number) | |
| if not value then | |
| return 0.1 | |
| end | |
| if str:find("ms") then | |
| return value / 1000 | |
| elseif str:find("d") then | |
| return value * 86400 | |
| elseif str:find("h") then | |
| return value * 3600 | |
| elseif str:find("m") then | |
| return value * 60 | |
| elseif str:find("s") then | |
| return value | |
| end | |
| return value | |
| end | |
| local function formatTimeString(seconds) | |
| if seconds >= 86400 then | |
| return string.format("%.1fd", seconds / 86400):gsub("%.0", "") | |
| elseif seconds >= 3600 then | |
| return string.format("%.1fh", seconds / 3600):gsub("%.0", "") | |
| elseif seconds >= 60 then | |
| return string.format("%.1fm", seconds / 60):gsub("%.0", "") | |
| elseif seconds >= 1 then | |
| return string.format("%.1fs", seconds):gsub("%.0", "") | |
| else | |
| return string.format("%dms", math.round(seconds * 1000)) | |
| end | |
| end | |
| -- ========================================== | |
| -- 2. TẠO GIAO DIỆN CHÍNH (UI) | |
| -- ========================================== | |
| local ScreenGui = Instance.new("ScreenGui") | |
| ScreenGui.Name = "MacroSystemGui" | |
| ScreenGui.ResetOnSpawn = false | |
| ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling | |
| ScreenGui.DisplayOrder = 999 | |
| ScreenGui.IgnoreGuiInset = true | |
| ScreenGui.Parent = PlayerGui | |
| local PointsFolder = Instance.new("Folder") | |
| PointsFolder.Name = "PointsFolder" | |
| PointsFolder.Parent = ScreenGui | |
| local MainFrame = Instance.new("Frame") | |
| MainFrame.Name = "MainFrame" | |
| MainFrame.Size = UDim2.new(0, 310, 0, 390) | |
| MainFrame.Position = UDim2.new(0.5, -155, 0.25, 0) | |
| MainFrame.BackgroundColor3 = Color3.fromRGB(25, 27, 38) | |
| MainFrame.BorderSizePixel = 0 | |
| MainFrame.Active = true | |
| MainFrame.Parent = ScreenGui | |
| local UICorner = Instance.new("UICorner"); UICorner.CornerRadius = UDim.new(0, 10); UICorner.Parent = MainFrame | |
| local UIStroke = Instance.new("UIStroke"); UIStroke.Color = Color3.fromRGB(60, 65, 85); UIStroke.Thickness = 1.5; UIStroke.Parent = MainFrame | |
| local Header = Instance.new("Frame") | |
| Header.Size = UDim2.new(1, 0, 0, 38); Header.BackgroundColor3 = Color3.fromRGB(35, 38, 52); Header.BorderSizePixel = 0; Header.Parent = MainFrame | |
| Instance.new("UICorner", Header).CornerRadius = UDim.new(0, 10) | |
| local Title = Instance.new("TextLabel") | |
| Title.Size = UDim2.new(1, -50, 1, 0); Title.Position = UDim2.new(0, 12, 0, 0); Title.BackgroundTransparency = 1 | |
| Title.Text = "✨ FINAL MASTER AUTO CLICKER"; Title.TextColor3 = Color3.fromRGB(255, 255, 255); Title.TextSize = 14; Title.Font = Enum.Font.GothamBold; Title.TextXAlignment = Enum.TextXAlignment.Left; Title.Parent = Header | |
| local CloseBtn = Instance.new("TextButton") | |
| CloseBtn.Size = UDim2.new(0, 30, 0, 30); CloseBtn.Position = UDim2.new(1, -5, 0.5, 0); CloseBtn.AnchorPoint = Vector2.new(1, 0.5); CloseBtn.BackgroundTransparency = 1 | |
| CloseBtn.Text = "✕"; CloseBtn.TextColor3 = Color3.fromRGB(255, 71, 87); CloseBtn.TextSize = 18; CloseBtn.Font = Enum.Font.GothamBold; CloseBtn.Parent = Header | |
| local StatusLabel = Instance.new("TextLabel") | |
| StatusLabel.Size = UDim2.new(1, -24, 0, 20); StatusLabel.Position = UDim2.new(0, 12, 0, 45); StatusLabel.BackgroundTransparency = 1 | |
| StatusLabel.Text = "Trạng thái: Đang nghỉ"; StatusLabel.TextColor3 = Color3.fromRGB(180, 185, 200); StatusLabel.TextSize = 13; StatusLabel.Font = Enum.Font.GothamMedium; StatusLabel.TextXAlignment = Enum.TextXAlignment.Left; StatusLabel.Parent = MainFrame | |
| local BtnContainer = Instance.new("Frame") | |
| BtnContainer.Size = UDim2.new(1, -24, 1, -125); BtnContainer.Position = UDim2.new(0, 12, 0, 75); BtnContainer.BackgroundTransparency = 1; BtnContainer.Parent = MainFrame | |
| local GridLayout = Instance.new("UIGridLayout") | |
| GridLayout.CellSize = UDim2.new(0.5, -5, 0, 35); GridLayout.CellPadding = UDim2.new(0, 10, 0, 10); GridLayout.SortOrder = Enum.SortOrder.LayoutOrder; GridLayout.Parent = BtnContainer | |
| local function createButton(name, text, color, order) | |
| local btn = Instance.new("TextButton"); btn.Name = name; btn.BackgroundColor3 = color; btn.Text = text; btn.TextColor3 = Color3.new(1,1,1); btn.Font = Enum.Font.GothamBold; btn.TextSize = 12; btn.LayoutOrder = order; btn.Parent = BtnContainer | |
| Instance.new("UICorner", btn).CornerRadius = UDim.new(0, 6) | |
| return btn | |
| end | |
| local BtnAdd = createButton("BtnAdd", "➕ Thêm Điểm", Color3.fromRGB(108, 92, 231), 1) | |
| local BtnMove = createButton("BtnMove", "🖐️ Di Chuyển", Color3.fromRGB(225, 112, 85), 2) | |
| local BtnDelOne = createButton("BtnDelOne", "🗑️ Xóa 1 Điểm", Color3.fromRGB(235, 77, 75), 3) | |
| local BtnTime = createButton("BtnTime", "⏱️ Chỉnh Time", Color3.fromRGB(9, 132, 227), 4) | |
| local BtnSave = createButton("BtnSave", "💾 Lưu Script", Color3.fromRGB(52, 152, 219), 5) | |
| local BtnLoad = createButton("BtnLoad", "📂 Tải Script", Color3.fromRGB(41, 128, 185), 6) | |
| local BtnClear = createButton("BtnClear", "🗑️ Xóa Tất Cả", Color3.fromRGB(127, 140, 141), 7) | |
| local BtnStart = createButton("BtnStart", "▶️ CHẠY MACRO", Color3.fromRGB(0, 184, 148), 8) | |
| BtnStart.Size = UDim2.new(1, 0, 0, 40) | |
| GridLayout.FillDirectionMaxCells = 2 | |
| -- ========================================== | |
| -- 3. BẢNG POPUP CHỈNH TIME | |
| -- ========================================== | |
| local TimePopup = Instance.new("Frame") | |
| TimePopup.Size = UDim2.new(0, 220, 0, 135); TimePopup.Position = UDim2.new(0.5, 0, 0.5, 0); TimePopup.AnchorPoint = Vector2.new(0.5, 0.5); TimePopup.BackgroundColor3 = Color3.fromRGB(45, 52, 54); TimePopup.Visible = false; TimePopup.ZIndex = 50; TimePopup.Parent = ScreenGui | |
| Instance.new("UICorner", TimePopup).CornerRadius = UDim.new(0, 10) | |
| local PopupLabel = Instance.new("TextLabel"); PopupLabel.Size = UDim2.new(1, 0, 0, 45); PopupLabel.Position = UDim2.new(0,0,0,5); PopupLabel.BackgroundTransparency = 1; PopupLabel.Text = "Nhập thời gian (ms, s, m, h, d):\nVD: 500ms | .5s | 2s | 1m" ; PopupLabel.TextColor3 = Color3.new(1,1,1); PopupLabel.Font = Enum.Font.GothamBold; PopupLabel.TextSize = 11; PopupLabel.Parent = TimePopup | |
| local TimeInput = Instance.new("TextBox"); TimeInput.Size = UDim2.new(0.8, 0, 0, 30); TimeInput.Position = UDim2.new(0.1, 0, 0, 50); TimeInput.BackgroundColor3 = Color3.fromRGB(20,20,20); TimeInput.TextColor3 = Color3.new(1,1,1); TimeInput.Text = "0.1s"; TimeInput.Font = Enum.Font.GothamMedium; TimeInput.Parent = TimePopup | |
| local PopupSave = Instance.new("TextButton"); PopupSave.Size = UDim2.new(0.8, 0, 0, 30); PopupSave.Position = UDim2.new(0.1, 0, 0, 90); PopupSave.BackgroundColor3 = Color3.fromRGB(0, 184, 148); PopupSave.Text = "LƯU"; PopupSave.TextColor3 = Color3.new(1,1,1); PopupSave.Font = Enum.Font.GothamBold; PopupSave.Parent = TimePopup; Instance.new("UICorner", PopupSave) | |
| -- ========================================== | |
| -- 4. HỆ THỐNG TƯƠNG TÁC & KIỂM TRA UI (Phần 2) | |
| -- ========================================== | |
| local draggingUI, dragStartUI, startPosUI | |
| table.insert(connections, Header.InputBegan:Connect(function(input) | |
| if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then | |
| draggingUI = true; dragStartUI = input.Position; startPosUI = MainFrame.Position | |
| end | |
| end)) | |
| table.insert(connections, UserInputService.InputChanged:Connect(function(input) | |
| if draggingUI and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then | |
| local delta = input.Position - dragStartUI | |
| MainFrame.Position = UDim2.new(startPosUI.X.Scale, startPosUI.X.Offset + delta.X, startPosUI.Y.Scale, startPosUI.Y.Offset + delta.Y) | |
| end | |
| if activeDraggingData and currentMode == "Move" and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then | |
| local delta = input.Position - dragStartPoint | |
| activeDraggingData.frame.Position = UDim2.new(0, startPosPoint.X.Offset + delta.X, 0, startPosPoint.Y.Offset + delta.Y) | |
| end | |
| end)) | |
| table.insert(connections, UserInputService.InputEnded:Connect(function(input) | |
| if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then | |
| draggingUI = false | |
| if activeDraggingData then | |
| activeDraggingData.isDragging = false | |
| activeDraggingData = nil | |
| end | |
| end | |
| end)) | |
| local function isClickingOnMacroUI(clickPos) | |
| local frames = {MainFrame, TimePopup} | |
| for _, frame in ipairs(frames) do | |
| if frame.Visible then | |
| local pos, size = frame.AbsolutePosition, frame.AbsoluteSize | |
| if clickPos.X >= pos.X and clickPos.X <= (pos.X + size.X) and clickPos.Y >= pos.Y and clickPos.Y <= (pos.Y + size.Y) then return true end | |
| end | |
| end | |
| return false | |
| end | |
| -- Phần 2: Hàm kiểm tra UI game chuẩn xác mở rộng | |
| local function isBlockedByGameUI(x, y) | |
| local objects = PlayerGui:GetGuiObjectsAtPosition(x, y) | |
| for _, obj in ipairs(objects) do | |
| local isOurUI = false | |
| local parent = obj | |
| while parent and parent ~= PlayerGui do | |
| if parent == ScreenGui then | |
| isOurUI = true | |
| break | |
| end | |
| parent = parent.Parent | |
| end | |
| if not isOurUI then | |
| if obj:IsA("GuiButton") | |
| or obj:IsA("Frame") | |
| or obj:IsA("TextLabel") | |
| or obj:IsA("TextButton") | |
| or obj:IsA("ImageLabel") | |
| or obj:IsA("ImageButton") | |
| or obj:IsA("ScrollingFrame") | |
| or obj:IsA("ViewportFrame") | |
| or obj:IsA("VideoFrame") then | |
| if obj.Visible then | |
| return true | |
| end | |
| end | |
| end | |
| end | |
| return false | |
| end | |
| local function updatePointLabels() | |
| for i, data in ipairs(pointsData) do | |
| data.id = i | |
| if data.numLabel then | |
| data.numLabel.Text = tostring(i) | |
| end | |
| end | |
| end | |
| local function removeWaypoint(targetData) | |
| if not targetData then | |
| return | |
| end | |
| for i = #pointsData, 1, -1 do | |
| local data = pointsData[i] | |
| if data == targetData then | |
| if data.conn then | |
| data.conn:Disconnect() | |
| data.conn = nil | |
| end | |
| if data.frame then | |
| data.frame:Destroy() | |
| data.frame = nil | |
| end | |
| data.timeLabel = nil | |
| data.numLabel = nil | |
| table.remove(pointsData, i) | |
| break | |
| end | |
| end | |
| updatePointLabels() | |
| end | |
| local function setMode(mode) | |
| if isRunning then return end | |
| currentMode = (currentMode == mode) and "None" or mode | |
| BtnAdd.BackgroundColor3 = (currentMode == "Add") and Color3.fromRGB(162, 155, 254) or Color3.fromRGB(108, 92, 231) | |
| BtnMove.BackgroundColor3 = (currentMode == "Move") and Color3.fromRGB(250, 177, 160) or Color3.fromRGB(225, 112, 85) | |
| BtnDelOne.BackgroundColor3 = (currentMode == "Delete") and Color3.fromRGB(255, 121, 121) or Color3.fromRGB(235, 77, 75) | |
| BtnTime.BackgroundColor3 = (currentMode == "Time") and Color3.fromRGB(116, 185, 255) or Color3.fromRGB(9, 132, 227) | |
| TimePopup.Visible = false | |
| currentlyEditingPoint = nil | |
| if currentMode == "None" then StatusLabel.Text = "Trạng thái: Đang nghỉ" | |
| elseif currentMode == "Add" then StatusLabel.Text = "Trạng thái: Bấm màn hình để đặt điểm" | |
| elseif currentMode == "Move" then StatusLabel.Text = "Trạng thái: Kéo thả điểm để di chuyển" | |
| elseif currentMode == "Delete" then StatusLabel.Text = "Trạng thái: Bấm vào điểm để xóa" | |
| elseif currentMode == "Time" then StatusLabel.Text = "Trạng thái: Bấm vào điểm để sửa Time" end | |
| end | |
| -- ========================================== | |
| -- 5. TẠO VÀ QUẢN LÝ WAYPOINT | |
| -- ========================================== | |
| local function createWaypoint(x, y) | |
| if #pointsData >= MAX_CLICKS then return end | |
| local id = #pointsData + 1 | |
| local Dot = Instance.new("Frame") | |
| Dot.Size = UDim2.new(0, 34, 0, 34) | |
| Dot.Position = UDim2.new(0, x, 0, y) | |
| Dot.AnchorPoint = Vector2.new(0.5, 0.5) | |
| Dot.BackgroundColor3 = Color3.fromRGB(255, 159, 67) | |
| Dot.BorderSizePixel = 0 | |
| Dot.ZIndex = 50 | |
| Dot.Parent = PointsFolder | |
| Instance.new("UICorner", Dot).CornerRadius = UDim.new(1, 0) | |
| local UIStrokeDot = Instance.new("UIStroke"); UIStrokeDot.Color = Color3.new(1,1,1); UIStrokeDot.Thickness = 2; UIStrokeDot.Parent = Dot | |
| local NumLabel = Instance.new("TextLabel"); NumLabel.Size = UDim2.new(1, 0, 1, 0); NumLabel.BackgroundTransparency = 1; NumLabel.Text = tostring(id); NumLabel.TextColor3 = Color3.new(1,1,1); NumLabel.Font = Enum.Font.GothamBold; NumLabel.TextSize = 16; NumLabel.Parent = Dot | |
| local TimeLabel = Instance.new("TextLabel"); TimeLabel.Size = UDim2.new(0, 50, 0, 20); TimeLabel.Position = UDim2.new(0.5, -25, 1, 2); TimeLabel.BackgroundTransparency = 1; TimeLabel.Text = "0.1s"; TimeLabel.TextColor3 = Color3.fromRGB(85, 239, 196); TimeLabel.Font = Enum.Font.GothamBold; TimeLabel.TextSize = 12; TimeLabel.TextStrokeTransparency = 0; TimeLabel.Parent = Dot | |
| local data = { id = id, frame = Dot, delay = 0.1, timeLabel = TimeLabel, numLabel = NumLabel, isDragging = false, conn = nil } | |
| data.conn = Dot.InputBegan:Connect(function(input) | |
| if isRunning then return end | |
| if currentMode == "Move" and (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) then | |
| activeDraggingData = data | |
| data.isDragging = true | |
| dragStartPoint = input.Position | |
| startPosPoint = Dot.Position | |
| elseif currentMode == "Delete" and (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) then | |
| removeWaypoint(data) | |
| elseif currentMode == "Time" and (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) then | |
| currentlyEditingPoint = data | |
| TimeInput.Text = formatTimeString(data.delay) | |
| TimePopup.Visible = true | |
| end | |
| end) | |
| table.insert(pointsData, data) | |
| end | |
| -- ========================================== | |
| -- 6. CÁC NÚT ĐIỀU KHIỂN & SAVE/LOAD (Phần 3 & 4) | |
| -- ========================================== | |
| table.insert(connections, PopupSave.Activated:Connect(function() | |
| if currentlyEditingPoint then | |
| local newTime = parseTimeString(TimeInput.Text) | |
| if newTime and newTime >= 0.001 then | |
| currentlyEditingPoint.delay = newTime | |
| currentlyEditingPoint.timeLabel.Text = formatTimeString(newTime) | |
| end | |
| end | |
| TimePopup.Visible = false | |
| currentlyEditingPoint = nil | |
| end)) | |
| table.insert(connections, UserInputService.InputBegan:Connect(function(input) | |
| if currentMode == "Add" and (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) then | |
| if not isClickingOnMacroUI(input.Position) then createWaypoint(input.Position.X, input.Position.Y) end | |
| end | |
| end)) | |
| table.insert(connections, BtnAdd.Activated:Connect(function() setMode("Add") end)) | |
| table.insert(connections, BtnMove.Activated:Connect(function() setMode("Move") end)) | |
| table.insert(connections, BtnDelOne.Activated:Connect(function() setMode("Delete") end)) | |
| table.insert(connections, BtnTime.Activated:Connect(function() setMode("Time") end)) | |
| -- Phần 3: Fix Save với kiểm tra ok/pcall rõ ràng | |
| table.insert(connections, BtnSave.Activated:Connect(function() | |
| if isRunning then return end | |
| if not writefile then | |
| StatusLabel.Text = "Trạng thái: Executor không hỗ trợ writefile!" | |
| return | |
| end | |
| local saveData = { | |
| mainFramePos = { | |
| XScale = MainFrame.Position.X.Scale, | |
| XOffset = MainFrame.Position.X.Offset, | |
| YScale = MainFrame.Position.Y.Scale, | |
| YOffset = MainFrame.Position.Y.Offset | |
| }, | |
| points = {} | |
| } | |
| for _, data in ipairs(pointsData) do | |
| table.insert(saveData.points, { | |
| x = data.frame.Position.X.Offset, | |
| y = data.frame.Position.Y.Offset, | |
| delay = data.delay | |
| }) | |
| end | |
| local success, encoded = pcall(function() | |
| return HttpService:JSONEncode(saveData) | |
| end) | |
| if not success then | |
| StatusLabel.Text = "Trạng thái: Lỗi khi mã hóa Script!" | |
| return | |
| end | |
| local ok = pcall(function() | |
| writefile( | |
| SAVE_FILE_NAME, | |
| encoded | |
| ) | |
| end) | |
| if ok then | |
| StatusLabel.Text = "Trạng thái: Đã lưu Script thành công!" | |
| else | |
| StatusLabel.Text = "Trạng thái: Không thể ghi file!" | |
| end | |
| end)) | |
| -- Phần 4: Fix Load kiểm tra kiểu dữ liệu file | |
| table.insert(connections, BtnLoad.Activated:Connect(function() | |
| if isRunning then return end | |
| if not readfile or not isfile or not isfile(SAVE_FILE_NAME) then | |
| StatusLabel.Text = "Trạng thái: Không tìm thấy file lưu!" | |
| return | |
| end | |
| local success, decoded = pcall(function() | |
| return HttpService:JSONDecode(readfile(SAVE_FILE_NAME)) | |
| end) | |
| if type(decoded) ~= "table" then | |
| StatusLabel.Text = "Trạng thái: File bị lỗi!" | |
| return | |
| end | |
| if success then | |
| for _, data in ipairs(pointsData) do | |
| if data.conn then data.conn:Disconnect() end | |
| data.frame:Destroy() | |
| end | |
| table.clear(pointsData) | |
| if decoded.mainFramePos then | |
| MainFrame.Position = UDim2.new( | |
| decoded.mainFramePos.XScale, decoded.mainFramePos.XOffset, | |
| decoded.mainFramePos.YScale, decoded.mainFramePos.YOffset | |
| ) | |
| end | |
| local pointsList = decoded.points or decoded | |
| for _, item in ipairs(pointsList) do | |
| if item.x and item.y then | |
| createWaypoint(item.x, item.y) | |
| if #pointsData > 0 then | |
| pointsData[#pointsData].delay = item.delay or 0.1 | |
| pointsData[#pointsData].timeLabel.Text = formatTimeString(item.delay or 0.1) | |
| end | |
| end | |
| end | |
| StatusLabel.Text = "Trạng thái: Tải Script thành công!" | |
| setMode("None") | |
| else | |
| StatusLabel.Text = "Trạng thái: Lỗi khi đọc file lưu!" | |
| end | |
| end)) | |
| table.insert(connections, BtnClear.Activated:Connect(function() | |
| if isRunning then return end | |
| for _, data in ipairs(pointsData) do | |
| if data.conn then data.conn:Disconnect() end | |
| data.frame:Destroy() | |
| end | |
| table.clear(pointsData) | |
| activeDraggingData = nil | |
| currentlyEditingPoint = nil | |
| TimePopup.Visible = false | |
| setMode("None") | |
| StatusLabel.Text = "Trạng thái: Đã xóa tất cả điểm!" | |
| end)) | |
| -- ========================================== | |
| -- 7. CHẠY MACRO (Phần 5, 6, 7) | |
| -- ========================================== | |
| table.insert(connections, BtnStart.Activated:Connect(function() | |
| if #pointsData == 0 then return end | |
| -- Phần 7: Fix nút Dừng/Stop chuẩn xác | |
| if isRunning then | |
| isRunning = false | |
| task.wait() | |
| BtnStart.Text = "▶️ CHẠY MACRO" | |
| BtnStart.BackgroundColor3 = Color3.fromRGB(0,184,148) | |
| StatusLabel.Text = "Trạng thái: Đang nghỉ" | |
| setMode("None") | |
| return | |
| end | |
| isRunning = true; currentMode = "Run"; TimePopup.Visible = false; currentlyEditingPoint = nil | |
| BtnStart.Text = "⏹️ DỪNG MACRO"; BtnStart.BackgroundColor3 = Color3.fromRGB(214, 48, 49) | |
| StatusLabel.Text = "Trạng thái: Đang chạy tự động..." | |
| task.spawn(function() | |
| while isRunning do | |
| for _, data in ipairs(pointsData) do | |
| -- Phần 5: Kiểm tra an toàn cho waypoint trong lúc chạy | |
| if not data.frame then continue end | |
| if not data.frame.Parent then continue end | |
| if not isRunning then break end | |
| local clickX = data.frame.AbsolutePosition.X + (data.frame.AbsoluteSize.X / 2) | |
| local clickY = data.frame.AbsolutePosition.Y + (data.frame.AbsoluteSize.Y / 2) | |
| -- Phần 6: Né UI game thông minh và tự trả lại màu chuẩn không bị kẹt xám | |
| if isBlockedByGameUI(clickX, clickY) then | |
| data.frame.BackgroundColor3 = Color3.fromRGB(120, 120, 120) | |
| task.wait(0.05) | |
| data.frame.BackgroundColor3 = Color3.fromRGB(255, 159, 67) | |
| continue | |
| end | |
| data.frame.BackgroundColor3 = Color3.fromRGB(255, 71, 87) | |
| pcall(function() | |
| VirtualInputManager:SendMouseMoveEvent(clickX, clickY, game) | |
| VirtualInputManager:SendMouseButtonEvent(clickX, clickY, 0, true, game, 1) | |
| VirtualInputManager:SendTouchEvent(data.id, 0, clickX, clickY) | |
| task.wait(0.08) | |
| VirtualInputManager:SendMouseButtonEvent(clickX, clickY, 0, false, game, 1) | |
| VirtualInputManager:SendTouchEvent(data.id, 2, clickX, clickY) | |
| end) | |
| pcall(function() | |
| if getconnections then | |
| local guiObjects = PlayerGui:GetGuiObjectsAtPosition(clickX, clickY) | |
| for _, gui in ipairs(guiObjects) do | |
| if gui:IsA("GuiButton") then | |
| for _, conn in ipairs(getconnections(gui.MouseButton1Down)) do conn:Fire() end | |
| for _, conn in ipairs(getconnections(gui.Activated)) do conn:Fire() end | |
| for _, conn in ipairs(getconnections(gui.TouchTap)) do conn:Fire() end | |
| for _, conn in ipairs(getconnections(gui.MouseButton1Click)) do conn:Fire() end | |
| for _, conn in ipairs(getconnections(gui.MouseButton1Up)) do conn:Fire() end | |
| break | |
| end | |
| end | |
| end | |
| end) | |
| task.wait(data.delay) | |
| data.frame.BackgroundColor3 = Color3.fromRGB(255, 159, 67) | |
| end | |
| task.wait(0.01) | |
| end | |
| end) | |
| end)) | |
| -- ========================================== | |
| -- 8. NÚT ĐÓNG / HỦY GIAO DIỆN (Phần 8) | |
| -- ========================================== | |
| table.insert(connections, CloseBtn.Activated:Connect(function() | |
| isRunning = false | |
| activeDraggingData = nil | |
| currentlyEditingPoint = nil | |
| task.wait() | |
| for _, conn in ipairs(connections) do | |
| if conn.Connected then | |
| conn:Disconnect() | |
| end | |
| end | |
| table.clear(connections) | |
| if ScreenGui then | |
| ScreenGui:Destroy() | |
| end | |
| end)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment