-- ============================================================ -- BSW HUB - PICK UP LEAFS -- made by baltazar.exe -- ============================================================ local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local LocalPlayer = Players.LocalPlayer local Remotes = ReplicatedStorage:WaitForChild("Remotes", 10) local LeafPickedUp = Remotes and Remotes:WaitForChild("LeafPickedUp", 10) -- SellLeavesEvent sits at the ReplicatedStorage root in the capture, but fall -- back to a deep search so a moved/renamed parent doesn't silently no-op local SellLeaves = ReplicatedStorage:FindFirstChild("SellLeavesEvent") or ReplicatedStorage:FindFirstChild("SellLeavesEvent", true) -- Modules.LeafData holds the client-side leaf table: each entry is -- { pickedUp, cframe, templateIndex, areaName, instance }. Reading it lets us -- fire pickups for leaves that actually exist (with their real areaName) -- instead of blind-spamming a hardcoded area. local LeafData do local modules = ReplicatedStorage:FindFirstChild("Modules") local leafDataModule = modules and modules:FindFirstChild("LeafData") if leafDataModule then local ok, result = pcall(require, leafDataModule) if ok then LeafData = result end end end -- the valid AreaName values are just the children of workspace.Areas local AreasFolder = workspace:WaitForChild("Areas", 10) local ALL_AREAS = "All Areas" local function getAreaNames() local names = { ALL_AREAS } local seen = {} if AreasFolder then local found = {} for _, area in ipairs(AreasFolder:GetChildren()) do if not seen[area.Name] then seen[area.Name] = true table.insert(found, area.Name) end end table.sort(found) for _, name in ipairs(found) do table.insert(names, name) end end if #names == 1 then table.insert(names, "Shed") end return names end -- if a previous instance is still running, shut it down before starting if getgenv and getgenv().__PickUpLeafsUnload then pcall(getgenv().__PickUpLeafsUnload) end local scriptRunning = true local connections = {} local function track(conn) connections[#connections + 1] = conn return conn end local Config = { AutoPickup = false, PickupDelay = 0.1, LeafsPerFire = 10, -- LeafPickedUp takes an array, so several leafs can go per call AreaName = ALL_AREAS, UseRealLeaves = true, -- pull pending leaves out of LeafData instead of spamming a fixed payload IsLucky = false, -- LeafData has no per-leaf lucky flag, so this is what goes in the payload AutoSell = false, SellDelay = 5, SellAmount = 1, AntiAFK = true, } local Window -- ============================================================ -- ANTI AFK -- ============================================================ local VirtualUser = game:GetService("VirtualUser") track(LocalPlayer.Idled:Connect(function() if not Config.AntiAFK then return end pcall(function() VirtualUser:CaptureController() VirtualUser:ClickButton2(Vector2.new()) end) end)) -- ============================================================ -- AUTO PICK UP LEAFS -- ============================================================ -- Collects up to `limit` leaf indexes that are still on the ground, honouring -- the area filter. Returns the indexes so they can be marked off after firing. local function takePendingLeaves(limit) local picked = {} if not (LeafData and LeafData.leaves) then return picked end local wantAll = Config.AreaName == ALL_AREAS for index, leaf in ipairs(LeafData.leaves) do if #picked >= limit then break end if not leaf.pickedUp and (wantAll or leaf.areaName == Config.AreaName) then table.insert(picked, { index = index, areaName = leaf.areaName }) end end return picked end task.spawn(function() while scriptRunning do task.wait(Config.PickupDelay) if Config.AutoPickup and LeafPickedUp then local batch = math.max(Config.LeafsPerFire, 1) local payload = {} local pending if Config.UseRealLeaves and LeafData and LeafData.leaves then pending = takePendingLeaves(batch) for _, leaf in ipairs(pending) do table.insert(payload, { AreaName = leaf.areaName, IsLucky = Config.IsLucky, }) end else -- no LeafData (or disabled): fall back to a fixed payload local area = Config.AreaName ~= ALL_AREAS and Config.AreaName or "Shed" for _ = 1, batch do table.insert(payload, { AreaName = area, IsLucky = Config.IsLucky, }) end end if #payload > 0 then pcall(function() LeafPickedUp:FireServer(payload) end) -- clear them locally so the next pass doesn't resend the same ones if pending and LeafData and LeafData.MarkPickedUp then for _, leaf in ipairs(pending) do pcall(LeafData.MarkPickedUp, leaf.index) end end end end end end) -- ============================================================ -- AUTO SELL LEAFS -- ============================================================ -- Returns ok, err so the UI button can actually report what went wrong -- instead of failing silently inside a bare pcall. local function fireSell() if not SellLeaves then return false, "SellLeavesEvent not found in ReplicatedStorage" end if SellLeaves:IsA("RemoteFunction") then return pcall(function() return SellLeaves:InvokeServer(Config.SellAmount) end) end return pcall(function() SellLeaves:FireServer(Config.SellAmount) end) end task.spawn(function() while scriptRunning do task.wait(Config.SellDelay) if Config.AutoSell then fireSell() end end end) -- ============================================================ -- UI VEIL -- ============================================================ local Veil local ok = pcall(function() Veil = loadstring(game:HttpGet("https://raw.githubusercontent.com/Baltazarexe/bswui/main/uilib.lua"))() end) if not ok or not Veil then warn("[BSW] VeilUI failed to load") return end if not LeafPickedUp then warn("[BSW] Remotes.LeafPickedUp not found") end if not SellLeaves then warn("[BSW] SellLeavesEvent not found") end local DISCORD_LINK = "https://discord.gg/2aHSqGXj9u" -- if the configured area isn't in this game, fall back to the first one found local areaNames = getAreaNames() local hasConfiguredArea = false for _, name in ipairs(areaNames) do if name == Config.AreaName then hasConfiguredArea = true break end end if not hasConfiguredArea then Config.AreaName = areaNames[1] end Window = Veil.CreateWindow({ Title = "BSW Hub", Subtitle = "Pick Up Leafs", Theme = "Balta", Transparency = 0.06, Blur = false, HideName = false, ToggleKey = Enum.KeyCode.K, ConfigurationSaving = { Enabled = true, FolderName = "BSWHub", FileName = "PickUpLeafsConfig" }, }) -- ── MAIN TAB ───────────────────────────────────────────── local MainTab = Window:CreateTab("Main") MainTab:CreateSection("Pick Up") MainTab:CreateToggle({ Name = "Auto Pick Up Leafs", Flag = "AutoPickup", CurrentValue = Config.AutoPickup, Callback = function(v) Config.AutoPickup = v end, }) MainTab:CreateSlider({ Name = "Pickup Delay", Range = { 0.05, 3 }, Increment = 0.05, Suffix = "s", CurrentValue = Config.PickupDelay, Flag = "PickupDelay", Callback = function(v) Config.PickupDelay = v end, }) MainTab:CreateSlider({ Name = "Leafs Per Fire", Description = "How many leafs go in each request", Range = { 1, 100 }, Increment = 1, Suffix = "", CurrentValue = Config.LeafsPerFire, Flag = "LeafsPerFire", Callback = function(v) Config.LeafsPerFire = v end, }) MainTab:CreateToggle({ Name = "Use Real Leaves", Description = "Only picks up leaves that actually exist, read from Modules.LeafData", Flag = "UseRealLeaves", CurrentValue = Config.UseRealLeaves, Callback = function(v) Config.UseRealLeaves = v end, }) MainTab:CreateDropdown({ Name = "Area", Description = "Read from workspace.Areas", Options = areaNames, CurrentOption = Config.AreaName, Flag = "AreaName", Callback = function(v) Config.AreaName = v end, }) MainTab:CreateToggle({ Name = "Is Lucky", Description = "Sends IsLucky = true in the pickup payload", Flag = "IsLucky", CurrentValue = Config.IsLucky, Callback = function(v) Config.IsLucky = v end, }) MainTab:CreateSection("Selling") MainTab:CreateToggle({ Name = "Auto Sell Leafs", Flag = "AutoSell", CurrentValue = Config.AutoSell, Callback = function(v) Config.AutoSell = v end, }) MainTab:CreateSlider({ Name = "Sell Delay", Range = { 1, 60 }, Increment = 1, Suffix = "s", CurrentValue = Config.SellDelay, Flag = "SellDelay", Callback = function(v) Config.SellDelay = v end, }) MainTab:CreateSlider({ Name = "Sell Amount", Description = "Value sent to SellLeavesEvent", Range = { 1, 10 }, Increment = 1, Suffix = "", CurrentValue = Config.SellAmount, Flag = "SellAmount", Callback = function(v) Config.SellAmount = v end, }) MainTab:CreateButton({ Name = "Sell Now", Description = "Fires SellLeavesEvent once and reports the result", Callback = function() local sold, err = fireSell() if sold then Window:Notify({ Title = "Sell", Content = ("Fired %s(%s)"):format(SellLeaves.ClassName, tostring(Config.SellAmount)), Type = "Success", }) else Window:Notify({ Title = "Sell failed", Content = tostring(err), Type = "Error" }) end end, }) -- ── INFO TAB ───────────────────────────────────────────── local InfoTab = Window:CreateTab("Info") InfoTab:CreateParagraph({ Title = "BSW Hub - Pick Up Leafs", Content = "Automatic leaf pickup and selling. Set the Area Name to the area you are farming.", }) InfoTab:CreateSection("General") InfoTab:CreateToggle({ Name = "Anti AFK", Flag = "AntiAFK", CurrentValue = Config.AntiAFK, Callback = function(v) Config.AntiAFK = v end, }) InfoTab:CreateKeybind({ Name = "Menu Toggle Key", CurrentKeybind = "K", Flag = "MenuToggleKey", Callback = function(key) Window:SetToggleKey(key) end, }) InfoTab:CreateToggle({ Name = "Hide Name", Description = "Hides your display name/username in the sidebar", Flag = "HideNameToggle", CurrentValue = false, Callback = function(v) Window:SetNameHidden(v) end, }) InfoTab:CreateButton({ Name = "Join Discord", Description = "Copy Discord invite link", Callback = function() if typeof(setclipboard) == "function" then setclipboard(DISCORD_LINK) Window:Notify({ Title = "Copied!", Content = "Discord link copied to clipboard.", Type = "Success" }) end end, }) InfoTab:CreateDivider() local function unload() scriptRunning = false Config.AutoPickup = false Config.AutoSell = false for _, conn in ipairs(connections) do pcall(function() conn:Disconnect() end) end pcall(function() Window:Destroy() end) if getgenv then getgenv().__PickUpLeafsUnload = nil end end if getgenv then getgenv().__PickUpLeafsUnload = unload end InfoTab:CreateButton({ Name = "Unload Script", Description = "Stops every loop, disconnects listeners and closes the UI", Callback = unload, }) InfoTab:CreateLabel("v1.0 | BSW UI") Window:Notify({ Title = "Loaded", Content = "BSW Pick Up Leafs started successfully.", Type = "Success" })