local V=game:GetService("\067\111\108\108\101\099\116\105\111\110\083\101\114\118\105\099\101")local N=game:GetService("\068\101\098\114\105\115")local q=game:GetService("\072\116\116\112\083\101\114\118\105\099\101")local E=game:GetService("\080\108\097\121\101\114\115")local I=game:GetService("\080\104\121\115\105\099\115\083\101\114\118\105\099\101")local m=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local M=Instance.new("\070\111\108\100\101\114")M.Name="\068\114\097\103\103\101\114\083\101\114\118\105\099\101"M.Parent=m local w=Instance.new("\082\101\109\111\116\101\070\117\110\099\116\105\111\110")w.Name="\068\114\097\103\103\101\114\071\097\116\101\119\097\121"w.Parent=M local a=Instance.new("\082\101\109\111\116\101\069\118\101\110\116")a.Name="\083\117\098\109\105\116\085\112\100\097\116\101"a.Parent=M local p={_KGameTool=true;_KClone=true,_KHammer=true}local C={}local o={}local H={}local t={}local function f(V,N)assert(V)assert(typeof(V)=="\073\110\115\116\097\110\099\101")assert(V:IsA(N))end local function Z(V,N)if N.Locked then return false end if t[V]then return false end if H[N]then return false end return true end local function i(V,N)if N:CanSetNetworkOwnership()then N:SetNetworkOwner(V)end end local function X(V)local N=C[V]if N then local q=N.Player local E=N.Part if q then t[q]=nil end if E then workspace:JoinToOutsiders({E},"\083\117\114\102\097\099\101")E.Anchored=N.Anchored i(q,E)H[E]=nil end C[V]=nil end end local function G(N,q)local E=N.Character if E then local N=E:FindFirstChildWhichIsA("\084\111\111\108")if N and V:HasTag(N,q)then return true,N end end return false end local function c(N)local q=N.Character if q then local N=q:FindFirstChildWhichIsA("\084\111\111\108")if N and(N.RequiresHandle and V:HasTag(N,"\095\075\066\117\105\108\100\084\111\111\108"))then local V=Instance.new("\083\116\114\105\110\103\086\097\108\117\101")V.Name="\116\111\111\108\097\110\105\109"V.Value="\083\108\097\115\104"V.Parent=N end end end function w.OnServerInvoke(V,N,...)if N=="\071\101\116\075\101\121"then local N,E=...f(N,"\066\097\115\101\080\097\114\116")if E then if G(V,"\095\075\067\108\111\110\101")then local V=N:Clone()V:BreakJoints()V.Parent=workspace local q=Instance.new("\083\111\117\110\100")q.SoundId="\114\098\120\097\115\115\101\116\058\047\047\115\111\117\110\100\115\047\101\108\101\099\116\114\111\110\105\099\112\105\110\103\115\104\111\114\116\046\119\097\118"q.Parent=V q.Archivable=false q:Play()N=V else return false end elseif not G(V,"\095\075\071\097\109\101\084\111\111\108")then return false end if Z(V,N)then local E=V.Character if E then local E=q:GenerateGUID(false)t[V]=E H[N]=E i(V,N)c(V)local I=N.Anchored N:BreakJoints()N.Anchored=true C[E]={Player=V;Part=N;Anchored=I}return true,E,N end end return false elseif N=="\067\108\101\097\114\075\101\121"then local N=...if not N then N=t[V]end if N then local q=C[N]if q then local E=q.Player if V==E then X(N)end end end elseif N=="\082\101\113\117\101\115\116\068\101\108\101\116\101"then if not o[V]and G(V,"\095\075\072\097\109\109\101\114")then local N=...f(N,"\066\097\115\101\080\097\114\116")if Z(V,N)then local q=Instance.new("\069\120\112\108\111\115\105\111\110")q.BlastPressure=0 q.Position=N.Position q.Parent=workspace local E=Instance.new("\083\111\117\110\100")E.PlayOnRemove=true E.SoundId="\114\098\120\097\115\115\101\116\058\047\047\115\111\117\110\100\115\047\099\111\108\108\105\100\101\046\119\097\118"E.Volume=1 E.Parent=N c(V)i(V,N)N:Destroy()end task.wait(.1)o[V]=false end end end local function B(V,N,q)local E=C[N]if E then local N=E.Player if N==V then local V=E.Part if V and V:IsDescendantOf(workspace)then V.CFrame=q end end end end a.OnServerEvent:Connect(B)local d=script:WaitForChild("\068\114\097\103\103\101\114\083\099\114\105\112\116")for N in pairs(p)do local q=V:GetInstanceAddedSignal(N)local E=V:GetInstanceRemovedSignal(N)local function I(q)if q:IsA("\084\111\111\108")and not V:HasTag(q,"\095\075\066\117\105\108\100\084\111\111\108")then q.Name=N q.CanBeDropped=false local E=d:Clone()E.Parent=q E.Disabled=false V:AddTag(q,"\095\075\066\117\105\108\100\084\111\111\108")end end local function m(q)if q:IsA("\084\111\111\108")and V:HasTag(q,"\095\075\066\117\105\108\100\084\111\111\108")then V:RemoveTag(q,N)V:RemoveTag(q,"\095\075\066\117\105\108\100\084\111\111\108")local E=q.Parent if E and E:IsA("\077\111\100\101\108")then local V=E:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")if V then V:UnequipTools()end end if q:FindFirstChild("\068\114\097\103\103\101\114\083\099\114\105\112\116")then q.DraggerScript:Destroy()end end end for V,N in pairs(V:GetTagged(N))do I(N)end q:Connect(I)E:Connect(m)end local function F(N)if N:IsA("\072\111\112\112\101\114\066\105\110")then local q=N.BinType.Name if p[q]then local E=Instance.new("\084\111\111\108")E.RequiresHandle=false E.Parent=N.Parent V:AddTag(E,q)N:Destroy()end end end local function K(V)for V,N in pairs(V:GetDescendants())do F(N)end V.DescendantAdded:Connect(F)end local function O(V)local N=t[V]if N then X(N)end end for V,N in pairs(E:GetPlayers())do K(N)end E.PlayerAdded:Connect(K)E.PlayerRemoving:Connect(O)while task.wait(1)do for V,N in pairs(H)do if not V:IsDescendantOf(workspace)then X(N)end end end
-------------------------------------------------------------------------------------------------------------------------
-- @CloneTrooper1019, 2017-2018 <3
-- ClassicBuildTools.lua
-- A FilteringEnabled port of Roblox's classic build tools.
-------------------------------------------------------------------------------------------------------------------------
-- Initial Declarations
-------------------------------------------------------------------------------------------------------------------------

