
Credits: mmr1337
auto farmsilent sellauto buy items
-- example script by https://github.com/mstudio45/LinoriaLib/blob/main/Example.lua and modified by deivid
-- You can suggest changes with a pull request or something
local repo = "https://raw.githubusercontent.com/deividcomsono/Obsidian/main/"
local Library = loadstring(game:HttpGet(repo .. "Library.lua"))()
local ThemeManager = loadstring(game:HttpGet(repo .. "addons/ThemeManager.lua"))()
local SaveManager = loadstring(game:HttpGet(repo .. "addons/SaveManager.lua"))()
local Options = Library.Options
local Toggles = Library.Toggles
Library.ForceCheckbox = false -- Forces AddToggle to AddCheckbox
Library.ShowToggleFrameInKeybinds = true -- Make toggle keybinds work inside the keybinds UI (aka adds a toggle to the UI). Good for mobile users (Default value = true)
local Window = Library:CreateWindow({
Title = "Example",
Footer = "by dex3x3",
Icon = 95952879196724,
NotifySide = "Right",
ShowCustomCursor = true,
})
-- Tabs: keep only Main (empty) and UI Settings
local Tabs = {
Main = Window:AddTab("Main", "user"),
["UI Settings"] = Window:AddTab("UI Settings", "settings"),
}
-- UI Settings
local MenuGroup = Tabs["UI Settings"]:AddLeftGroupbox("Menu", "wrench")
MenuGroup:AddToggle("ShowCustomCursor", {
Text = "Custom Cursor",
Default = true,
Callback = function(Value)
Library.ShowCustomCursor = Value
end,
})
MenuGroup:AddDropdown("NotificationSide", {
Values = { "Left", "Right" },
Default = "Right",
Text = "Notification Side",
Callback = function(Value)
Library:SetNotifySide(Value)
end,
})
MenuGroup:AddDropdown("DPIDropdown", {
Values = { "50%", "75%", "100%", "125%", "150%", "175%", "200%" },
Default = "100%",
Text = "DPI Scale",
Callback = function(Value)
Value = Value:gsub("%%", "")
local DPI = tonumber(Value)
Library:SetDPIScale(DPI)
end,
})
MenuGroup:AddDivider()
MenuGroup:AddLabel("Menu bind")
:AddKeyPicker("MenuKeybind", { Default = "RightShift", NoUI = true, Text = "Menu keybind" })
MenuGroup:AddButton("Unload", function()
Library:Unload()
end)
Library.ToggleKeybind = Options.MenuKeybind -- Allows you to have a custom keybind for the menu
-- Addons:
-- SaveManager (Allows you to have a configuration system)
-- ThemeManager (Allows you to have a menu theme system)
-- Hand the library over to our managers
ThemeManager:SetLibrary(Library)
SaveManager:SetLibrary(Library)
-- Ignore keys that are used by ThemeManager.
-- (we dont want configs to save themes, do we?)
SaveManager:IgnoreThemeSettings()
-- Adds our MenuKeybind to the ignore list
-- (do you want each config to have a different menu key? probably not.)
SaveManager:SetIgnoreIndexes({ "MenuKeybind" })
-- use case for doing it this way:
-- a script hub could have themes in a global folder
-- and game configs in a separate folder per game
ThemeManager:SetFolder("MyScriptHub")
SaveManager:SetFolder("MyScriptHub/specific-game")
SaveManager:SetSubFolder("specific-place") -- if the game has multiple places inside of it (for example: DOORS)
-- you can use this to save configs for those places separately
-- The path in this script would be: MyScriptHub/specific-game/settings/specific-place
-- [ This is optional ]
-- Builds our config menu on the right side of our tab
SaveManager:BuildConfigSection(Tabs["UI Settings"])
-- Builds our theme menu (with plenty of built in themes) on the left side
-- NOTE: you can also call ThemeManager:ApplyToGroupbox to add it to a specific groupbox
ThemeManager:ApplyToTab(Tabs["UI Settings"])
-- You can use the SaveManager:LoadAutoloadConfig() to load a config
-- which has been marked to be one that auto loads!
SaveManager:LoadAutoloadConfig()
-- Auto Harvest: UI (Main) + логика без стороннего GUI
do
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local player = Players.LocalPlayer
local function getZoneNames()
local fieldsFolder = Workspace:FindFirstChild("Fields")
if not fieldsFolder then return {} end
local list = {}
for _, zone in ipairs(fieldsFolder:GetChildren()) do
table.insert(list, zone.Name)
end
table.sort(list)
return list
end
local function getZoneByName(name)
local fieldsFolder = Workspace:FindFirstChild("Fields")
if not fieldsFolder then return nil end
return fieldsFolder:FindFirstChild(name)
end
local hitRemote = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("Tool"):WaitForChild("Hit")
local useRemote = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("Tool"):WaitForChild("Use")
local farmingZoneName = nil
local farmCoroutine = nil
local farmStop = false
local function stopFarming()
if farmingZoneName ~= nil then
print("[AutoHarvest] Stop farming zone:", farmingZoneName)
end
farmingZoneName = nil
if farmCoroutine then
farmStop = true
local tries = 0
while coroutine.status(farmCoroutine) ~= "dead" and tries < 100 do
task.wait(0.05)
tries = tries + 1
end
farmCoroutine = nil
end
farmStop = false
end
local function teleportToZone(zoneName)
local zone = getZoneByName(zoneName)
if not zone then return end
local char = player.Character or player.CharacterAdded:Wait()
if not (char and char:FindFirstChild("HumanoidRootPart")) then return end
local cf
if zone:IsA("Model") then
cf = zone:GetPivot()
elseif zone:IsA("BasePart") then
cf = zone.CFrame
else
return
end
char:PivotTo(cf + Vector3.new(0, 5, 0))
end
local function startFarming(zoneName)
if farmingZoneName == zoneName then return end
stopFarming()
if not zoneName then return end
local zone = getZoneByName(zoneName)
if not zone then
warn("[AutoHarvest] Zone not found:", zoneName)
return
end
local resources = zone:FindFirstChild("Resources")
if not resources then
warn("[AutoHarvest] No Resources folder in zone:", zoneName)
return
end
farmingZoneName = zoneName
print("[AutoHarvest] Start farming zone:", zoneName)
farmStop = false
farmCoroutine = coroutine.create(function()
while not farmStop do
useRemote:FireServer()
-- собрать актуальные модели ресурсов
local models = {}
for _, obj in ipairs(resources:GetChildren()) do
if obj.Name == "ResourceModel" then
table.insert(models, obj)
end
end
for _, resourceModel in ipairs(models) do
if farmStop then break end
hitRemote:FireServer(resourceModel)
task.wait(0.5)
if farmStop then break end
end
task.wait(0.1)
end
end)
coroutine.resume(farmCoroutine)
end
player.CharacterAdded:Connect(function()
if farmingZoneName then
teleportToZone(farmingZoneName)
startFarming(farmingZoneName)
end
end)
-- UI в Main
local MainGroup = Tabs.Main:AddLeftGroupbox("Auto Harvest", "sprout")
local zones = getZoneNames()
MainGroup:AddDropdown("HarvestZone", {
Values = zones,
Default = zones[1],
Multi = false,
Text = "Farm Zone",
Searchable = true,
Callback = function(value)
if Toggles.AutoHarvestToggle and Toggles.AutoHarvestToggle.Value then
teleportToZone(value)
startFarming(value)
end
end,
})
MainGroup:AddToggle("AutoHarvestToggle", {
Text = "Auto Harvest",
Default = false,
Callback = function(enabled)
local selected = Options.HarvestZone and Options.HarvestZone.Value or nil
if enabled then
if not selected or selected == "" then
Library:Notify("Select a zone in the dropdown list", 3)
Toggles.AutoHarvestToggle:SetValue(false)
return
end
teleportToZone(selected)
startFarming(selected)
else
stopFarming()
end
end,
})
MainGroup:AddButton("Update Zone List", function()
local newZones = getZoneNames()
Options.HarvestZone:SetValues(newZones)
if #newZones > 0 and not Options.HarvestZone.Value then
Options.HarvestZone:SetValue(newZones[1])
end
end)
end
do
local Players = game:GetService("Players")
local ProximityPromptService = game:GetService("ProximityPromptService")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local player = Players.LocalPlayer
local autoSellEnabled = false
local promptConn
local resetKeyConn
local currentPrompt
local savedDefaults
local function capturePromptDefaults(prompt)
return {
MaxActivationDistance = prompt.MaxActivationDistance,
RequiresLineOfSight = prompt.RequiresLineOfSight,
HoldDuration = prompt.HoldDuration,
ActionText = prompt.ActionText,
ObjectText = prompt.ObjectText,
KeyboardKeyCode = prompt.KeyboardKeyCode,
GamepadKeyCode = prompt.GamepadKeyCode,
ClickablePrompt = prompt.ClickablePrompt,
Enabled = prompt.Enabled,
UIOffset = prompt.UIOffset,
Style = prompt.Style,
}
end
local function resetPromptToDefault(prompt, defaults)
if not prompt or not defaults then return end
prompt.MaxActivationDistance = defaults.MaxActivationDistance
prompt.RequiresLineOfSight = defaults.RequiresLineOfSight
prompt.HoldDuration = defaults.HoldDuration
prompt.ActionText = defaults.ActionText
prompt.ObjectText = defaults.ObjectText
prompt.KeyboardKeyCode = defaults.KeyboardKeyCode
prompt.GamepadKeyCode = defaults.GamepadKeyCode
prompt.ClickablePrompt = defaults.ClickablePrompt
prompt.Enabled = defaults.Enabled
prompt.UIOffset = defaults.UIOffset
prompt.Style = defaults.Style
end
local function findLocalNest()
local map = Workspace:FindFirstChild("Map")
if not map then return nil end
local nestsFolder = map:FindFirstChild("Nests")
if not nestsFolder then return nil end
for _, nest in ipairs(nestsFolder:GetChildren()) do
local sign = nest:FindFirstChild("NestOwnerSign")
if sign then
local surfaceGui = sign:FindFirstChild("SurfaceGui")
if surfaceGui then
local playerUsername = surfaceGui:FindFirstChild("PlayerUsername")
if playerUsername and playerUsername:IsA("TextLabel") then
local expectedText = player.Name .. "'s Nest"
if playerUsername.Text == expectedText then
return nest
end
end
end
end
end
return nil
end
local function setupAutoSell()
local nest = findLocalNest()
if not nest then return end
local queenPoint = nest:FindFirstChild("QueenPoint")
if not queenPoint then return end
local prompt = queenPoint:FindFirstChild("ProximityPrompt")
if not prompt or not prompt:IsA("ProximityPrompt") then return end
currentPrompt = prompt
savedDefaults = capturePromptDefaults(prompt)
prompt.MaxActivationDistance = 999999
prompt.RequiresLineOfSight = false
local function tryTriggerPrompt()
if prompt.Enabled then
task.wait(0.01)
pcall(function()
ProximityPromptService:PromptTriggered(prompt, player)
end)
end
end
promptConn = prompt:GetPropertyChangedSignal("Enabled"):Connect(function()
if prompt.Enabled and autoSellEnabled then
tryTriggerPrompt()
end
end)
if prompt.Enabled then
tryTriggerPrompt()
end
resetKeyConn = UserInputService.InputBegan:Connect(function(input, processed)
if not processed and input.KeyCode == Enum.KeyCode.R and autoSellEnabled and currentPrompt then
resetPromptToDefault(currentPrompt, savedDefaults)
end
end)
end
local function teardownAutoSell()
if resetKeyConn then resetKeyConn:Disconnect() resetKeyConn = nil end
if promptConn then promptConn:Disconnect() promptConn = nil end
if currentPrompt and savedDefaults then
resetPromptToDefault(currentPrompt, savedDefaults)
end
currentPrompt = nil
savedDefaults = nil
end
local MainGroup = Tabs.Main:AddRightGroupbox("Auto Sell", "shopping-bag")
MainGroup:AddToggle("AutoSellToggle", {
Text = "Silent Sell",
Default = false,
Callback = function(enabled)
autoSellEnabled = enabled
if enabled then
setupAutoSell()
else
teardownAutoSell()
end
end,
})
end
do
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local purchaseRemote = ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("UI"):WaitForChild("PurchaseItem")
local gameContent = ReplicatedStorage:WaitForChild("GameContent")
local backpacksFolder = gameContent:WaitForChild("Backpacks")
local toolsFolder = gameContent:WaitForChild("Tools")
local function getItemNames(folder)
local names = {}
for _, itemFolder in ipairs(folder:GetChildren()) do
if itemFolder:IsA("Folder") then
table.insert(names, itemFolder.Name)
end
end
table.sort(names)
return names
end
local function getItemPriceFromFolder(folder, itemName)
local itemFolder = folder:FindFirstChild(itemName)
if not itemFolder then return nil end
local configScript = itemFolder:FindFirstChild("Config")
if not configScript then return nil end
if configScript:IsA("ModuleScript") then
local ok, cfg = pcall(function() return require(configScript) end)
if ok and cfg and cfg["Price"] then
return tonumber(cfg["Price"])
end
elseif configScript:IsA("Script") then
local src = configScript.Source
local price = string.match(src, '%["Price"%]%s*=%s*(%d+)')
if price then
return tonumber(price)
end
end
return nil
end
local ShopGroup = Tabs.Main:AddRightGroupbox("Shop", "shopping-cart")
local toolNames = getItemNames(toolsFolder)
local backpackNames = getItemNames(backpacksFolder)
table.insert(toolNames, 1, "None")
table.insert(backpackNames, 1, "None")
ShopGroup:AddDropdown("ShopTool", {
Values = toolNames,
Default = toolNames[1],
Multi = false,
Text = "Tools",
Searchable = true,
FormatDisplayValue = function(value)
if value == "None" or value == nil or value == "" then return "None" end
local price = getItemPriceFromFolder(toolsFolder, value)
if price then
return string.format("%s | Цена: %d", value, price)
end
return value
end,
})
ShopGroup:AddDropdown("ShopBackpack", {
Values = backpackNames,
Default = backpackNames[1],
Multi = false,
Text = "Backpacks",
Searchable = true,
FormatDisplayValue = function(value)
if value == "None" or value == nil or value == "" then return "None" end
local price = getItemPriceFromFolder(backpacksFolder, value)
if price then
return string.format("%s | Цена: %d", value, price)
end
return value
end,
})
ShopGroup:AddButton("Buy Selected Item", function()
local tool = Options.ShopTool and Options.ShopTool.Value or nil
local backpack = Options.ShopBackpack and Options.ShopBackpack.Value or nil
local category, itemName
if tool and tool ~= "" and tool ~= "None" then
category = "Tools"
itemName = tool
elseif backpack and backpack ~= "" and backpack ~= "None" then
category = "Backpacks"
itemName = backpack
end
if not category or not itemName then
Library:Notify("Select an item in Tools or Backpacks", 3)
return
end
local args = { category, itemName, 1 }
pcall(function()
purchaseRemote:FireServer(unpack(args))
end)
end)
ShopGroup:AddButton("Update Item List", function()
local newTools = getItemNames(toolsFolder)
local newBackpacks = getItemNames(backpacksFolder)
table.insert(newTools, 1, "None")
table.insert(newBackpacks, 1, "None")
Options.ShopTool:SetValues(newTools)
Options.ShopBackpack:SetValues(newBackpacks)
if #newTools > 0 and not Options.ShopTool.Value then
Options.ShopTool:SetValue(newTools[1])
end
if #newBackpacks > 0 and not Options.ShopBackpack.Value then
Options.ShopBackpack:SetValue(newBackpacks[1])
end
end)
endComments section coming soon...





