[{"data":1,"prerenderedAt":96},["ShallowReactive",2],{"site":3,"config-slug-site":15,"config-product-th-x3d-skin":21,"config-public-x3d-skin":91},{"site":4,"contact":10,"seo":13,"payment":14},{"name":5,"host":6,"default_locale":7,"locales":8},"X3D Developer","fivem.x3d-developer.com","th",[7,9],"en",{"discord_invite":11,"email":12,"line":12},"https:\u002F\u002Fdiscord.gg\u002FNA5kPVynFv","",{"google_site_verification":12,"bing_site_verification":12},{"bank_name":12,"account_name":12,"account_no":12,"promptpay_id":12},{"site":16,"contact":18,"seo":19,"payment":20},{"name":5,"host":6,"default_locale":7,"locales":17},[7,9],{"discord_invite":11,"email":12,"line":12},{"google_site_verification":12,"bing_site_verification":12},{"bank_name":12,"account_name":12,"account_no":12,"promptpay_id":12},{"id":22,"slug":23,"name":24,"summary":25,"price_thb":26,"license_mode":27,"cover_key":28,"cover_url":29,"category_slugs":30,"tags":32,"latest_version":50,"latest_released_at":51,"published_at":52,"has_docs":53,"config":54,"rent_price_satang":55,"description_md":56,"docs_md":57,"seo_title":58,"seo_description":59,"media":60,"versions":72},"7c86bf83-0df0-4e59-ab59-461ac4a2bff8","x3d-skin","X3D ตกแต่งตัวละคร","หน้าตกแต่งตัวละคร 77 ช่อง กล้องหมุนซูม ท่าโพส ไฟส่องหน้า ไม่ต้องลง skinchanger ไม่ต้องลงฐานข้อมูล ต่อกับเฟรมเวิร์กไหนก็ได้",0,"none","public\u002Fproducts\u002Fx3d-skin\u002Fcover\u002Fdb520ac6e2e3d502.jpg","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-skin\u002Fcover\u002Fdb520ac6e2e3d502.jpg",[31],"hud",[33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49],"esx","standalone","ตกแต่งตัวละคร","skin","character customization","skin creator","แต่งตัวละคร","ร้านเสื้อผ้า","ร้านตัดผม","ฟรี","free","ตู้เสื้อผ้า","ร้านเสริมสวย","ร้านหน้ากาก","ท่าโพส","แต่งหน้า","ไม่ต้องใช้ skinchanger","1.5.4","2026-10-12T17:21:14.159219Z","2026-09-22T04:02:41.988907Z",true,"public",null,"# หน้าตกแต่งตัวละคร — ฟรี ไม่ต้องลง skinchanger ไม่ต้องลงฐานข้อมูล\n\nหน้าแต่งตัวละครแบบเต็ม 77 ช่อง: หน้า ผม เครา เมกอัพ เสื้อผ้า ของประดับ พร้อมกล้องหมุน\u002Fซูม\u002Fเลื่อนมุม ท่าโพส ไฟส่องหน้า และปุ่มซ่อนผู้เล่นคนอื่น `x3d_skin` ทำครบในตัวเอง ผ่านแผง Nuxt 4 UI พร้อมใช้\n\n---\n\n## ฟีเจอร์\n\n- [+] ตั้งค่าง่าย ปรับได้หมดใน config หรือตั้งผ่านเว็บได้เลย\n- [+] แต่งตัวละคร 77 ช่อง หน้า ผม เครา เมกอัพ เสื้อผ้า ของประดับ\n- [+] ไม่ต้องลง skinchanger มี export ชื่อเดียวกันให้สคริปต์เดิมเรียกได้\n- [+] กล้องหมุน ซูม เลื่อนมุม ท่าโพส 4 แบบ ไฟส่องหน้า\n- [+] ปุ่มซ่อนผู้เล่นคนอื่นรัศมี 50 เมตร เวลาลานสร้างตัวละครแน่น\n- [+] ร้านเสื้อผ้า เสริมสวย หน้ากาก มีในตัว พร้อมจุดและ blip\n- [+] ตั้งราคาร้านแต่ละประเภทเอง ใส่ 0 = เข้าใช้ฟรี\n- [+] ตู้เสื้อผ้า เซฟชุดตั้งชื่อ จำกัดจำนวนชุดต่อคนได้\n- [+] สลับหน้าสำเร็จรูป 46 แบบ เป็นระบบพ่อ\u002Fแม่ ดัดจมูก แก้ม คางได้\n- [+] ใช้ร่วมกับ skinchanger \u002F esx_skin เดิมได้ ผ่าน Config.Backend\n- [+] ไม่ต้องลงฐานข้อมูล เก็บเป็นไฟล์ JSON หรือสลับเป็น MySQL ได้\n- [+] เขียนเชื่อมกับสคริปต์อื่นได้ที่ addons\u002F\n\n---\n\n## ไม่ต้องลง skinchanger — ตัวใส่ค่าลงร่างอยู่ในสคริปต์นี้เอง\n\n`skin.lua` ใช้ native ของเกมล้วน ๆ และมี export ชื่อเดียวกับที่สคริปต์อื่นคุ้นเคย (`GetSkin` \u002F `LoadSkin` \u002F `LoadClothes` \u002F `Change`) ร้านเสื้อผ้าหรือระบบยูนิฟอร์มที่เคยเรียก skinchanger ย้ายมาชี้ที่ `x3d_skin` ได้ทันที รายการช่องทั้งหมดอยู่ใน `components.lua` พร้อมค่าเริ่มต้น เพดาน และระยะกล้องต่อช่อง — เพดานจริงถามจากเกมตอนรัน ไม่ฮาร์ดโค้ด ชุด addon ที่เซิร์ฟลงเพิ่มจึงเลือกได้ครบ\n\n## กล้องเลื่อนตามช่องที่เลือกเอง แต่ไม่แย่งมือผู้เล่น\n\nเลือกทรงผม กล้องซูมเข้าหน้า เลือกรองเท้า กล้องลงไปที่เท้า พอผู้เล่นหมุนหรือซูมเอง กล้องจะหยุดขยับเองภายในหมวดนั้นจนกว่าจะเปลี่ยนหมวด · LMB ลากหมุนตัว RMB ลากเลื่อนมุม Scroll ซูม · ท่าโพส 4 แบบ ไฟส่องหน้า 3 ดวง และซ่อนผู้เล่นคนอื่นรัศมี 50 เมตรเวลาที่ลานสร้างตัวละครแน่น\n\n## ร้านตัดผม\u002Fร้านเสื้อผ้าเรียกใช้ได้ โดยจำกัดช่องที่แก้ได้\n\nเปิดพาเนลแบบล็อกเฉพาะช่องที่ร้านขาย ใส่ราคาแล้วปุ่มยืนยันกลายเป็น \"ซื้อ\" พร้อมราคา มี callback ตอนกดยืนยัน\u002Fยกเลิกให้ตัดเงินเอง (สคริปต์นี้ไม่แตะเงินของใคร) และมี hook `x3d_skin:onSave` ฝั่งเซิร์ฟเวอร์แจ้งทุกครั้งที่ผู้เล่นเซฟหน้าใหม่\n\n## ไม่ต้องลงฐานข้อมูล\n\nหน้าตาที่ผู้เล่นเซฟเก็บเป็นไฟล์ JSON ในตัว resource เอง คีย์เป็น identifier ถาวรไม่ใช่ server id เขียนลงดิสก์ตามรอบ ตอนผู้เล่นออก และตอนปิด resource อยากได้ MySQL? สลับ 4 ฟังก์ชันในไฟล์เดียวไปใช้บล็อก oxmysql ที่คอมเมนต์ไว้ท้ายไฟล์ พร้อม `install.sql`\n\nค่าที่พาเนลส่งมาไม่เชื่อสักตัว — ชื่อช่องต้องรู้จัก ค่าต้อง floor และ clamp เข้าช่วง เซฟได้ 1 ครั้ง\u002Fวินาที\u002Fคน และ `\u002Fskin \u003Cid>` ต้องมี ace เสมอ\n\n## ต้องมี\n\nไม่มี · ไม่ต้องใช้ skinchanger ไม่ต้องใช้ฐานข้อมูล ไม่ต้องใช้เฟรมเวิร์ก ไม่มีไลเซนส์ · วางแล้ว `ensure` ได้เลย\n\n**ฟรี** · แก้โค้ดได้ตามใจ · ขอแค่อย่านำไปขายต่อและอย่าอัปโหลดใหม่ในชื่อตัวเอง\n","## การติดตั้ง\n\n1. แตกไฟล์แล้ว **เปลี่ยนชื่อโฟลเดอร์เป็น `x3d_skin`** (สคริปต์อื่นเรียก export ด้วยชื่อนี้)\n2. วางใน `resources\u002F`\n3. เพิ่ม `ensure x3d_skin` ใน `server.cfg`\n\nจบ — ไม่ต้องลงฐานข้อมูล ไม่ต้องลงอะไรเพิ่ม ไม่ต้องแตะ resource เดิมของเซิร์ฟ ใช้ได้ทั้ง ESX, QBCore และเซิร์ฟเปล่า\n\nผู้เล่นเปิดด้วย `\u002Fskin` · แอดมินเปิดให้คนอื่นด้วย `\u002Fskin \u003Cid>`\n\nให้สิทธิ์แอดมิน:\n\n```\nadd_ace group.admin x3d_skin.admin allow\n```\n\n⚠ เซิร์ฟที่มี `esx_skin` อยู่แล้ว มันจด `\u002Fskin` ไว้เหมือนกัน — ตัวที่ `ensure` ทีหลังเป็นคนตอบ วาง `ensure x3d_skin` ไว้หลัง `ensure esx_skin` หรือเปลี่ยน `Config.Command`\n\n## ช่องที่แก้ได้\n\n77 ช่องในโหมดปกติ แบ่งเป็น 6 หมวดในแถบล่าง:\n\n| หมวด | มีอะไร |\n|---|---|\n| พื้นฐาน | เพศ · ใบหน้า · ผิว |\n| ผมและดวงตา | ทรงผม สีผม ไฮไลท์ · สีตา · ทรงคิ้ว สีคิ้ว ความเข้ม |\n| เสื้อผ้า | เสื้อชั้นใน เสื้อ ลวดลาย แขนเสื้อ เกราะ กางเกง รองเท้า (พร้อมช่องสีของแต่ละชิ้น) |\n| เครื่องประดับ | หน้ากาก สร้อยคอ หมวก แว่นตา นาฬิกา กำไล ต่างหู |\n| แต่งหน้า | เมกอัพ ลิปสติก ปัดแก้ม เครา |\n| รายละเอียด | อายุ ตำหนิ สีผิวไม่สม่ำเสมอ รอยแดดเผา ไฝ ขนหน้าอก ตำหนิร่างกาย |\n\nเพดานของแต่ละช่องถามจากเกมตอนรัน (`GetNumberOfPedDrawableVariations` และเพื่อน ๆ) ไม่ได้ฮาร์ดโค้ดไว้ — ลงชุด addon เพิ่มเมื่อไหร่ ผู้เล่นเลือกได้ครบทันทีโดยไม่ต้องแก้ config\n\nเปลี่ยน `Config.AdvancedFace = true` เพื่อสลับจาก \"เลือกหน้าสำเร็จรูป 46 แบบ\" ไปเป็นระบบพ่อ\u002Fแม่ + น้ำหนักหน้า + ดัดจมูก แก้ม คาง ทีละจุดแบบ GTA Online\n\n⚠ สลับค่านี้หลังเปิดเซิร์ฟแล้ว หน้าที่ผู้เล่นเซฟไว้จะเพี้ยน เพราะเป็นคนละชุดค่ากัน\n\n## การควบคุมในพาเนล\n\n| ปุ่ม | ทำอะไร |\n|---|---|\n| LMB + ลาก | หมุนตัวละคร |\n| RMB + ลาก | เลื่อนมุมกล้อง (มีขอบเขต ส่องไปที่อื่นไม่ได้) |\n| Scroll | ซูมเข้า\u002Fออก |\n| Q \u002F E | หมุนตัวละครทีละองศา |\n| คลิกช่อง + Scroll | ปรับค่าช่องนั้น |\n| Shift + Scroll | ปรับทีละ ±10 |\n| ลูกศร | ปรับละเอียด |\n\nปุ่มซ้ายล่าง: โฟกัสหัว · โฟกัสตัว · รีเซ็ตกล้อง · ไฟส่องหน้า · ท่าโพส (4 แบบ) · ซ่อนผู้เล่นคนอื่นในรัศมี 50 เมตร\n\nกล้องเลื่อนไปยังจุดที่กำลังแก้เอง แต่พอผู้เล่นหมุน\u002Fซูมเองแล้ว กล้องจะหยุดขยับเองภายในหมวดนั้น จนกว่าจะเลือกช่องในหมวดอื่น\n\n## เปิดจากร้าน (ร้านตัดผม ร้านเสื้อผ้า)\n\n```lua\nexports['x3d_skin']:OpenEditor({\n    title    = 'ร้านตัดผม',\n    price    = 500,\n    restrict = { 'hair_1', 'hair_2', 'hair_color_1', 'hair_color_2',\n                 'beard_1', 'beard_2', 'beard_3', 'beard_4' },\n    onSubmit = function() TriggerServerEvent('myshop:charge', 500) end,\n    onCancel = function() print('ยกเลิก') end,\n})\n```\n\n`restrict` จำกัดช่องที่แก้ได้ · `price` ทำให้ปุ่มยืนยันกลายเป็น \"ซื้อ\" พร้อมราคา\n\n⚠ ทางนี้ (`OpenEditor` เอง) **ไม่หักเงินให้** — ตัดเงินใน `onSubmit` ของร้านคุณเอง · ร้านที่อยู่ใน `Config.Shops` คนละทาง ตรงนั้นเซิร์ฟเวอร์หักเงินและบันทึกให้ในก้าวเดียว\n\n\n## เข้ากับ skinchanger \u002F esx_skin ที่มีอยู่แล้ว\n\nไม่ต้องตั้งอะไร สคริปต์ดูเองตอนเปิดเซิร์ฟ:\n\n- **มี `skinchanger` อยู่แล้ว** → ใช้ของเดิมใส่เสื้อผ้าลงร่าง และให้ `esx_skin` เก็บชุดทางเดิมของมัน x3d_skin เป็นแค่ UI + ร้าน + ตู้เสื้อผ้า\n- **ไม่มี** → x3d_skin ใส่เองและเก็บเองในไฟล์ JSON\n\nทั้งสองทางไม่ต้อง stop อะไร ไม่ต้องย้ายข้อมูล ตัวละครเก่าอยู่ครบ\n\nบังคับทางใดทางหนึ่งได้ที่ `Config.Backend` (`'skinchanger'` \u002F `'self'`) ถ้าจำเป็น\n\n## มากับซิปด้วย: `optional\u002Fskinchanger` + `optional\u002Fesx_skin`\n\nเซิร์ฟ ESX ส่วนใหญ่มีสองตัวนี้อยู่แล้ว — **มีอยู่แล้วก็ข้ามโฟลเดอร์ `optional\u002F` ไปเลย** `x3d_skin` ทำงานกับของเดิมได้อยู่แล้ว\n\nยังไม่มี? ย้ายออกมาไว้ใน `resources\u002F` แล้ว `ensure` ก่อน `x3d_skin`:\n\n```\nensure skinchanger\nensure esx_skin\nensure x3d_skin\n```\n\n- `skinchanger` = ของ ESX Legacy เดิม ตัดการ `@include` ไฟล์ locale ของ es_extended ออกให้ลงได้โดยไม่ error\n- `esx_skin` = เหลือเฉพาะส่วน API (เก็บคอลัมน์ `skin` + รับ event ชื่อเดิม) ไม่มี UI ซ้อนกับพาเนล และตั้งชื่อตารางผู้เล่นได้ใน config\n\nสองตัวนี้เป็นของ ESX Legacy สัญญาอนุญาต GPL v3 รายละเอียดอยู่ใน `optional\u002FREADME.md`\n\n`esx_skin` ที่แถมมายังมี `esx_skin:save`, callback `esx_skin:getPlayerSkin` และ event เปิดเมนูแบบเก่า — event พวกนี้จะเปิดพาเนลของ x3d_skin ให้ สคริปต์เดิมที่ยังเรียกอยู่จึงใช้ต่อได้\n\n## ร้าน (`Config.Shops`)\n\nร้านเสื้อผ้า 14 จุด ร้านเสริมสวย 7 จุด ร้านหน้ากาก 1 จุด อยู่ในสคริปต์นี้เลย ไม่ต้องลงร้านแยก\n\n- หมุดบนแผนที่โผล่เมื่อเข้าใกล้ 120 เมตร (`blipDistance = 0` = โชว์ตลอด)\n- วงกลมบนพื้น + ป้าย `[E] ร้านเสื้อผ้า ($500)` ภาษาไทยอ่านออก\n- แต่ละประเภทกำหนดราคาและช่องที่แก้ได้เองใน `Config.ShopTypes` พร้อมแท็บย่อย (เสื้อผ้า \u002F เครื่องประดับ ฯลฯ)\n- `Config.Shops.enabled = false` = ปิดร้านทั้งหมด เหลือแค่ `\u002Fskin`\n- ตั้ง `price = 0` = เข้าใช้ฟรี ไม่แตะระบบเงินเลย\n\n**เงินถูกหักและชุดถูกบันทึกในก้าวเดียวกันฝั่งเซิร์ฟเวอร์** ตอนกดยืนยัน เซิร์ฟเวอร์เช็กใหม่หมดว่ายังยืนอยู่ที่ร้านจริง เงินยังพอจริง แล้วค่อยหักและบันทึก หักไม่ผ่าน = ไม่บันทึกอะไรเลย · เขียนไม่ลง = คืนเงินทันที\n\n⚠ ร้านเสื้อผ้าแบบเดิม (สคริปต์ร้านเสื้อผ้าแยก + esx_skin) คิดเงินคนละทางกับที่บันทึกชุด ผู้เล่นที่บล็อกข้อความคิดเงินจะได้ชุดฟรี — ตัวนี้ปิดช่องนั้นแล้ว\n\nต่อระบบเงินของเซิร์ฟตัวเองที่ `addons\u002Fframework\u002Fserver.lua` (ESX มาให้แล้ว QBCore คอมเมนต์รออยู่) ถ้ายังไม่ต่อ ร้านที่มีราคาจะไม่เปิดและบอกให้แจ้งแอดมิน — ไม่แจกฟรี\n\n## ตู้เสื้อผ้า (`Config.Wardrobe`)\n\nเซฟชุดที่ใส่อยู่พร้อมตั้งชื่อ กดใส่ทีเดียวทั้งชุด เปลี่ยนชื่อ ทับชุดเดิม และลบได้ เก็บได้คนละ `maxPerType` ชุด (ค่าเริ่มต้น 20) ชื่อซ้ำกันไม่ได้\n\nชุดที่ใส่จากตู้จะทับเฉพาะเสื้อผ้า **หน้าตาไม่ขยับ** — เก็บหน้าเดิมไว้เสมอ\n\nรายการชุดเป็นของเซิร์ฟเวอร์ ส่งลงมาให้พาเนลทุกครั้งที่มีอะไรเปลี่ยน พาเนลไม่ได้เป็นคนตัดสินว่ามีชุดอะไรบ้าง\n\n## exports ฝั่งเซิร์ฟเวอร์\n\n```lua\nexports['x3d_skin']:GetSkin(src)          --> table หน้าที่เซฟไว้ หรือ nil\nexports['x3d_skin']:SetSkin(src, skin)    --> boolean (ตรวจแบบเดียวกับที่ผู้เล่นเซฟเอง)\nexports['x3d_skin']:OpenEditor(src)       --> boolean\n```\n\n`GetSkin` รับได้ทั้ง server id และ identifier · `SetSkin` ไม่ติด rate limit ระบบยูนิฟอร์มเปลี่ยนชุดให้หลายคนพร้อมกันได้\n\n## exports ฝั่ง client\n\n```lua\nexports['x3d_skin']:GetSkin()\nexports['x3d_skin']:GetMaxValues()\nexports['x3d_skin']:LoadSkin(skin)\nexports['x3d_skin']:LoadClothes(playerSkin, clothesSkin)   -- ทับเฉพาะเสื้อผ้า หน้าไม่ขยับ\nexports['x3d_skin']:Change('torso_1', 5)\nexports['x3d_skin']:OpenEditor(opts)\nexports['x3d_skin']:CloseEditor()\nexports['x3d_skin']:IsOpen()\n```\n\n## hook\n\n```lua\n-- server-internal ไม่ใช่ net event — client ยิงเองไม่ได้\nAddEventHandler('x3d_skin:onSave', function(src, identifier, skin)\n    print(('%s เซฟหน้าใหม่'):format(identifier))\nend)\n```\n\nฝั่ง client มี `x3d_skin:opened` กับ `x3d_skin:closed` ให้สคริปต์อื่นซ่อน HUD ของตัวเองตอนพาเนลเปิด\n\n## ที่เก็บข้อมูล\n\nหน้าตาของผู้เล่นเก็บฝั่งเซิร์ฟเวอร์เป็นไฟล์ JSON เดียว (`Config.Storage.File` ค่าเริ่มต้น `data\u002Fskins.json`) โหลดครั้งเดียวตอน resource เริ่ม เขียนกลับทุก `Config.Storage.FlushSeconds` วินาที ตอนผู้เล่นออก และตอนปิด resource แบบปกติ คีย์ที่ใช้คือ identifier ถาวร (license\u002Fdiscord\u002Fsteam) ไม่ใช่ server id\n\nไฟล์เสียจะถูกเก็บไว้เป็น `data\u002Fskins.broken.json` แล้วเริ่มใหม่จากว่าง พร้อมเตือนใน console ไม่ทับทิ้งเงียบ ๆ\n\nใช้ MySQL แทน:\n\n1. รัน `install.sql` ผ่าน oxmysql\n2. เปิด `addons\u002Fstorage\u002Fserver.lua` เลื่อนไปท้ายไฟล์ คัดลอกบล็อก oxmysql ทับสี่ฟังก์ชัน `Storage.Get\u002FSet\u002FAll\u002FFlush` ด้านบน\n\n## ความปลอดภัย (มีเทสคุมทุกข้อ)\n\n- **ค่าที่พาเนลส่งมาไม่เชื่อสักตัว** — ชื่อช่องต้องอยู่ใน `components.lua` ค่าต้องเป็นตัวเลข ถูก floor และ clamp เข้าช่วง คีย์แปลกปลอมถูกทิ้ง\n- **คีย์เก็บเป็น identifier เสมอ** ไม่ใช่ server id ที่ถูกใช้ซ้ำกับคนอื่นได้\n- **เซฟได้ 1 ครั้ง\u002Fวินาที\u002Fคน** cooldown ถูกล้างทันทีที่ผู้เล่นออก\n- **`\u002Fskin \u003Cid>` ต้องมี ace เสมอ** แม้เปิด `Config.PlayersCanEdit` ให้ทุกคนแก้ตัวเองได้\n- **เลขที่เกินช่วงถูก clamp ตอนใส่ลงร่างเท่านั้น ไม่เขียนกลับลงชุดที่เซฟ** — ชุด addon ที่โหลดไม่ทันจะไม่ล้างเสื้อผ้าผู้เล่นเป็น 0 ถาวร\n- **พาเนลปิดเองตอนตายและตอน resource หยุด** คืนเมาส์และคืนการควบคุมทุกครั้ง\n\n```bash\npip install lupa\npython tools\u002Flua-test\u002Fx3d_skin_check.py\n```\n\n## config (`config.lua`)\n\n| คีย์ | ทำอะไร |\n|---|---|\n| `Config.Locale` | ภาษาข้อความฝั่ง Lua (`th`\u002F`en`) — พาเนลมีปุ่มสลับภาษาของตัวเอง |\n| `Config.Command` \u002F `Config.Key` | คำสั่งเปิด (`\u002Fskin`) และปุ่มลัด (ว่าง = ไม่ผูกปุ่ม) |\n| `Config.AdminAce` | ace ที่ต้องมีถึงจะเปิดให้คนอื่นได้ |\n| `Config.PlayersCanEdit` | `false` = แก้ได้เฉพาะคนมี ace |\n| `Config.AdvancedFace` | ระบบหน้าแบบง่าย หรือแบบพ่อ\u002Fแม่ |\n| `Config.ApplyOnSpawn` \u002F `Config.FirstTimeSetup` | ใส่หน้าที่เซฟไว้ตอนเกิด · เปิดพาเนลให้คนที่ยังไม่เคยเซฟ |\n| `Config.Storage.File` \u002F `.FlushSeconds` | ไฟล์ที่เก็บและความถี่ในการเขียน |\n| `Config.Camera` | ระยะซูม ขอบเขตการเลื่อนกล้อง ไฟส่องตัวละคร |\n| `Config.HideHud` | ซ่อนเรดาร์\u002FHUD ระหว่างเปิดพาเนล |\n| `Config.Shops` \u002F `Config.ShopTypes` \u002F `Config.ShopLocations` | ร้าน — เปิดปิด ราคา ช่องที่แก้ได้ และที่ตั้ง |\n| `Config.Wardrobe` | ตู้เสื้อผ้า — เปิดปิด จำนวนชุดสูงสุดต่อคน |\n| `Config.Backend` | `auto`\u002F`skinchanger`\u002F`self` — ใครใส่ค่าลงร่างและใครเก็บชุด |\n\n## ช่วยเหลือ\n\nDiscord: discord.gg\u002Fx3d-developer · เว็บ: x3d-developer.com\n","สคริปต์ตกแต่งตัวละคร FiveM ฟรี ไม่ต้องใช้ skinchanger","หน้าตกแต่งตัวละคร FiveM ฟรี 77 ช่อง หน้า ผม เครา เมกอัพ เสื้อผ้า กล้องหมุนซูม ท่าโพส ไม่ต้องลง skinchanger ไม่ต้องลงฐานข้อมูล ร้านตัดผมเรียกใช้ได้",[61,64,66,68,70],{"kind":62,"url":63},"image","\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-skin\u002Fmedia\u002Fa08a6d9506a7700b.png",{"kind":62,"url":65},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-skin\u002Fmedia\u002Fcaf6452bf3d960de.png",{"kind":62,"url":67},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-skin\u002Fmedia\u002F69e3657b291a300b.png",{"kind":62,"url":69},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-skin\u002Fmedia\u002Fc67ad3f8f1dd1295.png",{"kind":62,"url":71},"\u002Fapi\u002Fv1\u002Fmedia\u002Fpublic\u002Fproducts\u002Fx3d-skin\u002Fmedia\u002Fb9dbff8a1dd766e4.png",[73,75,79,83,87],{"version":50,"released_at":51,"changelog_md":74},"### Changed\n\n- Store images now carry English captions for the English store page",{"version":76,"released_at":77,"changelog_md":78},"1.5.2","2026-10-12T03:23:58.490433Z","### Changed\n\n- UI font is now Kanit (one family for Thai and English), bundled inside the script; the Thai font now really loads in game (FiveM's browser dropped the old font declaration and fell back to a system font)\n- New store images",{"version":80,"released_at":81,"changelog_md":82},"1.5.1","2026-10-11T09:23:09.364562Z","### Changed\n\n- Clothing shop `[E]` label uses the X3D 3D-text standard (outlined Thai text, amber key line)",{"version":84,"released_at":85,"changelog_md":86},"1.4.0","2026-09-22T04:06:09.988343Z","### Added\n- `optional\u002Fskinchanger` and `optional\u002Fesx_skin` ship in the zip for servers that do not already have them, so nothing has to be hunted down elsewhere. A server that already runs them skips the folder and keeps its own.\n- The bundled `skinchanger` drops the `@include` of es_extended's locale file (a local `shim.lua` supplies `TranslateCap`), so it installs without erroring\n- The bundled `esx_skin` is trimmed to the API: the `skin` column, `esx_skin:save`, the `esx_skin:getPlayerSkin` callback and the old open-menu events, which now open the x3d_skin panel. No second UI, and the player table name is a config value.",{"version":88,"released_at":89,"changelog_md":90},"1.3.0","2026-09-22T04:02:29.316247Z","### Removed\r\n- The mode that answered as `skinchanger` and `esx_skin` so both could be deleted. Servers keep those two as their interface layer, so a mode built around removing them only made setup look frightening. Installing is now: drop the folder in, `ensure x3d_skin`, done.\r\n- The storage block that wrote the `users.skin` column — with the two originals left in place, `esx_skin` still owns that column.",{"slug":23,"version":50,"latest_version":50,"files":92,"options":55},[93],{"path":94,"content":95},"config.lua","-- ═══════════════════════════════════════════════════════════════\r\n--  X3D SKIN  ·  config\r\n--  แก้ไฟล์นี้ไฟล์เดียวพอ ไม่ต้องแตะโค้ดส่วนอื่น\r\n--  Edit this one file only, no other code needs touching\r\n-- ═══════════════════════════════════════════════════════════════\r\n\r\nConfig = {}\r\n\r\n-- ===== ทั่วไป \u002F General =====\r\n\r\n--- เฟรมเวิร์ก: 'auto' หาเองจาก es_extended · 'esx' บังคับ ESX · 'standalone' ไม่ใช้เฟรมเวิร์ก\r\n--- Framework: 'auto' detects es_extended · 'esx' forces ESX · 'standalone' uses no framework\r\nConfig.Framework = 'auto'\r\n\r\n--- ภาษาของข้อความฝั่ง Lua ('th' | 'en') — พาเนลมีปุ่มสลับภาษาของตัวเอง\r\n--- Language of Lua-side messages ('th' | 'en'), the panel has its own language switch\r\nConfig.Locale = 'th'\r\n\r\n--- คำสั่งเปิดหน้าตกแต่งตัวละครของตัวเอง\r\n--- Command that opens your own character editor\r\nConfig.Command = 'skin'\r\n\r\n--- ปุ่มลัด ปล่อยว่าง = ไม่ผูกปุ่ม (ผู้เล่นเปลี่ยนเองได้ที่ Settings > Key Bindings)\r\n--- Shortcut key, empty = no key bound (players can rebind it in Settings > Key Bindings)\r\nConfig.Key = ''\r\n\r\n--- ace ที่ต้องมีถึงจะเปิดให้คนอื่นได้ (`\u002Fskin \u003Cid>`)\r\n--- คอนโซลเซิร์ฟเวอร์ใช้ได้เสมอ ไม่ต้องมี ace\r\n--- เพิ่มให้แอดมิน: add_ace group.admin x3d_skin.admin allow\r\n--- ACE needed to open the editor for other players (`\u002Fskin \u003Cid>`)\r\n--- The server console always works without the ACE\r\n--- Grant to admins: add_ace group.admin x3d_skin.admin allow\r\nConfig.AdminAce = 'x3d_skin.admin'\r\n\r\n--- true = ผู้เล่นทั่วไปเปิด `\u002Fskin` แก้หน้าตัวเองได้ตลอดเวลา\r\n--- false = เปิดได้เฉพาะคนที่มี ace ข้างบน (เซิร์ฟที่อยากให้แก้ได้เฉพาะที่ร้าน)\r\n--- true = every player can open `\u002Fskin` and edit themselves at any time\r\n--- false = only holders of the ACE above (for servers that allow editing only at shops)\r\nConfig.PlayersCanEdit = true\r\n\r\n--- ระบบหน้า\r\n---   false = face + skin (เลือกหน้าสำเร็จรูป 46 แบบ) — ค่าเริ่มต้น เข้าใจง่าย\r\n---   true  = mom + dad + น้ำหนักหน้า + ดัดจมูก\u002Fแก้ม\u002Fคาง ทีละจุด (แบบ MP)\r\n--- ⚠ สลับค่านี้หลังเปิดเซิร์ฟแล้ว หน้าที่ผู้เล่นเซฟไว้จะเพี้ยน เพราะคนละชุดค่า\r\n--- Face system\r\n---   false = face + skin (46 ready-made faces), the default and easy to understand\r\n---   true  = mom + dad + face blend + nose\u002Fcheek\u002Fchin one by one (MP style)\r\n--- ⚠ Switching this on a running server breaks faces players already saved, the values differ\r\nConfig.AdvancedFace = false\r\n\r\n--- โหลดหน้าที่เซฟไว้ให้อัตโนมัติทุกครั้งที่ผู้เล่นเกิด\r\n--- Apply the saved appearance every time the player spawns\r\nConfig.ApplyOnSpawn = true\r\n\r\n--- เปิดหน้าตกแต่งอัตโนมัติให้ผู้เล่นที่ยังไม่เคยเซฟหน้าเลย (สร้างตัวละครครั้งแรก)\r\n--- Open the editor automatically for a player who has never saved an appearance (first character)\r\nConfig.FirstTimeSetup = true\r\n\r\n-- ===== ที่เก็บข้อมูล \u002F Storage =====\r\n\r\n--- ที่เก็บหน้าตัวละคร\r\n--- Where character appearances are stored\r\nConfig.Storage = {\r\n    --- ไฟล์ JSON ที่เก็บ (เทียบจากโฟลเดอร์สคริปต์)\r\n    --- JSON file used for storage (relative to the script folder)\r\n    File = 'data\u002Fskins.json',\r\n    --- เขียนลงไฟล์ทุกกี่วินาที (เขียนตอนผู้เล่นออกและตอนปิดสคริปต์อยู่แล้ว)\r\n    --- Seconds between writes to the file (it is also written on disconnect and on stop)\r\n    FlushSeconds = 60,\r\n}\r\n\r\n-- ===== กล้อง \u002F Camera =====\r\n\r\n--- กล้อง\r\n--- Camera\r\nConfig.Camera = {\r\n    --- ระยะซูมเริ่มต้น \u002F ต่ำสุด \u002F สูงสุด\r\n    --- Default \u002F minimum \u002F maximum zoom distance\r\n    zoom = 2.0,\r\n    zoomMin = 0.15,\r\n    zoomMax = 3.5,\r\n    --- ระยะที่ตัวละครขยับไปทางขวาของจอ (หลบพาเนลด้านซ้าย)\r\n    --- How far the character shifts to the right of the screen (clear of the left panel)\r\n    xOffset = 0.55,\r\n    --- ขอบเขตการเลื่อนกล้อง (กันส่องไปที่อื่น)\r\n    --- Camera pan limits (keeps it from drifting away)\r\n    panLimitX = 1.0,\r\n    panLimitUp = 1.2,\r\n    panLimitDown = 0.3,\r\n    --- ไฟส่องตัวละคร ปิดได้ถ้าเซิร์ฟมี ENB\u002Fgraphics mod ที่ตีกัน\r\n    --- Character lighting, turn it off if an ENB\u002Fgraphics mod conflicts\r\n    lights = true,\r\n}\r\n\r\n--- ซ่อน HUD\u002Fเรดาร์ระหว่างเปิดพาเนล\r\n--- Hide the HUD\u002Fradar while the panel is open\r\nConfig.HideHud = true\r\n\r\n-- ===== ตู้เสื้อผ้า \u002F Wardrobe =====\r\n\r\n--  ตู้เสื้อผ้า — เซฟชุดเป็นเซ็ตแล้วตั้งชื่อ กดใส่ทีเดียวทั้งชุด\r\n--  Wardrobe: save a whole look as a named set and apply it in one click\r\n\r\nConfig.Wardrobe = {\r\n    --- เปิด\u002Fปิดตู้เสื้อผ้า \u002F Wardrobe on\u002Foff\r\n    enabled = true,\r\n    --- เซฟได้กี่ชุดต่อคนต่อประเภท (outfit \u002F hairstyle \u002F mask)\r\n    --- Saved sets allowed per player per type (outfit \u002F hairstyle \u002F mask)\r\n    maxPerType = 20,\r\n    --- ความยาวชื่อชุดสูงสุด\r\n    --- Maximum outfit name length\r\n    nameLength = 50,\r\n}\r\n\r\n-- ===== ร้านค้า \u002F Shops =====\r\n\r\n-- ═══════════════════════════════════════════════════════════════\r\n--  ร้าน — ร้านเสื้อผ้า ร้านเสริมสวย ร้านหน้ากาก\r\n--  Shops: clothing, beauty and mask shops\r\n--\r\n--  ปิดทั้งระบบด้วย Config.Shops.enabled = false (เหลือแค่ \u002Fskin)\r\n--  ตั้ง price = 0 = เข้าใช้ฟรี ไม่แตะเงินใครเลย\r\n--\r\n--  ⚠ เงินถูกหักและชุดถูกบันทึกในก้าวเดียวกันฝั่งเซิร์ฟเวอร์\r\n--    ผู้เล่นบล็อกข้อความคิดเงินแล้วได้ชุดฟรีไม่ได้\r\n--\r\n--  Turn the whole system off with Config.Shops.enabled = false (only \u002Fskin remains)\r\n--  price = 0 means free to use and never touches anyone's money\r\n--\r\n--  ⚠ Money is charged and the outfit saved in one server-side step,\r\n--    so a player cannot block the charge message and keep the outfit for free\r\n-- ═══════════════════════════════════════════════════════════════\r\n\r\nConfig.Shops = {\r\n    --- เปิด\u002Fปิดระบบร้านทั้งหมด \u002F Shops system on\u002Foff\r\n    enabled = true,\r\n\r\n    --- ระยะที่เริ่มวาดวงกลมบนพื้น \u002F ระยะที่กด [E] ได้\r\n    --- Distance where the ground circle starts drawing \u002F distance where [E] works\r\n    drawDistance = 20.0,\r\n    interactDistance = 3.0,\r\n\r\n    --- วงกลมบนพื้นหน้าร้าน (ปิดด้วย marker = false)\r\n    --- Ground circle at the shop (turn off with marker = false)\r\n    marker = true,\r\n    --- ขนาดและสีของวงกลม \u002F Circle size and color\r\n    markerSize = vector3(4.0, 4.0, 0.2),\r\n    markerColor = { r = 212, g = 144, b = 122, a = 70 },\r\n\r\n    --- หมุดบนแผนที่ โผล่เมื่อเข้าใกล้ภายใน blipDistance เมตร (0 = โชว์ตลอด)\r\n    --- Map blip, shown within blipDistance meters (0 = always shown)\r\n    blips = true,\r\n    blipDistance = 120.0,\r\n}\r\n\r\n-- ===== ประเภทร้าน \u002F Shop types =====\r\n\r\n--- ประเภทร้าน — ราคาและช่องที่แก้ได้ในร้านนั้น\r\n--- `categories` = แท็บย่อยในพาเนล (components = nil คือแท็บ \"ทั้งหมด\")\r\n--- Shop types: price and editable slots per shop\r\n--- `categories` = sub-tabs in the panel (components = nil is the \"all\" tab)\r\n--- label = ชื่อร้าน \u002F shop name · price = ราคา (0 = ฟรี) \u002F price (0 = free)\r\n--- blip = ไอคอนและสีหมุด \u002F blip icon and color · components = ช่องที่แก้ได้ \u002F editable slots\r\n-- เช่น \u002F e.g. masks = { label = 'ร้านหน้ากาก', price = 200, blip = { sprite = 362, color = 1 }, components = { 'mask_1', 'mask_2' } }\r\nConfig.ShopTypes = {\r\n    clothing = {\r\n        label = 'ร้านเสื้อผ้า',\r\n        price = 500,\r\n        blip = { sprite = 73, color = 47 },\r\n        categories = {\r\n            { id = 'all', name = 'ทั้งหมด', components = nil },\r\n            { id = 'clothing', name = 'เสื้อผ้า', components = {\r\n                'tshirt_1', 'tshirt_2', 'torso_1', 'torso_2', 'arms', 'arms_2',\r\n                'pants_1', 'pants_2', 'shoes_1', 'shoes_2', 'bags_1', 'bags_2',\r\n                'decals_1', 'decals_2', 'bproof_1', 'bproof_2',\r\n            } },\r\n            { id = 'accessories', name = 'เครื่องประดับ', components = {\r\n                'helmet_1', 'helmet_2', 'glasses_1', 'glasses_2', 'watches_1', 'watches_2',\r\n                'bracelets_1', 'bracelets_2', 'ears_1', 'ears_2', 'chain_1', 'chain_2',\r\n            } },\r\n        },\r\n        components = {\r\n            'tshirt_1', 'tshirt_2', 'torso_1', 'torso_2', 'arms', 'arms_2',\r\n            'pants_1', 'pants_2', 'shoes_1', 'shoes_2', 'bags_1', 'bags_2',\r\n            'decals_1', 'decals_2', 'bproof_1', 'bproof_2',\r\n            'helmet_1', 'helmet_2', 'glasses_1', 'glasses_2', 'watches_1', 'watches_2',\r\n            'bracelets_1', 'bracelets_2', 'ears_1', 'ears_2', 'chain_1', 'chain_2',\r\n        },\r\n    },\r\n\r\n    beauty = {\r\n        label = 'ร้านเสริมสวย',\r\n        price = 200,\r\n        blip = { sprite = 71, color = 40 },\r\n        categories = {\r\n            { id = 'all', name = 'ทั้งหมด', components = nil },\r\n            { id = 'hair', name = 'ผมและเครา', components = {\r\n                'hair_1', 'hair_2', 'hair_color_1', 'hair_color_2',\r\n                'beard_1', 'beard_2', 'beard_3', 'beard_4',\r\n                'eyebrows_1', 'eyebrows_2', 'eyebrows_3', 'eyebrows_4',\r\n            } },\r\n            { id = 'makeup', name = 'แต่งหน้า', components = {\r\n                'makeup_1', 'makeup_2', 'makeup_3', 'makeup_4',\r\n                'lipstick_1', 'lipstick_2', 'lipstick_3', 'lipstick_4',\r\n                'blush_1', 'blush_2', 'blush_3', 'complexion_1', 'complexion_2',\r\n                'sun_1', 'sun_2', 'moles_1', 'moles_2', 'age_1', 'age_2',\r\n                'blemishes_1', 'blemishes_2',\r\n            } },\r\n        },\r\n        components = {\r\n            'hair_1', 'hair_2', 'hair_color_1', 'hair_color_2',\r\n            'beard_1', 'beard_2', 'beard_3', 'beard_4',\r\n            'eyebrows_1', 'eyebrows_2', 'eyebrows_3', 'eyebrows_4',\r\n            'makeup_1', 'makeup_2', 'makeup_3', 'makeup_4',\r\n            'lipstick_1', 'lipstick_2', 'lipstick_3', 'lipstick_4',\r\n            'blush_1', 'blush_2', 'blush_3', 'complexion_1', 'complexion_2',\r\n            'sun_1', 'sun_2', 'moles_1', 'moles_2', 'age_1', 'age_2',\r\n            'blemishes_1', 'blemishes_2',\r\n        },\r\n    },\r\n\r\n    masks = {\r\n        label = 'ร้านหน้ากาก',\r\n        price = 200,\r\n        blip = { sprite = 362, color = 1 },\r\n        components = { 'mask_1', 'mask_2' },\r\n    },\r\n}\r\n\r\n-- ===== ที่ตั้งร้าน \u002F Shop locations =====\r\n\r\n--- ที่ตั้งร้าน — `type` ต้องตรงกับคีย์ใน Config.ShopTypes\r\n--- Shop locations: `type` must match a key in Config.ShopTypes\r\n-- เช่น \u002F e.g. { type = 'clothing', coords = vector3(124.21, -219.85, 54.55) }\r\nConfig.ShopLocations = {\r\n    { type = 'clothing', coords = vector3(124.21, -219.85, 54.55) },      -- Vinewood\r\n    { type = 'clothing', coords = vector3(72.25, -1399.10, 28.37) },      -- Strawberry\r\n    { type = 'clothing', coords = vector3(-703.77, -152.25, 36.41) },     -- Burton\r\n    { type = 'clothing', coords = vector3(-167.86, -298.96, 38.73) },     -- Downtown\r\n    { type = 'clothing', coords = vector3(428.69, -800.10, 28.49) },      -- Pillbox Hill\r\n    { type = 'clothing', coords = vector3(-829.41, -1073.71, 10.32) },    -- Vespucci Canals\r\n    { type = 'clothing', coords = vector3(-1447.79, -242.46, 48.82) },    -- Morningwood\r\n    { type = 'clothing', coords = vector3(11.63, 6514.22, 30.87) },       -- Paleto Bay\r\n    { type = 'clothing', coords = vector3(1696.29, 4829.31, 41.06) },     -- Grapeseed\r\n    { type = 'clothing', coords = vector3(618.09, 2759.62, 41.08) },      -- Harmony\r\n    { type = 'clothing', coords = vector3(1190.55, 2713.44, 37.22) },     -- Grand Senora\r\n    { type = 'clothing', coords = vector3(-1193.42, -772.26, 16.32) },    -- Del Perro\r\n    { type = 'clothing', coords = vector3(-3172.49, 1048.13, 19.86) },    -- Chumash\r\n    { type = 'clothing', coords = vector3(-1108.44, 2708.92, 18.10) },    -- Zancudo\r\n\r\n    { type = 'beauty', coords = vector3(-814.30, -183.82, 36.56) },       -- Burton\r\n    { type = 'beauty', coords = vector3(136.82, -1708.37, 28.29) },       -- Davis\r\n    { type = 'beauty', coords = vector3(-1282.60, -1116.75, 5.99) },      -- Del Perro\r\n    { type = 'beauty', coords = vector3(1931.51, 3729.67, 31.84) },       -- Sandy Shores\r\n    { type = 'beauty', coords = vector3(1212.84, -472.92, 65.20) },       -- Mirror Park\r\n    { type = 'beauty', coords = vector3(-32.88, -152.31, 56.07) },        -- Hawick\r\n    { type = 'beauty', coords = vector3(-278.07, 6228.46, 30.69) },       -- Paleto Bay\r\n\r\n    { type = 'masks', coords = vector3(-1337.40, -1278.15, 4.87) },       -- Vespucci Beach\r\n}\r\n\r\n-- ===== ตัวใส่ค่า \u002F Backend =====\r\n\r\n--- ใครใส่หน้าตา\u002Fเสื้อผ้าลงร่าง — ปกติไม่ต้องแตะ\r\n--- Who applies the appearance to the ped, normally leave it alone\r\n---   'auto'        มี skinchanger อยู่แล้วก็ใช้ของเดิม ไม่มีก็ใช้ตัวในสคริปต์ (ค่าเริ่มต้น)\r\n---   'skinchanger' บังคับใช้ skinchanger\r\n---   'self'        บังคับใช้ตัวในสคริปต์\r\n---   'auto'        uses an existing skinchanger if present, otherwise the built-in one (default)\r\n---   'skinchanger' forces skinchanger\r\n---   'self'        forces the built-in applier\r\nConfig.Backend = 'auto'\r\n\r\n",1792316309057]