ยินดีต้อนรับสู่ Patreon Authenticator for Unity
แพ็กเกจ Unity ครบชุดสำหรับผสานการยืนยันตัวตน Patreon OAuth 2.0 พร้อมเซิร์ฟเวอร์ HTTP ในตัว ฟีเจอร์ความปลอดภัยขั้นสูง และรองรับหลายแพลตฟอร์ม
เริ่มต้นใช้งาน
Patreon Authenticator for Unity เป็นปลั๊กอินทรงพลังที่ผสานเกม Unity ของคุณเข้ากับระบบยืนยันตัวตนของ Patreon ได้อย่างราบรื่น ด้วยปลั๊กอินนี้คุณสามารถ:
- ความปลอดภัยขั้นสูง: การเข้ารหัส AES-256 การอำพรางโค้ด และการจัดเก็บที่ปลอดภัย
- เซิร์ฟเวอร์ HTTP ในตัว: HTTP listener ฝังในตัวสำหรับ callback ของ OAuth
- รองรับ middleware: middleware กำหนดเองสำหรับ callback ของ OAuth บนทุกแพลตฟอร์ม
- หลายแพลตฟอร์ม: ใช้งานได้บน WebGL, Android, iOS, Windows, Mac และ Linux
- จัดการโทเค็นอย่างปลอดภัย: เข้ารหัสเฉพาะอุปกรณ์พร้อมการสร้างคีย์ PBKDF2
- การทำงานที่ปลอดภัยต่อเธรด: จัดการคำขอ HTTP อย่างถูกต้อง
- หน้า callback ที่สวยงาม: หน้า HTML สำเร็จและข้อผิดพลาดที่ปรับแต่งได้
- ตรวจสอบ state: ป้องกัน CSRF ด้วยการตรวจพารามิเตอร์ state
- รีเฟรชโทเค็น: รีเฟรช access token อัตโนมัติ
- ดึงโปรไฟล์ผู้ใช้: ข้อมูลผู้ใช้และข้อมูลสมาชิก
- ทดสอบความปลอดภัย: เครื่องมือในตัวสำหรับตรวจสอบและทดสอบความปลอดภัย
- รองรับ GIF: อวาตาร์ Patreon แบบเคลื่อนไหวพร้อมรองรับแอนิเมชัน GIF
ข้อกำหนด
ก่อนเริ่ม ตรวจสอบว่าคุณมีสิ่งต่อไปนี้:
- Unity 2021.3 LTS ขึ้นไป
- .NET Standard 2.1 ขึ้นไป
- บัญชีครีเอเตอร์ Patreon
- ความรู้พื้นฐานเกี่ยวกับ Unity และ C#
- การเชื่อมต่ออินเทอร์เน็ตสำหรับคำขอ API ของ Patreon
หมายเหตุสำคัญ
ปลั๊กอินนี้ต้องใช้ Unity 2021.3 LTS ขึ้นไป ไม่รองรับเวอร์ชันเก่ากว่า
การติดตั้ง
1. ติดตั้งแพ็กเกจ Newtonsoft.Json (จำเป็น)
สำคัญ: ต้องทำขั้นตอนนี้ก่อนใช้ปลั๊กอิน!
- เปิด Package Manager ใน Unity (
Window → Package Manager) - คลิกปุ่ม "+"
- เลือก "Install package by name…"
- Enter
com.unity.nuget.newtonsoft-json - คลิก "Add" เพื่อติดตั้งแพ็กเกจ
หากไม่มีแพ็กเกจนี้ สคริปต์จะคอมไพล์ไม่ได้!
2. คัดลอกไฟล์ปลั๊กอิน
- คัดลอกโฟลเดอร์
Assets/Plugins/PatreonAuthenticatorForUnity/ไปยังโปรเจกต์ Unity ของคุณ - คัดลอกไฟล์
Assets/StreamingAssets/patreon-callback.htmlไปยังโฟลเดอร์ StreamingAssets
3. ตั้งค่าซีน
- สร้างแอสเซ็ต PatreonConfig:
- ไปที่โฟลเดอร์ Resources (สร้างขึ้นหากยังไม่มี)
- คลิกขวาในหน้าต่าง Project
- ไปที่
Create → Patreon Authenticator for Unity → Create New Config - แอสเซ็ตจะถูกสร้างในโฟลเดอร์
Assets/Resources/(PatreonConfig) - ตั้งค่าพื้นฐาน (ดูหัวข้อการกำหนดค่าด้านล่าง)
- Client ID และ Client Secret จะตั้งค่าภายหลังด้วยสคริปต์ PatreonReEncryptCredentials
- สร้าง GameObject ชื่อ PatreonManager:
- คลิกขวาในหน้าต่าง Hierarchy
- เลือก
Create Empty - เปลี่ยนชื่อ GameObject เป็น
PatreonManager
- เพิ่มสคริปต์ที่จำเป็นให้ PatreonManager:
- เลือก GameObject
PatreonManager - Add Component → สคริปต์
PatreonManager - สำคัญ: กำหนดแอสเซ็ต PatreonConfig ในช่อง "Patreon Config"
- Add Component → สคริปต์
PatreonCallbackManager(ใช้ได้ทุกแพลตฟอร์ม ต้องมีคอมโพเนนต์ด้านล่าง) - Add Component → สคริปต์
PatreonEmbeddedServer(เฉพาะแพลตฟอร์มเดสก์ท็อป) - Add Component → สคริปต์
PatreonDeepLinkHandler(เฉพาะแพลตฟอร์มมือถือ) - Add Component → สคริปต์
PatreonWebGLHandler(เฉพาะแพลตฟอร์ม WebGL)
สคริปต์ทั้งหมดเข้ากันได้และใช้ร่วมกันได้
- เลือก GameObject
-
การตั้งค่าตามแพลตฟอร์ม:
📱 แพลตฟอร์มมือถือ (Android/iOS):
- จะใช้
PatreonDeepLinkHandlerโดยอัตโนมัติ - ตั้งค่า Android: เพิ่มลงใน
AndroidManifest.xmlของคุณ:<activity android:name="com.unity3d.player.UnityPlayerActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="PatreonAuthenticatorForUnity.oauth" /> </intent-filter> </activity> - ตั้งค่า iOS: เพิ่มลงใน
Info.plistของคุณ:<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLName</key> <string>Patreon OAuth</string> <key>CFBundleURLSchemes</key> <array> <string>PatreonAuthenticatorForUnity.oauth</string> </array> </dict> </array>
🌐 แพลตฟอร์ม WebGL:
- จะใช้
PatreonWebGLHandlerโดยอัตโนมัติ - ใช้ middleware สำหรับ callback ของ OAuth (ไม่ต้องตั้งค่าเพิ่ม)
🖥️ แพลตฟอร์มเดสก์ท็อป (Windows/Mac/Linux):
- จะใช้
PatreonEmbeddedServerโดยอัตโนมัติ - สร้างเซิร์ฟเวอร์ HTTP ภายในที่
localhost:3000
- จะใช้
- เกี่ยวกับ middleware:
- ทุกแพลตฟอร์มใช้ middleware สำหรับ callback ของ OAuth
- Middleware จัดการขั้นตอน OAuth และเปลี่ยนเส้นทางกลับไปยังแอปของคุณ
- URI scheme กำหนดเอง: ตั้งค่าใน PatreonConfig (ค่าเริ่มต้น:
PatreonAuthenticatorForUnity.oauth) - ตัวเลือก middleware ฟรี: คุณสร้าง middleware ของตัวเองบน GitHub Pages ได้
- คัดลอกโค้ด middleware จาก
Assets/StreamingAssets/patreon-callback.html - โฮสต์บน GitHub Pages เพื่อเป็น middleware ฟรี
- อัปเดต redirect URI ใน PatreonConfig ให้ชี้ไปที่ middleware ของคุณ
- URI scheme กำหนดเอง: ตั้งค่า middleware ให้ใช้ URI scheme ของคุณจาก PatreonConfig
- ตรวจสอบการตั้งค่า:
- GameObject PatreonManager ต้องมีสคริปต์ที่จำเป็นครบ
- ต้องกำหนด PatreonConfig ในคอมโพเนนต์ PatreonManager
- ต้องไม่มีข้อผิดพลาดการคอมไพล์ใน Console
ติดตั้งเสร็จสมบูรณ์
หลังนำเข้าจาก Unity Asset Store โฟลเดอร์ 'PatreonAuthenticatorForUnity' จะปรากฏในไดเรกทอรี Assets/Plugins
ฟีเจอร์ความปลอดภัย
ระบบเข้ารหัสขั้นสูง
ปลั๊กอินมาพร้อมระบบความปลอดภัยครบชุดเพื่อปกป้องข้อมูลรับรอง Patreon ของคุณ:
การเข้ารหัส AES-256
- Client Secret ถูกเข้ารหัสด้วย AES-256 โดยใช้คีย์เฉพาะอุปกรณ์
- การสร้างคีย์ PBKDF2 ด้วย 10,000 รอบเพื่อความปลอดภัยสูงสุด
- การเข้ารหัสเฉพาะอุปกรณ์ — คีย์ไม่ซ้ำกันสำหรับแต่ละอุปกรณ์/แอป
- สร้าง IV อัตโนมัติ สำหรับการเข้ารหัสทุกครั้ง
การอำพรางแบบ XOR
- Client ID ถูกอำพรางด้วยการเข้ารหัส XOR
- การเข้ารหัส Base64 สำหรับการจัดเก็บที่ปลอดภัย
- การป้องกันแบบเบา เหมาะกับตัวระบุสาธารณะ
การจัดเก็บที่ปลอดภัย
- ที่เก็บ PlayerPrefs แบบเข้ารหัส สำหรับข้อมูลสำคัญ
- ล้างข้อมูลสำคัญออกจากหน่วยความจำโดยอัตโนมัติ
- เมธอดลบอย่างปลอดภัยสำหรับข้อมูลที่จัดเก็บ
การตรวจสอบความปลอดภัย
- การทดสอบความปลอดภัยในตัวด้วยคอมโพเนนต์
PatreonSecurityTest - ตรวจสอบอัตโนมัติสำหรับการเข้ารหัส/ถอดรหัส
- ทดสอบประสิทธิภาพของการทำงานด้านความปลอดภัย
- ตรวจสอบความปลอดภัยของหน่วยความจำ
ระดับความปลอดภัย
| เลเวล | Client ID | Client Secret | การใช้งาน |
|---|---|---|---|
| สูงสุด | อำพรางแล้ว | เข้ารหัสแล้ว | โปรดักชัน |
| สูง | ข้อความธรรมดา | เข้ารหัสแล้ว | การพัฒนา |
| ปานกลาง | อำพรางแล้ว | ข้อความธรรมดา | การทดสอบ |
| ไม่มี | ข้อความธรรมดา | ข้อความธรรมดา | ไม่แนะนำ |
แนวปฏิบัติด้านความปลอดภัย
- เปิดการเข้ารหัสเสมอสำหรับ Client Secret ในโปรดักชัน
- ใช้การอำพรางสำหรับ Client ID เมื่อทำได้
- ห้าม commit PatreonConfig.asset เข้าระบบควบคุมเวอร์ชัน
- ทดสอบระบบความปลอดภัยก่อนบิลด์โปรดักชัน
- ใช้การจัดเก็บที่ปลอดภัยสำหรับข้อมูลสำคัญทุกชนิด
- ล้างข้อมูลสำคัญออกจากหน่วยความจำเมื่อไม่ต้องใช้แล้ว
สำคัญมาก: ตั้งค่าข้อมูลรับรองอย่างปลอดภัย
เรื่องนี้สำคัญอย่างยิ่งต่อความปลอดภัย!
ข้อมูลรับรอง Patreon ของคุณ (Client ID และ Client Secret) อ่อนไหวอย่างยิ่ง และต้องเข้ารหัสก่อนใช้งาน ห้ามเก็บเป็นข้อความธรรมดาเด็ดขาด!
ทำไมเรื่องนี้จึงสำคัญ
- ข้อความธรรมดา = ความเสี่ยงด้านความปลอดภัย: หากเก็บข้อมูลรับรองเป็นข้อความธรรมดา ใครก็ตามที่เข้าถึงบิลด์ของคุณได้ก็ขโมยไปได้
- ผลกระทบทางการเงิน: ข้อมูลรับรองที่ถูกขโมยอาจถูกใช้เข้าบัญชี Patreon ของคุณและก่อความเสียหายทางการเงิน
- ผลกระทบต่อการทำงาน: การรั่วไหลด้านความปลอดภัยอาจทำลายชื่อเสียงและความเชื่อใจของผู้ใช้
- ผลทางกฎหมาย: มาตรการความปลอดภัยที่ไม่เพียงพออาจนำไปสู่ปัญหาทางกฎหมาย
วิธีตั้งค่าข้อมูลรับรองอย่างปลอดภัย
ทำตามขั้นตอนนี้เพื่อเข้ารหัสข้อมูลรับรอง Patreon:
ขั้นที่ 1: สร้าง GameObject สำหรับเข้ารหัสใหม่
- สร้าง GameObject ว่างใหม่ในซีน
- เปลี่ยนชื่อเป็นชื่ออย่าง
"PatreonEncryptCredentials"(จะลบทิ้งภายหลัง) - เพิ่มสคริปต์
PatreonEncryptCredentialsให้ GameObject
ขั้นที่ 2: ใส่ข้อมูลรับรองจริง
- เลือก GameObject ใน Hierarchy
- ใน Inspector คุณจะเห็นสคริปต์เข้ารหัสใหม่พร้อมคำแนะนำที่ชัดเจน
- กรอกข้อมูลรับรองจริงในช่องที่กำหนด:
Real Client Id: Client ID ของ PatreonReal Client Secret: Client Secret ของ Patreon
ขั้นที่ 3: กำหนด PatreonConfig (ไม่บังคับแต่แนะนำ)
- ลากแอสเซ็ต PatreonConfig ไปที่ช่อง
PatreonConfig Asset - หากกำหนด PatreonConfig: ค่าต่าง ๆ จะถูกตั้งอัตโนมัติหลังเข้ารหัส
- หากไม่กำหนด PatreonConfig: ต้องคัดลอกค่าที่เข้ารหัสแล้วด้วยตนเอง
ขั้นที่ 4: เข้ารหัสข้อมูลรับรองใหม่
- คลิกขวาที่สคริปต์ใน Inspector
- เลือก “Re-Encrypt All Credentials” จากเมนูคลิกขวา
- รอให้กระบวนการเสร็จ - จะเห็นข้อความสำเร็จใน Console
ขั้นที่ 5: ตรวจสอบและเก็บกวาด
- ดู Console ว่ามีข้อความสำเร็จ
- หากกำหนด PatreonConfig แล้ว: ค่าต่าง ๆ ถูกตั้งอัตโนมัติ
- หากไม่ได้กำหนด PatreonConfig: คัดลอกค่าที่เข้ารหัสแล้วไปใส่ PatreonConfig ด้วยตนเอง
- ลบ GameObject - ไม่ต้องใช้ในซีนอีกแล้ว
การกำหนดค่า
ตั้งค่า Patreon
ก่อนตั้งค่าปลั๊กอินใน Unity คุณต้องตั้งค่าแอปบน Patreon ก่อน:
- เป็นครีเอเตอร์บน Patreon:
- ต้องเป็นครีเอเตอร์บน Patreon จึงจะลงทะเบียน OAuth client ได้
- ไปที่ Patreon Developer Console
- สร้าง OAuth client:
- คลิก “Create Client” หรือ “Register New Client”
- กรอกรายละเอียดแอป
- สำคัญ: ตั้ง redirect URI เป็น:
http://localhost:3000/patreon-callback - ค่านี้ต้องตรงกับ redirect URI ใน PatreonConfig ทุกตัวอักษร
- รับข้อมูลรับรอง:
- Client ID: คัดลอกจากการตั้งค่า OAuth client
- Client Secret: คัดลอกจากการตั้งค่า OAuth client (เก็บเป็นความลับ!)
- Creator ID: ชื่อผู้ใช้ Patreon ของคุณ (เช่น ถ้า Patreon ของคุณคือ
patreon.com/DryreLCreator ID คือDryreL)
คำเตือนด้านความปลอดภัย:
- ห้ามแชร์ Client ID และ Client Secret กับใคร
- ห้าม commit ค่าเหล่านี้เข้าระบบควบคุมเวอร์ชัน
- ห้ามโพสต์ในฟอรัมสาธารณะหรือช่อง Discord
- ข้อมูลรับรองเหล่านี้ให้สิทธิ์เข้าถึงบัญชี Patreon ของคุณเต็มรูปแบบ
การตั้งค่า Unity
หลังสร้างแอสเซ็ต PatreonConfig (ดูการตั้งค่าซีนด้านบน) ให้ตั้งค่า Patreon API:
- Redirect URI:
http://localhost:3000/patreon-callback(ต้องตรงกับการตั้งค่าในคอนโซล Patreon) - Creator ID: ชื่อผู้ใช้ Patreon ของคุณ (เช่น
DryreLสำหรับpatreon.com/DryreL) - Authentication Timeout: ระยะเวลารอให้ผู้ใช้ยืนยันตัวตน (ค่าเริ่มต้น: 120 วินาที)
สำคัญมาก: Redirect URI ใน PatreonConfig ต้องตรงกับในการตั้งค่า Patreon Developer Console ทุกตัวอักษร!
สำคัญ: ห้าม commit PatreonConfig เข้าระบบควบคุมเวอร์ชัน!
- เพิ่ม
Assets/Resources/PatreonConfig.assetลงในไฟล์.gitignore - ไฟล์นี้มีข้อมูลรับรอง API ที่อ่อนไหว
Client ID และ Client Secret จะถูกตั้งค่าอัตโนมัติเมื่อใช้สคริปต์ PatreonEncryptCredentials!
🌐 คู่มือตั้งค่า middleware
การใช้ URI scheme แบบไดนามิก
ตอนนี้ปลั๊กอินใช้ระบบ middleware ที่ให้ทุกแพลตฟอร์มใช้ redirect URI เดียวกัน
1. การสร้าง URL ของ OAuth:
https://yourdomain.com/api/oauth/redirect?scheme=YOUR_APP_SCHEME
ตัวอย่าง:
https://yourdomain.com/api/oauth/redirect?scheme=mygame.oauthhttps://yourdomain.com/api/oauth/redirect?scheme=awesomeapp.authhttps://yourdomain.com/api/oauth/redirect?scheme=unitygame.patreon
2. การตั้งค่าแอป Patreon:
- Redirect URI:
https://yourdomain.com/api/oauth/redirect?scheme=YOUR_APP_SCHEME - Client ID: เหมือนเดิม
- Client Secret: เหมือนเดิม
3. การตั้งค่าแพลตฟอร์ม:
Android (AndroidManifest.xml):
<activity android:name="com.unity3d.player.UnityPlayerActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="YOUR_APP_SCHEME" />
</intent-filter>
</activity>
iOS (Info.plist):
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Patreon OAuth</string>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR_APP_SCHEME</string>
</array>
</dict>
</array>
4. การตั้งค่า PatreonConfig:
ตั้งค่า URI scheme ของคุณใน PatreonConfig:
- Custom URI Scheme: ตั้งเป็น scheme ที่ต้องการ (เช่น
mygame.oauth) - Redirect URI: อัปเดตให้ตรงกับ URL ของ middleware
- การเปลี่ยนแปลงทั้งหมด: ทำผ่านหน้า PatreonConfig
5. URL ทดสอบ:
https://yourdomain.com/api/oauth/redirect?scheme=YOUR_APP_SCHEME&code=test123&state=test456
✅ ข้อดี:
- middleware เดียวสำหรับทุกเกม
- scheme แบบไดนามิกต่างกันในแต่ละเกม
- ตั้งค่าง่าย แค่เปลี่ยน scheme
- ตรวจจับแพลตฟอร์มอัตโนมัติ
🔧 วิธีใช้:
- เลือก scheme:
mygame.oauth - การตั้งค่าแอป Patreon:
https://yourdomain.com/api/oauth/redirect?scheme=mygame.oauth - คัดลอกไฟล์แพลตฟอร์มแล้วเปลี่ยน scheme
- ตั้งค่า
customUriSchemeใน Unity - ทดสอบเลย! 🎯
👑 ตั้งค่า Creator API (ไม่บังคับ)
สำหรับฟีเจอร์ขั้นสูง เช่น ข้อมูลแคมเปญ รายชื่อสมาชิก และข้อมูลระดับ:
ขั้นที่ 1: รับ Creator's Access Token
- ไปที่ Patreon Developer Console
- สร้าง “Creator’s Access Token” (ไม่ใช่ OAuth Client)
- เลือก scope:
campaigns,campaigns.members,campaigns.tiers - คัดลอก Access Token และ Refresh Token
ขั้นที่ 2: เปิดใช้ Creator API
- ในสคริปต์
PatreonEncryptCredentials:- ✅ ติ๊ก “Enable Creator API”
- ใส่ Creator Access Token
- ใส่ Creator Refresh Token
- คลิก “Encrypt All Credentials”
- ค่าต่าง ๆ จะถูกตั้งใน PatreonConfig อัตโนมัติ
อีกทางเลือก: ตั้งค่าด้วยตนเอง
คุณตั้งค่าโทเค็น Creator API ใน PatreonConfig โดยตรงได้เช่นกัน:
- Creator Access Token: ตั้งใน PatreonConfig เพื่อเข้าถึงข้อมูลแคมเปญ/สมาชิก
- Creator Refresh Token: ตั้งใน PatreonConfig เพื่อต่ออายุโทเค็น
- Enable Creator API: เปิดใน PatreonConfig เพื่อใช้ฟีเจอร์ขั้นสูง
หมายเหตุ: ตรวจสอบให้แน่ใจว่าเข้ารหัสแล้ว!
ขั้นที่ 3: ใช้ Creator API
// Get campaign information
StartCoroutine(PatreonManager.Instance.GetCampaignInfo());
// Get all campaign members/patrons
StartCoroutine(PatreonManager.Instance.GetCampaignMembers());
// Get campaign tiers/rewards
StartCoroutine(PatreonManager.Instance.GetCampaignTiers());
ขั้นที่ 4: แสดงใน UI
ใช้ PatreonUserInfoDisplay กับฟิลด์ใหม่:
- ชื่อแคมเปญ, สรุปแคมเปญ, จำนวนผู้สนับสนุน
- ยอดของระดับ, คำอธิบายระดับ, ขีดจำกัดระดับ
- เป็นสมาชิกตั้งแต่, สถานะการสนับสนุน, การเรียกเก็บครั้งถัดไป
อ้างอิง: Patreon API Guide
การยืนยันตัวตน
ขั้นตอนการเข้าสู่ระบบ
กระบวนการยืนยันตัวตนเป็นไปตามมาตรฐาน OAuth 2.0:
- เริ่มต้น authenticator
- เริ่มกระบวนการเข้าสู่ระบบ
- จัดการ callback
- ตรวจสอบโทเค็น
ตัวอย่างพื้นฐาน:
using DryreL.Patreon;
public class PatreonManager : MonoBehaviour
{
private PatreonAuthenticator authenticator;
void Start()
{
authenticator = new PatreonAuthenticator();
authenticator.OnLoginSuccess += OnLoginSuccess;
authenticator.OnLoginFailed += OnLoginFailed;
}
public void Login()
{
authenticator.StartLogin();
}
private void OnLoginSuccess(PatreonUser user)
{
Debug.Log($"Welcome, {user.FullName}!");
// Handle successful login
}
private void OnLoginFailed(string error)
{
Debug.LogError($"Login failed: {error}");
// Handle login failure
}
}
การจัดการโทเค็น
ปลั๊กอินจัดการการรีเฟรชและการเก็บโทเค็นให้อัตโนมัติ:
// Check if user is authenticated
if (authenticator.IsAuthenticated)
{
// Get current user
PatreonUser user = authenticator.CurrentUser;
// Check subscription status
bool isSubscriber = user.IsSubscriber;
string tier = user.SubscriptionTier;
}
ข้อมูลอ้างอิง API
คลาส
PatreonManager
คลาส singleton หลักสำหรับจัดการการยืนยันตัวตน Patreon
พร็อพเพอร์ตี:
bool IsUserAuthenticated()- คืนค่า true หากผู้ใช้เข้าสู่ระบบแล้วPatreonUser GetCurrentUser()- ดึงผู้ใช้ที่ยืนยันตัวตนอยู่ในขณะนี้string GetValidAccessToken()- ดึง access token ที่ใช้ได้ (รีเฟรชเมื่อจำเป็น)
เมธอด:
void StartPatreonAuth()- เริ่มขั้นตอน OAuth ของ Patreonvoid Logout()- ออกจากระบบผู้ใช้ปัจจุบันและล้างโทเค็นvoid SetAccessToken(string token)- ตั้งค่า access tokenvoid ExchangeCodeForToken(string code, string state)- แลกรหัสอนุญาตเป็น access token
PatreonUser
แทนผู้ใช้ Patreon พร้อมข้อมูลการสมัคร
พร็อพเพอร์ตี:
string Id- Patreon ID ของผู้ใช้string FullName- ชื่อเต็มของผู้ใช้string Email- อีเมลของผู้ใช้string FirstName- ชื่อจริงของผู้ใช้string LastName- นามสกุลของผู้ใช้string Vanity- URL เฉพาะของผู้ใช้string ImageUrl- URL รูปโปรไฟล์ของผู้ใช้bool IsPatron- ผู้ใช้เป็นผู้สนับสนุนหรือไม่float PledgeAmount- ยอดสนับสนุนเป็นดอลลาร์bool HasPledge- ผู้ใช้มีการสนับสนุนที่ใช้งานอยู่หรือไม่string DisplayName- ชื่อที่แสดงของผู้ใช้string PatronStatus- สถานะผู้สนับสนุนของผู้ใช้string TierTitle- ชื่อระดับการสมัครของผู้ใช้int CentsPledged- ยอดสนับสนุนเป็นเซนต์
เมธอด:
void LoadProfileAvatar(Action<Sprite> onComplete)- โหลดอวาตาร์โปรไฟล์ของผู้ใช้เป็น Sprite
เมธอด
StartLogin()
เริ่มขั้นตอน OAuth ของ Patreon
public void StartLogin()
ค่าที่คืน: void
ตัวอย่าง:
authenticator.StartLogin();
Logout()
ออกจากระบบผู้ใช้ปัจจุบันและล้างโทเค็นที่เก็บไว้
public void Logout()
ค่าที่คืน: void
ตัวอย่าง:
authenticator.Logout();
อีเวนต์
OnLoginSuccess
ทำงานเมื่อผู้ใช้เข้าสู่ระบบสำเร็จ
public event Action<PatreonUser> OnLoginSuccess;
พารามิเตอร์:
PatreonUser user- ผู้ใช้ที่ยืนยันตัวตนแล้ว
OnLoginFailed
ทำงานเมื่อเข้าสู่ระบบไม่สำเร็จ
public event Action<string> OnLoginFailed;
พารามิเตอร์:
string error- ข้อความแสดงข้อผิดพลาดที่อธิบายสาเหตุ
ตัวอย่าง
การยืนยันตัวตนพื้นฐาน
using UnityEngine;
public class SimplePatreonExample : MonoBehaviour
{
void Start()
{
// Subscribe to events
PatreonManager.OnUserAuthenticated += HandleLoginSuccess;
PatreonManager.OnAuthenticationFailed += HandleLoginFailed;
}
public void LoginButtonClicked()
{
PatreonManager.Instance.StartPatreonAuth();
}
private void HandleLoginSuccess(PatreonUser user)
{
Debug.Log($"Welcome {user.FullName}!");
if (user.IsPatron)
{
Debug.Log($"You are a patron with tier: {user.TierTitle}");
Debug.Log($"Pledge amount: ${user.PledgeAmount:F2}");
// Unlock premium content
}
else
{
Debug.Log("You are not a patron");
// Show subscription prompt
}
}
private void HandleLoginFailed(string error)
{
Debug.LogError($"Login failed: {error}");
// Show error message to user
}
}
การจัดการเนื้อหาพรีเมียม
public class PremiumContentManager : MonoBehaviour
{
[SerializeField] private PatreonAuthenticator authenticator;
[SerializeField] private GameObject premiumContent;
void Start()
{
CheckSubscriptionStatus();
}
private void CheckSubscriptionStatus()
{
if (authenticator.IsAuthenticated)
{
PatreonUser user = authenticator.CurrentUser;
if (user.IsSubscriber)
{
EnablePremiumContent(user.SubscriptionTier);
}
else
{
DisablePremiumContent();
}
}
else
{
DisablePremiumContent();
}
}
private void EnablePremiumContent(string tier)
{
premiumContent.SetActive(true);
// Configure content based on tier
switch (tier)
{
case "Bronze":
// Bronze tier features
break;
case "Silver":
// Silver tier features
break;
case "Gold":
// Gold tier features
break;
}
}
private void DisablePremiumContent()
{
premiumContent.SetActive(false);
}
}
การแก้ปัญหา
ปัญหาที่พบบ่อย
ข้อผิดพลาด “Invalid Client ID”
ปัญหา: พบข้อผิดพลาด “Invalid Client ID” ขณะยืนยันตัวตน
วิธีแก้:
- ตรวจสอบ Client ID ใน Patreon Developer Portal
- ตรวจสอบว่าใส่ Client ID ใน Project Settings ของ Unity ถูกต้อง
- ตรวจสอบว่าแอปตั้งค่าบน Patreon ถูกต้อง
ปัญหาการรีเฟรชโทเค็น
ปัญหา: โทเค็นไม่รีเฟรชอัตโนมัติ
วิธีแก้:
- ตรวจสอบการเชื่อมต่ออินเทอร์เน็ต
- ตรวจสอบว่า Client Secret ถูกต้อง
- ตรวจสอบว่า redirect URI ตรงกันทุกตัวอักษร
ปัญหาการบิลด์ใน Unity
ปัญหา: ปลั๊กอินทำงานในเอดิเตอร์แต่ไม่ทำงานในบิลด์
วิธีแก้:
- ตรวจสอบว่ารวม dependency ที่จำเป็นทั้งหมดไว้ในบิลด์
- ตรวจสอบว่าการตั้งค่า Patreon พร้อมสำหรับโปรดักชัน
- ตรวจสอบว่าแอปที่เผยแพร่เข้าถึง redirect URI ได้
โหมดดีบัก
เปิดโหมดดีบักเพื่อดูล็อกละเอียดขึ้น:
PatreonConfig config = new PatreonConfig
{
// ... other settings
DebugMode = true
};
แพลตฟอร์มที่รองรับ
| แพลตฟอร์ม | สถานะ | หมายเหตุ |
|---|---|---|
| WebGL | ✅ รองรับเต็มรูปแบบ | ยืนยันตัวตนผ่านเบราว์เซอร์พร้อมเซิร์ฟเวอร์ในตัว |
| Android | ✅ รองรับเต็มรูปแบบ | ผสานกับเบราว์เซอร์แบบเนทีฟ, middleware (URI กำหนดเอง) |
| iOS | ✅ รองรับเต็มรูปแบบ | ผสานกับเบราว์เซอร์แบบเนทีฟ, middleware (URI กำหนดเอง) |
| Windows | ✅ รองรับเต็มรูปแบบ | บิลด์ 32-bit และ 64-bit |
| Mac | ✅ รองรับเต็มรูปแบบ | รองรับ universal binary |
| Linux | ✅ รองรับเต็มรูปแบบ | ทุกดิสทริบิวชันหลัก |
ฟีเจอร์บนแพลตฟอร์มมือถือ
- Application.identifier: รองรับเต็มรูปแบบบน iOS/Android
- Device ID: คีย์เข้ารหัสที่ปลอดภัยเฉพาะอุปกรณ์
- เบราว์เซอร์ของระบบ: ขั้นตอน OAuth แบบเนทีฟพร้อมกลับเข้าแอป
- StreamingAssets: จัดการไฟล์ตามแพลตฟอร์ม
- URL scheme: จัดการ callback แบบกำหนดเอง
🔗 การจัดการ callback ตามแพลตฟอร์ม
ทุกแพลตฟอร์ม (ระบบ middleware แบบรวม)
- redirect URI เดียว:
https://yourdomain.com/api/oauth/redirect?scheme=YOUR_APP_SCHEME - scheme แบบไดนามิก: แต่ละเกมใช้ URI scheme ของตัวเองได้
- ตรวจจับแพลตฟอร์ม: ตรวจจับและกำหนดเส้นทางอัตโนมัติ
- รองรับทุกที่: ใช้ได้บนเดสก์ท็อป มือถือ และ WebGL
แพลตฟอร์มมือถือ (Android, iOS, Windows, UWP)
- Deep linking: URI scheme กำหนดเอง (
YOUR_APP_SCHEME://patreon-callback) - การเปลี่ยนเส้นทางของ middleware:
https://yourdomain.com/api/oauth/redirect→ deep link - เบราว์เซอร์ของระบบ: ขั้นตอน OAuth แบบเนทีฟพร้อมกลับเข้าแอปอัตโนมัติ
- ตรวจสอบ state: ป้องกัน CSRF ด้วยพารามิเตอร์ state
แพลตฟอร์ม WebGL
- ขั้นตอน middleware: ใช้
https://yourdomain.com/api/oauth/redirect - JavaScript callback: สื่อสาร
postMessageกับหน้าต่างหลัก - ไม่ต้องมีเซิร์ฟเวอร์: ใช้บริการ middleware ที่โฮสต์ไว้
- รองรับ CORS: จัดการคำขอข้ามต้นทาง
แพลตฟอร์มเดสก์ท็อป (Windows, Mac, Linux)
- การเปลี่ยนเส้นทางของ middleware:
https://yourdomain.com/api/oauth/redirect→localhost:3000 - เซิร์ฟเวอร์ในตัว: HTTP Listener ที่
localhost:3000 - ขั้นตอน loopback: เบราว์เซอร์ → middleware → localhost → callback ของแอป
- ไม่มี dependency: ใช้ HttpListener ของ .NET ล้วน
📱 สิ่งที่ต้องตั้งค่าบนมือถือ
ตั้งค่า Android
- สร้าง AndroidManifest.xml ใน
Assets/Plugins/Android/: ```xml
#### **iOS Setup**
1. **Player Settings** → **Other** → **Configuration**
2. **Add to Supported URL schemes**: `YOUR_APP_SCHEME`
3. Make sure **ios-info.plist** created.
4. **Xcode**: Verify URL scheme registration
#### **Patreon OAuth Client Configuration**
- **All Platforms**: Use single redirect URI with middleware
- **Redirect URI**: `https://yourdomain.com/api/oauth/redirect?scheme=YOUR_APP_SCHEME`
- **Client Type**: Select "Web application" (works for all platforms)
- **Dynamic Scheme**: Each game uses its own URI scheme
### 🌐 **Unified Middleware System**
**Hosted Middleware**: `https://yourdomain.com/api/oauth/redirect`
**Features:**
- **Platform Detection**: Automatic platform detection and routing
- **Dynamic Scheme**: Each game uses its own URI scheme
- **Universal Support**: Works on Desktop, Mobile, and WebGL
- **No Setup Required**: Uses hosted middleware service
**Middleware Workflow:**
1. **Patreon** → `https://yourdomain.com/api/oauth/redirect?scheme=YOUR_APP_SCHEME&code=...&state=...`
2. **Middleware** → Platform detection
3. **Redirect** → Platform-specific callback method
### 🚀 **Usage Examples**
#### **Platform-Specific OAuth Flow**
```csharp
// Automatic platform detection and callback handling
PatreonCallbackManager callbackManager = GetComponent<PatreonCallbackManager>();
callbackManager.StartPatreonOAuthFlow(clientId, state);
// Get platform-specific redirect URI
string redirectUri = callbackManager.GetPlatformRedirectUri();
Debug.Log($"Platform redirect URI: {redirectUri}");
การจัดการ deep link บนมือถือ
// Mobile deep link callback (called by system)
PatreonDeepLinkHandler deepLinkHandler = GetComponent<PatreonDeepLinkHandler>();
deepLinkHandler.HandleDeepLinkCallback("myapp.oauth://patreon-callback?code=abc123&state=xyz789");
// Test deep link callback
deepLinkHandler.TestDeepLinkCallback();
การจัดการ middleware บน WebGL
// WebGL middleware callback
PatreonWebGLHandler webGLHandler = GetComponent<PatreonWebGLHandler>();
webGLHandler.StartPatreonOAuthFlow(clientId, state);
// Test WebGL callback
webGLHandler.TestWebGLCallback();
ข้อมูลแพลตฟอร์ม
// Show current platform and callback method
PatreonCallbackManager callbackManager = GetComponent<PatreonCallbackManager>();
callbackManager.ShowPlatformInfo();
// Output:
// 📱 Current Platform: AndroidPlayer
// 📱 Redirect URI: myapp.oauth://patreon-callback
// 🔗 Using deep link callback method
🧪 การทดสอบ
คำสั่งทดสอบ
Test Platform OAuth Flow: ทดสอบขั้นตอน OAuth ตามแพลตฟอร์มTest Deep Link Callback: ทดสอบการจัดการ deep link บนมือถือTest WebGL Callback: ทดสอบการจัดการ middleware บน WebGLShow Platform Info: แสดงข้อมูลแพลตฟอร์มปัจจุบัน
สคริปต์ทดสอบ
PatreonCallbackManager: ทดสอบตามแพลตฟอร์มPatreonDeepLinkHandler: ทดสอบ deep link บนมือถือPatreonWebGLHandler: ทดสอบ middleware บน WebGLPatreonMobileTest: ทดสอบความเข้ากันได้กับมือถือ
การทดสอบความปลอดภัย
ปลั๊กอินมีระบบทดสอบความปลอดภัยครบถ้วน:
1. เพิ่มคอมโพเนนต์ Security Test
// Add PatreonSecurityTest component to any GameObject
// Right-click on GameObject → Add Component → PatreonSecurityTest
2. รันการทดสอบความปลอดภัย
// In Inspector, click "Run All Security Tests" or use code:
var securityTest = GetComponent<PatreonSecurityTest>();
securityTest.RunAllTests();
3. ทดสอบคอมโพเนนต์ทีละตัว
// Test encryption only
securityTest.TestEncryption();
// Test obfuscation only
securityTest.TestObfuscation();
// Test secure storage only
securityTest.TestSecureStorage();
// Performance test
securityTest.PerformanceTest();
4. การตรวจสอบความปลอดภัย
// Validate entire security system
bool isValid = PatreonSecurity.PatreonSecurity.ValidateSecuritySystem();
Debug.Log($"Security system valid: {isValid}");
ฝ่ายสนับสนุน
ขอความช่วยเหลือ
หากพบปัญหาหรือมีคำถาม:
- อ่านเอกสาร - ปัญหาทั่วไปส่วนใหญ่มีคำตอบอยู่ที่นี่
- เข้าร่วมชุมชน Discord ของเรา - รับความช่วยเหลือจากนักพัฒนาคนอื่นและทีมของเรา
- ติดต่อฝ่ายสนับสนุน - สำหรับปัญหาทางเทคนิค โปรดส่งข้อมูลต่อไปนี้มา:
- เวอร์ชัน Unity
- เวอร์ชันปลั๊กอิน
- ขั้นตอนที่ทำให้เกิดปัญหา
- ข้อความแสดงข้อผิดพลาด
- ไฟล์ log
ชุมชน
เข้าร่วมชุมชนของเราเพื่อรับความช่วยเหลือและข่าวอัปเดต:
- อีเมล: [email protected]
- Discord: เข้าร่วมชุมชนของเรา
- YouTube: DryreL Hub
- YouTube #2: DryreL Software
อัปเดต
ติดตามฟีเจอร์ล่าสุดและการแก้บั๊ก:
- Unity Asset Store: ดาวน์โหลดจาก Marketplace (เร็ว ๆ นี้)
- ชุมชน Discord: เข้าร่วม Discord ของ DryreL Hub เพื่อรับความช่วยเหลือและข่าวอัปเดต
ข้อจำกัดความรับผิดและความรับผิดชอบ
ประกาศด้านความปลอดภัยที่สำคัญ
ปลั๊กอินนี้มีการเข้ารหัส AES-256 และการ obfuscate เพื่อช่วยปกป้องข้อมูลรับรอง API ของ Patreon อย่างไรก็ตาม ผู้ใช้เป็นผู้รับผิดชอบแต่เพียงผู้เดียว ต่อความปลอดภัยของข้อมูลรับรองและผลที่ตามมาทั้งหมดหากข้อมูลนั้นรั่วไหล
ฟีเจอร์ความปลอดภัยที่มีให้
- การเข้ารหัส AES-256: สำหรับปกป้อง Client Secret
- การ obfuscate แบบ XOR: สำหรับซ่อน Client ID
- การสร้างคีย์หลายชั้น: คีย์เข้ารหัสเฉพาะแต่ละแพลตฟอร์ม
- การป้องกันการดัดแปลง: ตรวจสอบความสมบูรณ์ขั้นพื้นฐาน
- บันทึกการตรวจสอบความปลอดภัย: เครื่องมือติดตามและดีบัก
ความรับผิดชอบของผู้ใช้
- จัดเก็บอย่างปลอดภัย: ห้าม commit
PatreonConfigเข้าระบบควบคุมเวอร์ชัน - ใช้อย่างถูกต้อง: ปฏิบัติตามแนวทางความปลอดภัยทั้งหมดในเอกสารนี้
- อัปเดตสม่ำเสมอ: รักษาข้อมูลรับรองให้เป็นปัจจุบันและเปลี่ยนเป็นระยะ
- ความปลอดภัยของสภาพแวดล้อม: ตรวจให้แน่ใจว่าสภาพแวดล้อมการพัฒนาและการใช้งานจริงปลอดภัย
- การควบคุมการเข้าถึง: จำกัดการเข้าถึงไฟล์ข้อมูลรับรองและผลลัพธ์จากการ build
ข้อจำกัดความรับผิด
DRYREL HUB ไม่รับผิดชอบ ต่อความเสียหายใด ๆ ไม่ว่าทางตรง ทางอ้อม โดยบังเอิญ พิเศษ ต่อเนื่อง หรือเชิงลงโทษ รวมถึงแต่ไม่จำกัดเพียง:
- ความเสียหายทางการเงิน: รายได้ที่สูญเสีย ธุรกิจหยุดชะงัก หรือความสูญเสียทางการเงิน
- การละเมิดความปลอดภัย: การเข้าถึงบัญชีหรือข้อมูล Patreon โดยไม่ได้รับอนุญาต
- การใช้ API ในทางที่ผิด: บุคคลที่สามนำข้อมูลรับรองไปใช้ในทางที่ผิด
- ข้อมูลรั่วไหล: ข้อมูลสำคัญหลุดออกไป
- บริการหยุดชะงัก: ระบบล่มหรือใช้งานบริการไม่ได้
- ผลทางกฎหมาย: ปัญหาทางกฎหมายใด ๆ ที่เกิดจากข้อมูลรับรองรั่วไหล
ใช้ปลั๊กอินนี้โดยยอมรับความเสี่ยงเอง ไม่มีการรับประกันใด ๆ
🔧 API V2: ปัญหาและวิธีแก้ตามประเภทบัญชี
⚠️ ปัญหาที่ทราบกับบัญชีประเภทต่าง ๆ
เมื่อทดสอบกับบัญชี Patreon ประเภทต่าง ๆ (ครีเอเตอร์กับผู้ใช้ทั่วไป) อาจพบปัญหาต่อไปนี้:
1. ไม่ได้รับอีเมล
- ปัญหา: ช่องอีเมลว่างสำหรับผู้ใช้ทั่วไป
- สาเหตุ: ข้อจำกัดของ scope OAuth
- วิธีแก้: scope OAuth ที่ขยายแล้วตอนนี้รวมถึง
identity[email]
2. ไม่ได้รับรูปโปรไฟล์
- ปัญหา: URL รูปโปรไฟล์ว่าง
- สาเหตุ: การจับคู่ฟิลด์ของ API แตกต่างกัน
- วิธีแก้: ใช้
thumb_urlอัตโนมัติเมื่อimage_urlว่าง
3. ข้อมูล tier/สถานะไม่ถูกต้อง
- ปัญหา: ผู้ใช้ทั่วไปแสดงเป็น tier “creator”
- สาเหตุ: การตอบกลับของ API ไม่สอดคล้องกันระหว่างประเภทบัญชี
- วิธีแก้: เพิ่มการบันทึก log และการตรวจสอบ (ดูคำเตือนใน console)
4. ไม่ได้รับลิงก์โซเชียล
- ปัญหา: ลิงก์ YouTube, Twitter, Facebook ว่าง
- สาเหตุ: ผู้ใช้ทั่วไปเข้าถึงฟิลด์ API ได้จำกัด
- วิธีแก้: ขอฟิลด์เพิ่มเติมในการเรียก API
🔍 ข้อมูลดีบัก
ตอนนี้ปลั๊กอินมี log ดีบักครบถ้วน ดูใน Console ของ Unity สำหรับ:
🔧 === USER DATA DEBUG ===- การวิเคราะห์ข้อมูลผู้ใช้อย่างละเอียด🔧 Email not available- คำเตือนข้อจำกัดของ scope🔧 Normal user has tier_title- ความไม่สอดคล้องของประเภทบัญชี
📋 รายการตรวจสอบการทดสอบ
เมื่อทดสอบกับบัญชีประเภทต่าง ๆ:
- ทดสอบบัญชีครีเอเตอร์:
- ✅ ต้องได้รับอีเมล
- ✅ ต้องได้รับรูปโปรไฟล์
- ✅ ข้อมูล tier ต้องถูกต้อง
- ✅ อาจมีลิงก์โซเชียล
- ทดสอบบัญชีผู้ใช้ทั่วไป:
- ⚠️ อาจไม่มีอีเมล (ขึ้นอยู่กับ scope)
- ✅ ต้องได้รับรูปโปรไฟล์ (มีค่าสำรอง)
- ⚠️ ข้อมูล tier อาจไม่ถูกต้อง (บันทึกเป็นคำเตือน)
- ⚠️ อาจไม่มีลิงก์โซเชียล
🛠️ scope OAuth ที่ขยายเพิ่ม
ตอนนี้ปลั๊กอินขอ scope ที่ขยายเพิ่ม:
identity identity[email] identity.memberships campaigns
ช่วยให้เข้าถึงข้อมูลผู้ใช้ได้ดีขึ้นในบัญชีทุกประเภท
🔧 การตรวจสอบและแก้ไขข้อมูล API
หมายเหตุสำคัญ: ปลั๊กอินมีการตรวจสอบข้อมูลฝั่ง client และแก้ไขความไม่สอดคล้องที่ทราบของ Patreon API V2 ซึ่งจำเป็นเพราะ:
- ปัญหาข้อมูล API: บางครั้ง Patreon API V2 ส่งข้อมูลผิดสำหรับผู้ใช้ทั่วไป (เช่น แสดง tier “Creator” ให้ผู้ใช้ทั่วไป)
- ข้อมูลขัดแย้งกัน: API อาจส่งค่าที่ขัดแย้งกัน (เช่น
patron_status: "not_patron"แต่is_patron: true) - ประเภทบัญชีปนกัน: บางครั้งข้อมูลผู้ใช้กับครีเอเตอร์ปนกันในการตอบกลับของ API
- ปัญหาสถานะผู้ติดตาม: ฟิลด์
is_followerไม่น่าเชื่อถือ และอาจส่งfalseแม้ผู้ใช้จะติดตามอยู่
สิ่งที่ปลั๊กอินทำ:
- ✅ ตรวจสอบข้อมูลผู้ใช้ทั้งหมดจาก API
- ✅ แก้ความไม่สอดคล้องของข้อมูลที่ทราบโดยอัตโนมัติ
- ✅ บันทึกปัญหา API ไว้สำหรับดีบัก
- ✅ ใช้ค่าสำรองเมื่อจำเป็น
- ✅ เตือนเกี่ยวกับฟิลด์ที่ไม่น่าเชื่อถือ เช่น
is_follower
log ใน console ที่ควรสังเกต:
🔧 API ISSUE: Normal user has incorrect tier_title: Creator - fixing🔧 API ISSUE: is_follower is false - this might be incorrect due to Patreon API V2 limitations🔧 API DATA ISSUES DETECTED AND FIXED - This indicates Patreon API V2 data inconsistencies
ข้อจำกัดของ API ที่ทราบ:
is_follower: ฟิลด์นี้ไม่น่าเชื่อถือใน Patreon API V2 และอาจส่งfalseแม้ผู้ใช้จะติดตามครีเอเตอร์อยู่- การตรวจจับผู้ติดตาม: การตรวจจับผู้ติดตามให้แม่นยำต้องเรียก API เพิ่มไปยัง endpoint campaigns/pledges
- อ้างอิง: ดู Patreon API Guide สำหรับวิธีตรวจจับผู้ติดตามที่ถูกต้อง
แนวทางนี้ทำให้ได้ข้อมูลผู้ใช้ที่เชื่อถือได้แม้ API จะไม่สอดคล้องกัน
ขอบคุณ!
ขอบคุณที่ใช้ Patreon Authenticator for Unity หวังว่าปลั๊กอินนี้จะช่วยสร้างประสบการณ์ที่ยอดเยี่ยมให้ผู้สนับสนุนบน Patreon!

