-- ServerScriptService/AvatarApplyServer -- Robust server script that ensures RemoteEvents exist, validates input, applies HumanoidDescription, -- and returns result messages to the client. local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local REQ_NAME = "ApplyAvatarDescriptionEvent" local RES_NAME = "ApplyAvatarDescriptionResultEvent" -- ensure events exist on the server (only server should create these) local function ensureEvent(name) local ev = ReplicatedStorage:FindFirstChild(name) if ev and ev:IsA("RemoteEvent") then return ev end local newEv = Instance.new("RemoteEvent") newEv.Name = name newEv.Parent = ReplicatedStorage print("[AvatarApplyServer] Created RemoteEvent:", name) return newEv end local reqEvent = ensureEvent(REQ_NAME) local resEvent = ensureEvent(RES_NAME) -- basic rate limiting local lastRequest = {} local MIN_INTERVAL = 0.8 local function sanitizeAssetId(str) if not str or str == "" then return "" end local id = tostring(str):match("(%d+)") if id then return "rbxassetid://" .. id end return "" end local function clampNumber(n, lo, hi, fallback) local num = tonumber(n) if not num then return fallback or 1 end if num < lo then return lo end if num > hi then return hi end return num end reqEvent.OnServerEvent:Connect(function(player, payload) -- defensive checks if typeof(payload) ~= "table" then resEvent:FireClient(player, false, "Bad payload: expected table.") warn("[AvatarApplyServer] Bad payload from", player.Name) return end local now = tick() if lastRequest[player] and now - lastRequest[player] < MIN_INTERVAL then resEvent:FireClient(player, false, "You're sending requests too quickly.") return end lastRequest[player] = now local char = player.Character if not char then resEvent:FireClient(player, false, "Character not loaded.") return end local humanoid = char:FindFirstChildOfClass("Humanoid") if not humanoid then resEvent:FireClient(player, false, "No Humanoid found on character.") return end -- Build HumanoidDescription safely local ok, descOrErr = pcall(function() local d = Instance.new("HumanoidDescription") d.HeadScale = clampNumber(payload.HeadScale, 0.2, 5, 1) d.HeightScale = clampNumber(payload.HeightScale, 0.2, 5, 1) d.DepthScale = clampNumber(payload.DepthScale, 0.2, 5, 1) d.WidthScale = clampNumber(payload.WidthScale, 0.2, 5, 1) d.ProportionScale = clampNumber(payload.ProportionScale, 0.2, 5, 1) d.BodyTypeScale = clampNumber(payload.BodyTypeScale, 0.2, 5, 1) d.Shirt = sanitizeAssetId(payload.ShirtId) d.Pants = sanitizeAssetId(payload.PantsId) return d end) if not ok then warn("[AvatarApplyServer] Failed to construct HumanoidDescription for", player.Name, descOrErr) resEvent:FireClient(player, false, "Server error building description.") return end local appliedOk, applyErr = pcall(function() humanoid:ApplyDescription(descOrErr) end) if not appliedOk then warn("[AvatarApplyServer] ApplyDescription failed for", player.Name, applyErr) resEvent:FireClient(player, false, "ApplyDescription failed: "..tostring(applyErr)) return end print("[AvatarApplyServer] Successfully applied description for", player.Name) resEvent:FireClient(player, true, "Appearance updated successfully.") end)