
Key Required

-- ============================================================
-- 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" })No comments yet for this script.