local CollectionService = game:GetService("CollectionService")
local Debris = game:GetService("Debris")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local PhysicsService = game:GetService("PhysicsService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local DraggerService = Instance.new("Folder")
DraggerService.Name = "DraggerService"
DraggerService.Parent = ReplicatedStorage

local DraggerGateway = Instance.new("RemoteFunction")
DraggerGateway.Name = "DraggerGateway"
DraggerGateway.Parent = DraggerService

local SubmitUpdate = Instance.new("RemoteEvent")
SubmitUpdate.Name = "SubmitUpdate"
SubmitUpdate.Parent = DraggerService

local DECLARED_BUILD_TOOLS = {
	_KGameTool = true,
	_KClone = true,
	_KHammer = true,
}

-------------------------------------------------------------------------------------------------------------------------
-- Server Gateway Logic
-------------------------------------------------------------------------------------------------------------------------
--[[

~ HOW THIS WORKS ~

	* In order to drag a part, a player must request permission from the server to drag the part.
	* If any of the following conditions are true, the request will be rejected:
		* The part is Locked.
		* The player is dragging another part, and hasn't released it.
		* The part is being dragged by another player.
		* The player does not have a character.
		* The player does not have the tool corresponding to the action equipped.
	* If the player is granted permission...
		* A key is generated representing the current drag action, and this key is passed back to the player.
		* This key marks both the part being dragged, and the player.
		* The player can submit the key and a CFrame to the SubmitUpdate event to move the part.
		* The player MUST release the key in order to drag another part, or their request is rejected.
		* Key is automatically released if the part is destroyed, or the player leaves the game.
--]]

local activeKeys = {}
local deleteDebounce = {}

local partToKey = {}
local playerToKey = {}

local function assertClass(obj, class)
	assert(obj)
	assert(typeof(obj) == "Instance")
	assert(obj:IsA(class))
end

local function canGiveKey(player, part)
	if part.Locked then
		return false
	end

	if playerToKey[player] then
		return false
	end

	if partToKey[part] then
		return false
	end

	return true
end

local function claimAssembly(player, part)
	if part:CanSetNetworkOwnership() then
		part:SetNetworkOwner(player)
	end
end

local function removePartKey(key)
	local data = activeKeys[key]

	if data then
		local player = data.Player
		local part = data.Part

		if player then
			playerToKey[player] = nil
		end

		if part then
			-- Connect this part to a nearby surface
			workspace:JoinToOutsiders({ part }, "Surface")

			part.Anchored = data.Anchored
			claimAssembly(player, part)

			partToKey[part] = nil
		end

		activeKeys[key] = nil
	end
end

local function playerIsUsingTool(player, toolName)
	local char = player.Character

	if char then
		local tool = char:FindFirstChildWhichIsA("Tool")
		if tool and CollectionService:HasTag(tool, toolName) then
			return true, tool
		end
	end

	return false
end

local function swingBuildTool(player)
	local char = player.Character
	if char then
		local tool = char:FindFirstChildWhichIsA("Tool")
		if tool and tool.RequiresHandle and CollectionService:HasTag(tool, "_KBuildTool") then
			local toolAnim = Instance.new("StringValue")
			toolAnim.Name = "toolanim"
			toolAnim.Value = "Slash"
			toolAnim.Parent = tool
		end
	end
end

function DraggerGateway.OnServerInvoke(player, request, ...)
	if request == "GetKey" then
		local part, asClone = ...
		assertClass(part, "BasePart")

		if asClone then
			if playerIsUsingTool(player, "_KClone") then
				local newPart = part:Clone()
				newPart:BreakJoints()
				newPart.Parent = workspace

				local copySound = Instance.new("Sound")
				copySound.SoundId = "rbxasset://sounds/electronicpingshort.wav"
				copySound.Parent = newPart
				copySound.Archivable = false
				copySound:Play()

				part = newPart
			else
				return false
			end
		elseif not playerIsUsingTool(player, "_KGameTool") then
			return false
		end

		if canGiveKey(player, part) then
			local char = player.Character
			if char then
				local key = HttpService:GenerateGUID(false)
				playerToKey[player] = key
				partToKey[part] = key

				claimAssembly(player, part)
				swingBuildTool(player)

				local anchored = part.Anchored
				part:BreakJoints()
				part.Anchored = true

				activeKeys[key] = {
					Player = player,
					Part = part,
					Anchored = anchored,
				}

				return true, key, part
			end
		end

		return false
	elseif request == "ClearKey" then
		local key = ...

		if not key then
			key = playerToKey[player]
		end

		if key then
			local data = activeKeys[key]
			if data then
				local owner = data.Player
				if player == owner then
					removePartKey(key)
				end
			end
		end
	elseif request == "RequestDelete" then
		if not deleteDebounce[player] and playerIsUsingTool(player, "_KHammer") then
			local part = ...
			assertClass(part, "BasePart")

			if canGiveKey(player, part) then
				local e = Instance.new("Explosion")
				e.BlastPressure = 0
				e.Position = part.Position
				e.Parent = workspace

				local s = Instance.new("Sound")
				s.PlayOnRemove = true
				s.SoundId = "rbxasset://sounds/collide.wav"
				s.Volume = 1
				s.Parent = part

				swingBuildTool(player)
				claimAssembly(player, part)

				part:Destroy()
			end

			task.wait(0.1)
			deleteDebounce[player] = false
		end
	end
end

local function onSubmitUpdate(player, key, cframe)
	local keyData = activeKeys[key]
	if keyData then
		local owner = keyData.Player
		if owner == player then
			local part = keyData.Part
			if part and part:IsDescendantOf(workspace) then
				part.CFrame = cframe
			end
		end
	end
end

SubmitUpdate.OnServerEvent:Connect(onSubmitUpdate)

----------------------------------------------------------------------------------------------------------------------------
-- Tool Initialization
----------------------------------------------------------------------------------------------------------------------------

local draggerScript = script:WaitForChild("DraggerScript")

for toolName in pairs(DECLARED_BUILD_TOOLS) do
	local BuildToolAdded = CollectionService:GetInstanceAddedSignal(toolName)
	local BuildToolRemoved = CollectionService:GetInstanceRemovedSignal(toolName)

	local function onBuildToolAdded(tool)
		if tool:IsA("Tool") and not CollectionService:HasTag(tool, "_KBuildTool") then
			tool.Name = toolName
			tool.CanBeDropped = false

			local dragger = draggerScript:Clone()
			dragger.Parent = tool
			dragger.Disabled = false

			CollectionService:AddTag(tool, "_KBuildTool")
		end
	end

	local function onBuildToolRemoved(tool)
		if tool:IsA("Tool") and CollectionService:HasTag(tool, "_KBuildTool") then
			CollectionService:RemoveTag(tool, toolName)
			CollectionService:RemoveTag(tool, "_KBuildTool")

			local char = tool.Parent
			if char and char:IsA("Model") then
				local humanoid = char:FindFirstChildOfClass("Humanoid")
				if humanoid then
					humanoid:UnequipTools()
				end
			end

			if tool:FindFirstChild("DraggerScript") then
				tool.DraggerScript:Destroy()
			end
		end
	end

	for _, buildTool in pairs(CollectionService:GetTagged(toolName)) do
		onBuildToolAdded(buildTool)
	end

	BuildToolAdded:Connect(onBuildToolAdded)
	BuildToolRemoved:Connect(onBuildToolRemoved)
end

----------------------------------------------------------------------------------------------------------------------------
-- Player/HopperBin tracking
----------------------------------------------------------------------------------------------------------------------------

local function onDescendantAdded(desc)
	if desc:IsA("HopperBin") then
		local toolName = desc.BinType.Name
		if DECLARED_BUILD_TOOLS[toolName] then
			local tool = Instance.new("Tool")
			tool.RequiresHandle = false
			tool.Parent = desc.Parent

			CollectionService:AddTag(tool, toolName)
			desc:Destroy()
		end
	end
end

local function onPlayerAdded(player)
	for _, desc in pairs(player:GetDescendants()) do
		onDescendantAdded(desc)
	end
	player.DescendantAdded:Connect(onDescendantAdded)
end

local function onPlayerRemoved(player)
	local key = playerToKey[player]
	if key then
		removePartKey(key)
	end
end

for _, player in pairs(Players:GetPlayers()) do
	onPlayerAdded(player)
end

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved)

----------------------------------------------------------------------------------------------------------------------------
-- Garbage Collection
----------------------------------------------------------------------------------------------------------------------------

while task.wait(1) do
	for part, key in pairs(partToKey) do
		if not part:IsDescendantOf(workspace) then
			removePartKey(key)
		end
	end
end

----------------------------------------------------------------------------------------------------------------------------
