تغییرات این نسخه:
1. آپلود مستقیم ادمین: فقط فایل بفرست (بدون رفتن به پنل مدیریت آپلود)
2. همه متن‌های مهم کاربر قابل ویرایش از پنل (تنظیمات > تغییر متن‌های ربات)
3. ویرایش متن با ادیت همان پیام (نه پیام جدید)
4. متن‌های اضافه: هشدار تمدید، پرداخت TON، رسید، ربات خاموش، ...
5. کیبورد پنل کاربر دست نخورده باقی مانده
6. مشاهده فایل‌ها: دکمه ویرایش کپشن + تعویض فایل + حذف
7. پشتیبانی ایموجی پرمیوم در ویرایش متن‌های ربات (ذخیره entities)
8. پنل ادمین قسمت‌ها: اول لیست فصل‌ها، بعد از انتخاب فصل دکمه‌های «قسمت ۰۱» سه‌ستونه + صفحه‌بندی (قسمت بعدی / صفحه اصلی / برگشت)
9. ویزارد ثبت سریال کاملاً بازطراحی شد: نوار پیشرفت، دکمه‌های آماده زبان/کشور/ژانر (چند‌انتخابی)، رد تک‌مرحله و رد بقیه، ثبت سریع نهایی
10. ایموجی پرمیوم: با فرستادن متن (متن‌های ربات / متن دکمه کیبورد) خودکار شناسایی و ذخیره می‌شود — نیازی به تنظیم جداگانه نیست؛ پیش‌نمایش هم با ایموجی پرمیوم نمایش داده می‌شود

──────────────────────────────────────────────
رفع مشکل «کندی/تاخیر ۵ دقیقه‌ای گاه‌به‌گاه در کلیک دکمه‌ها»:
──────────────────────────────────────────────
علت: چندین تابع curl (بیشتر مربوط به ارسال همگانی، پین پیام، ارسال عکس/ویدیو/
فایل/صدا/استیکر، بکاپ و ...) هیچ CURLOPT_TIMEOUT/CURLOPT_CONNECTTIMEOUT
نداشتند. اگر تلگرام برای یکی از کاربران دیر جواب می‌داد یا کانکشن گیر می‌کرد،
اسکریپت (به‌خصوص cron.php که هر دقیقه اجرا می‌شود و صدها کاربر را در یک اجرا
پیام می‌دهد) می‌توانست دقیقه‌ها معلق بماند و روی هاست اشتراکی یک پروسه PHP را
اشغال کند؛ همین باعث می‌شد کلیک دکمه‌های عادی کاربران هم تا آزاد شدن یک worker
صف بکشند.

تغییرات اعمال‌شده:
- admin_extras.php: توابع broadcast_copy_message و broadcast_message_with_entities
  (ارسال همگانی + پین) اکنون CONNECTTIMEOUT=3s و TIMEOUT=12s دارند.
  batch_size از ۱۰۰ به ۵۰ کاهش یافت تا هر اجرای cron سریع‌تر تمام شود.
- functions.php: send_sticker / send_photo / send_video / send_document /
  send_audio / send_voice / perform_backup(sendDocument) / 
  update_channel_post_like_keyboard اکنون timeout دارند (بکاپ چون فایل حجیم‌تری
  آپلود می‌کند timeout=60s گرفته).
- ads.php و features.php: curl مربوط به sendInvoice / answerPreCheckoutQuery
  اکنون timeout دارند.
- language.php: ارسال عکس ابتدای بات (start_send_photo) timeout گرفت.
- lucky_prize.php: send_dice timeout گرفت.
- cron.php: یک سقف زمانی سخت‌گیرانه set_time_limit(90) اضافه شد تا در بدترین
  حالت هم اجرای cron بیش از ۹۰ ثانیه یک پروسه PHP را اشغال نکند.

نتیجه: حتی اگر تلگرام یا شبکه برای یک کاربر خاص کند جواب بدهد، حداکثر تاخیر
همان ۱۲ ثانیه (یا ۶۰ ثانیه فقط برای آپلود بکاپ) خواهد بود، نه چند دقیقه.

──────────────────────────────────────────────
ادامه رفع مشکل کندی — پیدا شدن علت اصلی و بزرگ‌تر:
──────────────────────────────────────────────
بعد از فیکس اول، مشخص شد مشکل فقط به curl محدود نبوده. در کل پروژه (به‌خصوص
در index.php که مغز اصلی webhook است — ۴۳ مورد!) ده‌ها فراخوانی
file_get_contents() به سرور تلگرام زده می‌شود که هیچ‌کدام timeout جداگانه
نداشتند. مقدار پیش‌فرض PHP برای این نوع درخواست‌ها (default_socket_timeout)
روی بسیاری از هاست‌ها ۶۰ ثانیه است. یعنی اگر برای *هر* کلیک دکمه‌ی عادی
کاربر (نه فقط ارسال همگانی)، اتصال به تلگرام برای یک لحظه کند/معلق شود،
همان یک درخواست webhook می‌توانست تا ۶۰ ثانیه (و با تکرار/صف‌شدن روی هاست
اشتراکی، تا چند دقیقه) طول بکشد — این دقیقاً همان رفتار «بعضی وقت‌ها سریع،
بعضی وقت‌ها ۵ دقیقه» است که کاربر گزارش داد و بعد از فیکس اول هم باقی مانده بود.

