null nil true false StellarX Studio Builder 0 and parts==#job.actions and parts<=90 pending.Text=(safeAuto and "Auto Build (parts only):\n" or "Waiting for your approval:\n").. tostring(job.title or "Build").."\n"..parts.." parts and "..scripts.." disabled scripts." setButtonState(true) if safeAuto and os.clock()-lastAutoBuild>=30 then lastAutoBuild=os.clock() task.defer(function() if handle and currentJob and currentJob.id==job.id and not busy and autoBuild then handle(true) end end) end else currentJob=nil setButtonState(false) pending.Text="No build waiting. Describe something on the StellarX website." end end local function number(v,limit) return type(v)=="number" and v==v and v>=-limit and v<=limit end local function coordinates(v,limit,positive) if type(v)~="table" or #v~=3 then return nil end for i=1,3 do if not number(v[i],limit) or (positive and v[i]<.05) then return nil end end return Vector3.new(v[1],v[2],v[3]) end local permittedMaterials={ SmoothPlastic=true,Plastic=true,Asphalt=true,Concrete=true,Wood=true, Grass=true,Ground=true,Metal=true,Glass=true,Neon=true,Brick=true, Fabric=true,Cobblestone=true,Granite=true,Sand=true,Slate=true } local function verify(actions) if type(actions)~="table" or #actions<1 or #actions>90 then error("The requested build has too many changes.") end for _,a in ipairs(actions) do if type(a)~="table" or type(a.name)~="string" or #a.name<1 or #a.name>75 then error("A build object has an invalid name.") end if a.type=="part" then if not coordinates(a.size,500,true) or not coordinates(a.position,15000,false) then error("A part has unsafe dimensions or position.") end if a.color and (type(a.color)~="string" or not a.color:match("^#%x%x%x%x%x%x$")) then error("A part has an invalid colour.") end if a.material and not permittedMaterials[a.material] then error("A part has an unsupported material.") end if a.shape and a.shape~="Block" and a.shape~="Ball" and a.shape~="Cylinder" then error("Unsupported part shape.") end elseif a.type=="script" then if type(a.source)~="string" or #a.source>14000 then error("A generated script is invalid.") end else error("Unsupported action. No changes were made.") end end end local function folder(parent,name) local f=parent:FindFirstChild(name) if f and not f:IsA("Folder") then error(name.." is not a folder") end if not f then f=Instance.new("Folder");f.Name=name;f.Parent=parent end return f end local function safeFolderName(value) return (tostring(value):gsub("[^%w_%- ]",""):sub(1,38)) end local function apply(actions,id,title) verify(actions) local selected=Selection:Get() local offset=Vector3.zero local first=selected[1] if first then if first:IsA("BasePart") then offset=first.Position elseif first:IsA("Model") then offset=first:GetPivot().Position end end local parent=folder(workspace,"StellarGenerated") local run=Instance.new("Folder") run.Name=safeFolderName(title).."_"..id:sub(1,8) local scriptRoot=nil local scriptGroup=nil local ok,err=pcall(function() for _,a in ipairs(actions) do if a.type=="part" then local part=Instance.new("Part") part.Name=a.name part.Anchored=true part.Size=coordinates(a.size,500,true) part.Position=offset+coordinates(a.position,15000,false) if a.color then part.Color=Color3.fromHex(a.color) end if a.material then part.Material=Enum.Material[a.material] end if a.shape then part.Shape=Enum.PartType[a.shape] end part.Parent=run elseif a.type=="script" then if not scriptRoot then scriptRoot=folder(ServerScriptService,"StellarGeneratedScripts") end if not scriptGroup then scriptGroup=Instance.new("Folder") scriptGroup.Name=run.Name end local scriptObject=Instance.new("Script") scriptObject.Name=a.name scriptObject.Disabled=true scriptObject.Source=a.source scriptObject.Parent=scriptGroup end end if #run:GetChildren()>0 then run.Parent=parent else run:Destroy() end if scriptGroup then scriptGroup.Parent=scriptRoot end end) if not ok then pcall(function()run:Destroy()end) if scriptGroup then pcall(function()scriptGroup:Destroy()end) end error(err) end pcall(function() ChangeHistoryService:SetWaypoint("StellarX builder: "..safeFolderName(title)) end) end local function finish(id,result,note) local ok,reply=pcall(request,"stellar_studio_finish",{ p_code=code,p_job=id,p_status=result,p_note=tostring(note or ""):sub(1,260) }) return ok and reply==true end handle=function(accepted) if busy or not currentJob then return end busy=true local job=currentJob setButtonState(false) pending.Text=accepted and "Building inside Studio. Please wait..." or "Rejecting build..." task.spawn(function() local statusValue="rejected" local reason="Rejected in Roblox Studio" if accepted then local ok,err=pcall(apply,job.actions,job.id,job.title) statusValue=ok and "applied" or "failed" reason=ok and "Added into StellarGenerated. Scripts disabled." or tostring(err) if ok then completed[job.id]=true end else completed[job.id]=true end local acknowledged=finish(job.id,statusValue,reason) if acknowledged then pending.Text=accepted and (statusValue=="applied" and "Build added to your game. Review your map and save it." or "Build failed: "..reason) or "Build rejected. No changes made." else pending.Text="Local action finished, but the website did not confirm it. Do not run this job again. Check connection." end currentJob=nil busy=false task.wait(1) poll() end) end autoToggle.MouseButton1Click:Connect(function() autoBuild=not autoBuild autoToggle.Text=autoBuild and "Auto Build: ON (parts only)" or "Auto Build: OFF (safe parts only)" pending.Text=autoBuild and "Auto Build ON for parts only. Scripts still need approval." or "Auto Build OFF. All builds require manual approval." if autoBuild then task.defer(poll) end end) approve.MouseButton1Click:Connect(function()if currentJob and not busy then handle(true)end end) reject.MouseButton1Click:Connect(function()if currentJob and not busy then handle(false)end end) refresh.MouseButton1Click:Connect(function()task.spawn(poll)end) openWeb.MouseButton1Click:Connect(function() status.Text="Open "..BUILDER_URL.." in your browser, sign in, then enter the code shown above." -- The website address is shown above. This button never runs commands. end) toggle.Click:Connect(function()widget.Enabled=not widget.Enabled;if widget.Enabled then task.spawn(poll) end end) task.spawn(function() while true do if not busy then poll() end task.wait(7) end end) ]]>