راه‌حل: به‌جای پچ تک‌تک ده‌ها نقطه، یک خط در config.php (که در همه‌ی
فایل‌های ورودی — index.php، cron.php، check_ton_payments.php،
check_renewals.php و... — همیشه اول از همه require می‌شود) اضافه شد:

    ini_set('default_socket_timeout', 8);

این سقف زمانی سراسری (۸ ثانیه) برای کل پروسه‌ی PHP روی همه‌ی این تماس‌های
file_get_contents اعمال می‌شود، حتی آن‌هایی که در فایل‌های index.php،
series.php، language.php و بقیه پخش شده بودند و context جداگانه نداشتند.
همراه با فیکس قبلی curl، الان عملاً هیچ تماس شبکه‌ای به تلگرام در کل بات
بدون سقف زمانی نیست.

batch_size توابع broadcast_message و forward_message_to_all (در
functions.php) هم مثل نسخه‌ی قبل از ۱۰۰ به ۵۰ کاهش یافت.

──────────────────────────────────────────────
بهینه‌سازی سراسری سوم — علت اصلیِ گیر کردنِ تکرارشونده:
──────────────────────────────────────────────
کل لیست کاربران (همه‌ی کاربران بات) در یک ردیف MySQL به‌صورت یک بلاک JSON
واحد ذخیره می‌شود (کلید 'users'). این یعنی هر بار که چیزی درباره‌ی کاربران
عوض می‌شود، کل این بلاک (که با رشد تعداد کاربران بزرگ‌تر و بزرگ‌تر می‌شود)
باید از نو نوشته شود؛ و چون فقط یک ردیف است، هر نوشتن، ردیف را برای بقیه‌ی
نوشتن‌های هم‌زمان قفل می‌کند.

باگ اصلی: در چهار تابع ارسال همگانی/فوروارد همگانی (broadcast_copy_message،
broadcast_message_with_entities در admin_extras.php و broadcast_message،
forward_message_to_all در functions.php)، به‌ازای هر کاربری که ربات را
بلاک/حذف کرده بود، بلافاصله save_users() صدا زده می‌شد — یعنی در یک اجرای
همگانی با ۵۰ نفر در بچ، اگر مثلاً ۱۵ نفرشان بات را بلاک کرده باشند، کل بلاک
کاربران ۱۵ بار پشت‌سرهم به‌طور کامل بازنویسی می‌شد! همین باعث می‌شد در حین
هر ارسال همگانی، ردیف 'users' مدت طولانی قفل بماند و هر درخواست webhook
دیگری (کلیک دکمه‌ی سایر کاربران، یا حتی /start زدن) که هم‌زمان به همان ردیف
نیاز داشت، پشت این قفل صف بکشد — دقیقاً همان رفتار «گاهی بدون دلیل جام
می‌کند» که گزارش شد.

فیکس: در هر ۴ تابع، حذف کاربرهای بلاک‌شده از آرایه در حافظه انجام می‌شود
ولی save_users() فقط یک‌بار، در پایان کل بچ (نه به‌ازای هر کاربر)، صدا زده
می‌شود. نتیجه: به‌جای مثلاً ۱۵ نوشتن کامل روی یک ردیف در هر بچ، فقط ۱ نوشتن.

نکته برای آینده: اگر تعداد کاربران بات خیلی زیاد شود (چند ده‌هزار به بالا)،
حتی همین یک نوشتن/خواندن کامل هم کند خواهد بود، چون کل لیست به‌عنوان یک
بلوب جابه‌جا می‌شود — دقیقاً همان مشکلی که قبلاً برای «state کاربران» با
منتقل‌کردن هرکدام به یک کلید جداگانه (ustate_<id>) حل شده (کامنت بالای
set_user_state در functions.php). راه‌حل قطعی و کامل، انجام همین کار برای
'users' هم هست: هر کاربر در یک ردیف/کلید جدا (مثلاً user_<id>) به‌همراه یک
ایندکس سبک از شناسه‌ها. این یک ریفکتور بزرگ‌تر است که به بسیاری از فایل‌ها
(هرجا آرایه‌ی کامل $users پیمایش یا مستقیم دستکاری می‌شود) سرک می‌کشد و باید
جداگانه و با احتیاط انجام شود؛ فعلاً همین فیکس دسته‌ای، مشکل قفل‌شدن حین
ارسال همگانی را کاملاً برطرف می‌کند.
