أجهزة الكمبيوتر شبابيك إنترنت

أساسيات العمل مع خادم LongPoll VK. هل هناك نقطة ضعف

أساسيات واجهة برمجة التطبيقات (يمكن لمن هم على دراية بالطرق والطلبات الأساسية لهم تخطي هذه النقطة)

ما هي واجهة برمجة تطبيقات VK؟ هذه هي الطريقة التي تفسرها الوثائق الرسمية:

Callback API هي أداة لتتبع نشاط المستخدم في مجتمع VK الخاص بك.

بمعنى آخر ، هذه طريقة لإرسال الطلبات إلى خوادم VK لتلقي استجابة تحتوي على بعض المعلومات. باستخدام VK API ، يمكنك فعل كل شيء تقريبًا: إرسال رسالة إلى المستخدم ، وتغيير كلمة مرور الحساب ، وإنشاء ألبوم به صور ، وما إلى ذلك. أنا شخصياً أستخدم مكتبة vk_api للعمل مع واجهة برمجة التطبيقات ، ولكن يمكنك أيضًا التعامل مع مكتبة الطلبات. سننظر الآن المبادئ الأساسيةالشغل. إذا قررت استخدام مكتبة vk_api ، فسيبدو طلب المثال كما يلي:

استيراد vk_api session = vk_api.VkApi (token = "(ACCESS_TOKEN)") print (session.method ("users.get"، ("user_ids": 210700286، "field": "photo_50، city، Verified")))
دعنا نحلل الخطوط:

استيراد vk_api يتم استيراد المكتبة التي نحتاجها هنا.

Session = vk_api.VkApi (token = "(ACCESS_TOKEN)") باستخدام هذا السطر ، نسمح من خلال رمز الوصول (طرق الحصول عليها موصوفة في الوثائق وعلى الإنترنت ، لن أركز عليها). لاحظ أنه ليست كل الطرق تتطلب إذنًا. عندما يكون مطلوبًا ، سيتم كتابته في وثائق الطريقة على موقع فكونتاكتي.

طباعة (session.method ("users.get"، ("user_ids": 210700286، "الحقول": "photo_50، city"))) هذا الجزء من الكود يستحق اهتمامًا خاصًا. ماذا يجري هنا؟ نسمي طريقة الطريقة ، ونمرر معاملين إليها: الأول هو اسم طريقة API ، والثاني هو قاموس من معاملات هذه الطريقة. توجد قائمة بجميع الطرق ومعلماتها في وثائق API. في هذه الحالة ، نسمي طريقة "users.get" ونمرر المعلمات التالية: "user_ids" - قائمة بمعرفات المستخدمين التي نريد تلقي بيانات لها ، "الحقول": معلومة اضافيةحول المستخدمين: الصورة الرمزية ومدينة الإقامة. ستكون نتيجة تنفيذ البرنامج هي سطر الإخراج التالي: [("id": 210700286، "first_name": "Lindsey"، "last_name": "Stirling"، "city": ("id": 5331، "title ":" Los Angeles ")،" photo_50 ":" https://pp.userapi.com/c636821/v636821286/38a75/Ay-bEZoJZw8.jpg ")]

إذا ارتكبت أي خطأ ، على سبيل المثال ، حددت اسمًا خاطئًا للطريقة التي تم استدعاؤها ، فسيتم طرح استثناء: vk_api.exceptions.ApiError: فشل ترخيص المستخدم: لم يتم تمرير access_token. ...
ملاحظة: إذا حدث خطأ في اسم معامل اختياري ، فلن يتم طرح استثناء ، وسيتم تجاهل المعلمة غير المعروفة.

إذا قررت استخدام مكتبة الطلبات ، فسيتعين عليك البحث بشكل أعمق قليلاً في وثائق API لمعرفة تنسيق الطلب والاستجابة.
يجب أن يبدو الطلب على النحو التالي: https://api.vk.com/method/(METHOD_NAME)؟(PARAMS)&v=(API_VERSION) ، حيث (METHOD_NAME) هو اسم الطريقة ، (PARAMS) هي معلمات الطريقة المطلوبة ، و (API_VERSION) - إصدار واجهة برمجة التطبيقات التي يجب أن يستخدمها الخادم عند إنشاء الاستجابة.
ردًا على ذلك ، سيتم إرجاع كائن JSON بمعلومات حول نتائج استدعاء الطريقة إلينا. دعنا ننفذ طلب API باستخدام مكتبة الطلبات:

بيانات طلبات الاستيراد = Orders.get ("https://api.vk.com/method/(METHOD_NAME)" .format (METHOD_NAME = "users.get") ، المعلمات = ("user_ids": 210700286 ، "الحقول": "photo_50، city")). json () print (data)
فلنلقِ نظرة على ما كتب.

طلبات الاستيراد - استيراد مكتبة الطلبات

البيانات = Orders.get ("https://api.vk.com/method/(METHOD_NAME)" .format (METHOD_NAME = "users.get") ، المعلمات = ("user_ids": 210700286 ، "الحقول": "photo_50 ، city ")). json () هذا السطر يكتب استجابة الخادم لمتغير البيانات. نقوم بتمرير وسيطين لوظيفة get: العنوان الذي يجب إرسال الطلب إليه (في حالتنا ، سلسلة منسقة) ، وقاموس من معلمات هذه الطريقة. إذا لم يتم استدعاء الطريقة بدون رمز وصول ، فستحتاج إلى إضافتها إلى القاموس باستخدام مفتاح "access_token". المعلمة "v" (إصدار API) اختيارية ، حيث ستكون القيمة الافتراضية احدث اصدار، ولكن إذا كنت تريد استخدام إصدار مختلف ، فستحتاج أيضًا إلى إضافته إلى القاموس باستخدام مفتاح "v". يتم تطبيق طريقة json () على الاستجابة المستلمة من الخادم ، والتي تعالج كائنات JSON.

يعرض السطر الأخير نتيجة العمل ، في حالتنا - ("response": [("uid": 210700286، "first_name": "Lindsey"، "last_name": "Stirling"، "city": 5331، " photo_50 ":" https://pp.userapi.com/c636821/v636821286/38a75/Ay-bEZoJZw8.jpg ")]).

إذا قمت بتمرير اسم أسلوب غير صحيح ، فسيتم عرض ما يلي: ("خطأ": ("error_code": 5 ، "error_msg": "فشل ترخيص المستخدم: لم يتم تمرير access_token." ، "Request_params": [("مفتاح ":" oauth "،" value ":" 1 ")، (" key ":" method "،" value ":" user.get ")، (" key ":" user_ids "،" value ":" 210700286 ") ، (" مفتاح ":" الحقول "،" القيمة ":" photo_50، city ")])).


ما هو LongPoll؟

أولاً ، دعنا ننتقل إلى الوثائق للحصول على المساعدة:

Long Polling هي تقنية تسمح لك بالحصول على معلومات حول الأحداث الجديدة باستخدام "استعلامات طويلة". يتلقى الخادم طلبًا ، ولكنه لا يرسل ردًا عليه على الفور ، ولكن فقط عند وقوع حدث (على سبيل المثال ، حدث جديد رسالة واردة) ، أو انتهاء المهلة المحددة.
بمعنى آخر ، عند تلقي طلب منك ، ينتظر الخادم حدثًا يجب أن يخطرك به ، وعندما يحدث ، يرسل خادم الاستقصاء الطويل ردًا على طلبك يحتوي على معلومات حول الحدث الذي حدث.
سنقوم بكتابة برنامج يقوم بإخطار المستخدم ببعض التغييرات في حسابه ، والتي سنستلمها من خادم الاستطلاع الطويل. لبدء تلقي الاستجابات من الخادم ، تحتاج إلى الحصول على ثلاث معلمات مطلوبة لكي يعمل Long Poll-a: الخادم والمفتاح و ts.
المفتاح - المفتاح السري للدورة ؛
الخادم - عنوان الخادم ؛
ts - رقم الحدث الأخير ، بدءًا من الذي تريد تلقي البيانات منه.

لا تحتاج إلى استقبالهم في كل مرة تقوم فيها بالاتصال باستطلاع طويل - فقط مكالمة واحدة ستكون كافية. يتبع من الوثائق أنه يمكن الحصول على هذه القيم عن طريق استدعاء طريقة messages.getLongPollServer. دعنا نكتب برنامجًا يقدم طلبًا بهذه الطريقة وسوف نستخدم البيانات المستلمة للوصول إلى الاستطلاع الطويل.

رمز طلبات الاستيراد = "" # هنا يجب أن تكتب بيانات access_token الخاصة بك = request.get ("https://api.vk.com/method/messages.getLongPollServer"، params = ("access_token": token)). Json ( ) ["response"] # احصل على استجابة من الخادم print (data)
إذا فعلت كل شيء بشكل صحيح ، فسيعرض البرنامج قاموسًا بثلاثة مفاتيح: ("مفتاح": "############################ ## "،" server ":" imv4.vk.com/im#### "،" ts ": 0000000000)


طلب إلى خادم الاستطلاع الطويل

الآن ، باستخدام القيم المخزنة في القاموس الذي تم إنشاؤه في الجزء السابق ، يمكننا الاستعلام عن خادم الاستطلاع الطويل! للقيام بذلك ، تحتاج إلى تقديم طلب إلى العنوان التالي: https: // ($ server)؟ Act = a_check & key = ($ key) & ts = ($ ts) & wait = 25 & mode = 2 & الإصدار = 2 ، حيث ($ server) و ($ key) و ($ ts) - القيم من القاموس بمفاتيح "server" و "key" و "ts" ، على التوالي ، الانتظار هو الوقت الذي يستغرقه الاستطلاع الطويل سينتظر الخادم التحديثات ، ويكون الوضع خيارات استجابة إضافية. دعنا نكتب برنامجًا يقدم طلبًا واحدًا إلى خادم Long Poll

رمز طلبات الاستيراد = "" # يجب عليك كتابة access_token الخاص بك هنا params = calls.get ("https://api.vk.com/method/messages.getLongPollServer"، params = ("access_token": token)). Json ( ) ["response"] # تلقي استجابة من استجابة الخادم = request.get ("https: // (server)؟ act = a_check & key = (key) & ts = (ts) & wait = 90 & mode = 2 & version = 2 ".format (server = data [" server "]، key = data [" key "]، ts = data [" ts "])). json () # إرسال طلب إلى خادم الاستقصاء الطويل مع وقت انتظار 90 ثانية وخيارات الاستجابة 2 طباعة (استجابة)
إذا وقع حدث خلال 90 ثانية يقع في قائمة المعالجة بواسطة خادم الاستقصاء الطويل ، فسيتم عرض شيء مشابه على الشاشة: ("ts": 0000000000 ، "التحديثات": []). ماذا تعني الإجابة المستلمة وكيف يمكنك العمل معها بشكل أكبر؟

أولاً ، ربما لاحظت أن الرد يحتوي على معلمة "ts" التي استخدمناها عند إرسال الطلب. إنه هنا لسبب ما. يتم ترقيم جميع الأحداث المدرجة في قائمة الاستقصاء الطويل للخادم. عند إنشاء حساب جديد ، يتم ترقيم الحدث الأول من هذا القبيل بالرقم 1 ، والثاني هو 2 ، وهكذا. عند إرسال طلب لاستطلاع رأي طويل ، تحتاج إلى تمرير هذه المعلمة حتى يعرف الخادم الرقم الذي سيتم إرسال التحديثات منه. تأتي هذه المعلمة أيضًا في كل استجابة خادم بحيث تستخدمها في المرة التالية التي تتصل فيها بالخادم Long Poll.

ثانيًا ، يحتوي القاموس على مفتاح "التحديثات" باسم لا يحتاج إلى شرح. ليس من الصعب تخمين أن قيمة هذا المفتاح تخزن التحديثات التي حدثت بعد إرسال الطلب. تنسيق التحديث عبارة عن مصفوفة من المصفوفات. كل مصفوفة في المصفوفة هي تحديث حدث ويجب معالجته. إذا كانت المصفوفة الأولى تحتوي على أكثر من مصفوفة واحدة ، فهذا يعني أن العديد من الأحداث قد حدثت في وقت واحد. تحتوي المعلمة "ts" على رقم الأخير. إذا كانت المصفوفة التي يمكن الوصول إليها عن طريق مفتاح "التحديثات" فارغة ، فلن تحدث أي أحداث أثناء الانتظار. تسأل: "ما هذه الأرقام غير المفهومة في المصفوفات؟" الجواب بسيط للغاية - إنها معلومات حول الحدث الذي حدث ، والتي يمكن تحويلها إلى صيغة أكثر قابلية للفهم. سنتعامل مع معالجتها لاحقًا ، وفي الجزء التالي سنكتب برنامجًا سيتواصل باستمرار مع خادم Long Poll.


استعلامات دورية طويلة ورموز الأحداث

من أجل إرسال الطلبات باستمرار إلى Long Poll ، قررت استخدام حلقة حتى لا أتجاوز المكدس بالتكرار. يوجد أدناه تطبيق لبرنامج يصل إلى الاستطلاع الطويل ويطبع التحديثات على الشاشة

رمز طلبات الاستيراد = "" # هنا يجب أن تكتب بيانات access_token الخاصة بك = request.get ("https://api.vk.com/method/messages.getLongPollServer"، params = ("access_token": token)). Json ( ) ["response"] # تلقي استجابة من الخادم بينما True: response = calls.get ("https: // (server)؟ act = a_check & key = (key) & ts = (ts) & wait = 20 & mode = 2 & version = 2 ". format (server = data [" server "]، key = data [" key "]، ts = data [" ts "])). json () # إرسال طلب إلى خادم استطلاع طويل مع وقت انتظار يبلغ 20 وتحديث خيارات الاستجابة 2 = استجابة ["تحديثات"] إذا كانت التحديثات: # تحقق مما إذا كانت هناك تحديثات للعنصر في التحديثات: # التكرار خلال جميع التحديثات في استجابة طباعة (عنصر) البيانات [" ts "] = response [" ts "] # تحديث رقم التحديث الأخير
يرسل هذا البرنامج بشكل دوري الطلبات إلى Long Poll ، ويتحقق مما إذا كانت هناك تحديثات ، ويعرض التحديثات المستلمة على الشاشة. لكن ناتج هذا البرنامج كما هو الآن لا قيمة له. الآن يبدو إخراج البرنامج كما يلي:



الرقم الأول في كل مصفوفة يعني رمز الحدث. باستخدامه ، يمكنك فهم الحدث الذي حدث. فيما يلي قائمة برموز الأحداث مع وصف مختصر(من الوثائق الرسمية):
1 - الاستبدال أعلام الرسالة(FLAGS: = $ flags) ؛
2 - التثبيت أعلام الرسالة(FLAGS | = $ قناع) ؛
3 - إعادة تعيين أعلام الرسالة(FLAGS & = ~ $ قناع) ؛
4 - إضافة رسالة جديدة ؛
6 - اقرأ جميع الرسائل الواردة في $ peer_id التي جاءت قبل الرسالة بـ $ local_id.
7 - قراءة جميع الرسائل الصادرة بـ $ peer_id التي جاءت قبل الرسالة بـ $ local_id.
8 - $ user_id صديق متصل. لا يساوي $ extra 0 إذا تم تمرير علامة 64 إلى الوضع. يحتوي البايت المنخفض (باقي القسمة على 256) من الرقم الإضافي معرّف النظام الأساسيالطابع الزمني $ - وقت آخر إجراء للمستخدم $ user_id على الموقع؛
9 - أصبح $ user_id friend غير متصل بالإنترنت ($ flags تساوي 0 إذا غادر المستخدم الموقع (على سبيل المثال ، نقر الخروج) و 1 إذا كان غير متصل بسبب انتهاء المهلة (على سبيل المثال ، حالة بعيد)). الطابع الزمني $ - وقت آخر إجراء للمستخدم $ user_id على الموقع؛
10 - إعادة تعيين أعلام الحوار$ peer_id. يتوافق مع العملية (PEER_FLAGS & = ~ $ flags). للحوارات المجتمعية فقط ؛
11- الاستبدال أعلام الحوار$ peer_id. يتوافق مع العملية (PEER_FLAGS: = $ flags). للحوارات المجتمعية فقط ؛
12 - التثبيت أعلام الحوار$ peer_id. يتوافق مع العملية (PEER_FLAGS | = $ flags). للحوارات المجتمعية فقط ؛
13 - حذف جميع الرسائل في مربع الحوار $ peer_id بمعرفات تصل إلى $ local_id ؛
14 - التعافي مؤخرًا (أقل من 20 يومًا) الرسائل المحذوفةفي مربع الحوار $ peer_id مع معرفات تصل إلى $ local_id؛
51 - تم تغيير أحد معاملات (التركيب ، الموضوع) للمحادثة $ chat_id. $ self - 1 أو 0 (سواء كانت التغييرات ناتجة عن المستخدم نفسه) ؛
61 - المستخدم $ user_id يقوم بكتابة نص في مربع الحوار. يقع الحدث مرة كل 5 ثوانٍ تقريبًا مع الكتابة المستمرة. أعلام الدول = 1 ؛
62 - المستخدم $ user_id يكتب في المحادثة $ chat_id؛
70 - المستخدم $ user_id أجرى مكالمة مع المعرف $ call_id؛
80 - أصبح العداد غير المقروء في القائمة اليسرى عدد دولارات ؛
112 - تم تغيير إعدادات الإعلام. $ peer_id - معرف الدردشة / الأقران.

وبالتالي ، إذا كان الرقم الأول في المصفوفة هو 8 ، فهذا يعني أن أحد أصدقائك أصبح متصلاً بالإنترنت ، إذا كان الرقم 9 غير متصل ، وهكذا. تعتبر بقية الأرقام في المصفوفة مهمة أيضًا ، لكننا سنصل إليها لاحقًا ، لأن معناها يعتمد على رمز الحدث.


معالجة الأحداث القادمة

في هذا الجزء ، سننفذ معالجة الأحداث التي تأتي إلينا كرد فعل. دعني أذكرك أن هذه الأحداث مقدمة كمصفوفات تحتوي على معلومات تحتاج إلى المعالجة. أقترح البدء بالرمز 80 - تحديث العداد رسائل غير مقروءة، لأن هذا الحدث في رأيي هو الأقل صعوبة. فيما يلي مثال على معرف الأحداث 80:

المعلمة الأولى ، كما تعلم بالفعل ، هي رمز الحدث. يبقى عنصران: 0 و 0 في الحالة الأولى و 1 0 في الحالة الثانية. يجب أن تكون المعلمة الأخيرة للكود 80 صفرًا دائمًا ، لذلك يمكن تجاهلها ؛ فقط الثاني هو المهم بالنسبة لنا. تشير المعلمة الثانية إلى المقدار هذه اللحظةلدى المستخدم رسائل غير مقروءة. الحد الأدنى للقيمة هو 0 (لا توجد رسائل جديدة) ، والحد الأقصى غير محدود. هذا كافٍ للتعامل مع جميع الأحداث مع الكود 80. دعنا ننفذ هذا في الكود:

تم حذف # جزء من الكود في هذا المثال لتوفير مساحة ، ولن يعمل الرمز بدونه بينما True: response = calls.get ("https: // (server)؟ act = a_check & key = (key) & ts = (ts) & wait = 20 & mode = 2 & version = 2 ".format (server = data [" server "] ، key = data [" key "] ، ts = data [" ts "])). Json () # إرسال طلب إلى خادم الاستطلاع الطويل مع انتهاء المهلة 20 وتحديث خيارات الاستجابة 2 = استجابة ["التحديثات"] إذا كانت التحديثات: # تحقق مما إذا كانت هناك تحديثات للعنصر في التحديثات: # التكرار من خلال جميع التحديثات في الاستجابة action_code = العنصر # الكتابة إلى متغير رمز الحدث إذا كان action_code == 80: # فحص طباعة رمز الحدث ("أصبح عدد الرسائل غير المقروءة متساويًا" ، العنصر) # بيانات الإخراج ["ts"] = استجابة ["ts"] # تحديث رقم التحديث الأخير
إذا قمت بتشغيل هذا البرنامج ، فسيعرض رسائل على التغيير في عدد الرسائل غير المقروءة. تحتوي التحديثات التالية البسيطة نسبيًا على الرمزين 8 و 9 - أصبح الصديق متصلاً بالإنترنت وغير متصل ، على التوالي. دعنا نكمل برنامجنا حتى يتمكن من معالجتها أيضًا. لنبدأ بالرمز 9. لنكتب سطرًا يتحقق من رمز الحدث:

أكواد الإجراء إليف == 9:
بعد ذلك ، ضع في اعتبارك تنسيق التحديثات الواردة بالرمز 9:
مع الفهرس 0 ، كما تعلم بالفعل ، يتم تخزين رمز التحديث - 9. يأتي بعد ذلك المعرف السلبي للمستخدم الذي أصبح غير متصل بالإنترنت (للحصول على معرف صالح ، تحتاج إلى الضرب في -1 للتخلص من ناقص). يمكن أن يأخذ العنصر الذي يحتوي على فهرس 3 قيمتين فقط: 0 أو 1. 1 يعني أنه تم تعيين العلامة "غير متصل" بعد انتهاء مهلة عدم النشاط ، ويعني 0 أن المستخدم غادر الموقع بشكل صريح ، على سبيل المثال ، بالضغط على "خروج " زر. القيمة الأخيرة في الاستجابة هي وقت آخر إجراء للمستخدم على الموقع في وقت Unix. دعنا نكتب جميع المعلومات الواردة في المتغيرات:

معرف المستخدم = عنصر * -1 # معرف المستخدم غير المتصل = request.get ("https://api.vk.com/method/users.get"، params = ("user_ids": user_id، "الحقول": " sex ")). json () [" response "] # الاسم الأول ، والاسم الأخير والجنس للمستخدم مع id = user_id timeout = bool (element) # كانت حالة عدم الاتصال التي تم تعيينها بعد انتهاء المهلة last_visit = element # time of آخر إجراء للمستخدم بالموقع في وقت Unix
كما لاحظت ، بالإضافة إلى الاسم الأول والأخير للمستخدم ، نحصل أيضًا على جنسه. هذا ضروري حتى يستخدم البرنامج الجنس بشكل صحيح في الجمل ولا يكتب شيئًا مثل "خرج إيفان إيفانوف أمن فكونتاكتي ". يكون متغير المهلة خطأ إذا غادر المستخدم الموقع صراحةً ، ويكون صحيحًا إذا انتهت المهلة. الآن يمكنك عرض البيانات المستلمة:

# لا تنس كتابة "وقت الاستيراد" في البداية ، يتم استخدام هذه المكتبة هنا إذا كان المستخدم ["sex"] == 1: verb = ["أصبح"، "left"] else: verb = ["أصبح" ، "left"] إذا انتهت المهلة: print (user ["first_name"] ، مستخدم ["last_name"] ، فعل ، "غير متصل بعد انتهاء المهلة. وقت آخر نشاط على الموقع:" ، time.ctime (last_visit). split ()) else: print (user ["first_name"] ، user ["last_name"] ، فعل ، "من VKontakte. وقت آخر نشاط على الموقع:" ، time.ctime (last_visit) .split ())
الشيء الوحيد الذي أراه غير واضح في هذا الرمز هو إخراج التوقيت:

Time.ctime (last_visit) .split ()
دعنا نلقي نظرة على هذا الجزء من الكود. تأخذ وظيفة ctime لمكتبة الوقت رقمًا كوسيطة - الوقت في وقت Unix وتعيد سلسلة مثل "الخميس 1 يناير 03:00:00 1970"
... نظرًا لأننا نحتاج فقط إلى وقت الإجراء الأخير على الموقع ، فإننا نقسم هذه السلسلة باستخدام طريقة التقسيم على مسافات ونحصل على مصفوفة حيث يتم تخزين يوم الأسبوع في الفهرس 0 ، الشهر في الفهرس 1 ، الرقم 2 - رقم ، 3 - الوقت و 4 - سنوات. نسترجع العنصر في الفهرس 3 ، وهو الوقت.

لنكتب الآن تنفيذ معالجة التحديثات بالرمز 8. يبدو تنسيقها كما يلي :. العنصر الثاني في المصفوفة هو المعرف السلبي للمستخدم الذي أصبح متصلًا بالإنترنت ، والثالث هو النظام الأساسي الذي قام المستخدم بتسجيل الدخول منه ، والرابع هو وقت آخر إجراء للمستخدم على الموقع في وقت Unix. دعنا ننفذ البيانات المستلمة في الكود:

User_id = element * -1 # معرف المستخدم الذي دخل إلى الإنترنت : "sex")). json () ["response"] # اسم المستخدم واللقب والجنس مع id = user_id platform = element # رمز النظام الأساسي للمستخدم last_visit = element # وقت آخر زيارة لوقت Unix إذا كان المستخدم ["sex"] == 1: فعل = "أصبح" آخر: فعل = "أصبح"
هنا قمنا بكتابة البيانات من الإجابة إلى متغيرات ، وكذلك وضعنا الفعل في الجنس المطلوب. تحتوي معلمة النظام الأساسي الآن على رقم بين 1 و 7 ، ضمناً. يحدد كل رقم النظام الأساسي الذي اتخذ المستخدم إجراءً من خلاله. دعنا نترجم هذا الرقم إلى نص:

# تحديد المنصة برمزها إذا كانت المنصة == 1: platform = "official اصدار المحمولموقع VK الإلكتروني "elif platform == 2: platform =" تطبيق VK رسمي لـ iPhone "منصة elif == 3: platform =" تطبيق VK رسمي لجهاز iPad "منصة elif == 4: platform =" تطبيق VK رسمي لنظام Android "منصة elif == 5: النظام الأساسي = "تطبيق VK الرسمي لـ هاتف ويندوز"منصة elif == 6: النظام الأساسي =" تطبيق VK الرسمي لنظام التشغيل Windows "منصة elif == 7: النظام الأساسي =" إصدار الويب الرسمي من VK "
يمكنك الآن عرض المعلومات على الشاشة:

طباعة (المستخدم ["الاسم_الأول"] ، المستخدم ["اسم_الأخير"] ، فعل ، "عبر الإنترنت عبر" ، النظام الأساسي ، "في" ، time.ctime (last_visit) .split ())
بعد ذلك سنلقي نظرة على الرموز 61 و 62. أبلغوا أن شخصًا ما يكتب رسالة. الاختلاف هو أن التحديثات برمز 61 تُعلمك بالكتابة في الرسائل الخاصة ، و 62 - في المحادثات. تبدو التحديثات بالرمز 62 كما يلي :. العنصر الثاني من المصفوفة هو معرف المستخدم الذي يكتب الرسالة ، والثالث هو معرف المحادثة. التحديثات برمز 61 هي كما يلي: هنا ، العنصر الثاني فقط هو المهم - معرف المستخدم الذي يكتب الرسالة. لنكتب معالجًا لهذه الأحداث:

Elif action_code == 61: user = calls.get ("https://api.vk.com/method/users.get"، params = ("user_ids": element)). Json () ["response"] # الحصول على طباعة الاسم الأول والأخير للمستخدم (المستخدم ["first_name"] ، المستخدم ["last_name"] ، "كتابة رسالة") elif action_code == 62: user = calls.get ("https: //api.vk. com / method /users.get "، params = (" user_ids ": element)). json () [" response "] # احصل على الاسم الأول والأخير للمستخدم الذي يكتب الرسالة chat = calls.get (" https: //api.vk.com /method/messages.getChat "، params = (" chat_id ": element،" access_token ": token)). json () [" response "] [" title "] # احصل على اسم طباعة المحادثة (المستخدم ["First_name"] ، المستخدم ["last_name"] ، "كتابة رسالة في محادثة" () "". تنسيق (دردشة))
الخامس الموضوع التاليسنكتب معالج الرسائل الواردة وننظر في أعلام الرسائل.


التعامل مع الرسائل والعلامات

التحديثات الأكثر إثارة للاهتمام ، في رأيي ، هي إضافة الرسائل. هذه التحديثات هي رمز 4 وإرجاع معلومات حول الرسائل الواردة والصادرة. فيما يلي مثال على التحديث بالرمز 4 :. هنا $ ts هو رقم الحدث الوارد ، $ flag هي إشارات الرسالة ، $ id هو معرف المحاور أو 2000000000 + معرف المحادثة (في حالة الحوارات الجماعية) ، $ unixtime هو الوقت الذي تمت فيه إضافة الرسالة إلى Unix الوقت ، والعنصر الأخير عبارة عن قاموس يحتوي على معلومات حول المرفقات والمرسل والتغييرات في إعدادات المحادثة. أولاً ، دعنا نتعرف على مكان إضافة الرسالة: في المراسلات الشخصية أو المحادثة. إذا تم إرسال الرسالة في محادثة ، فكما كتبت بالفعل ، سيحتوي حقل معرف $ على الرقم الذي تم الحصول عليه بإضافة 2000000000 و chat_id (معرف المحادثة). إذا تمت إضافة الرسالة في المراسلات الشخصية ، فسيحتوي الحقل $ id على معرف المحاور ، والذي يكون دائمًا أقل من 2000000000 + chat_id لأي محادثة. من هذا يمكننا أن نستنتج أنه إذا كان $ id هو 2،000،000،000> 0 ، فسيتم إرسال الرسالة في محادثة ، إذا كانت أقل ، في المراسلات الشخصية. إذا تم إرسال الرسالة في محادثة ، فسيتم الإشارة إلى معرف المستخدم الذي كتب الرسالة في القاموس تحت مفتاح "من". لنكتب معالج الرسالة:

Elif action_code == 4: if element - 2000000000>
ومع ذلك ، فإن هذا البرنامج له عيوب قليلة. هنا بعض منهم:

  • عدم القدرة على التمييز بين الرسائل الصادرة والرسائل الواردة ؛
  • تجاهل مرفقات الوسائط ؛
  • تجاهل الرسائل التي تشير إلى تغيير في إعدادات المحادثة ؛
  • عدم القدرة على معالجة الرموز الخاصة في الرسائل
يمكن حل مشكلتين من المشاكل الأربع باستخدام إشارات الرسائل المخزنة في مصفوفة التحديث في الفهرس 2. عنصر المصفوفة هذا هو رقم ناتج عن إضافة بعض المعلمات أدناه (من الوثائق الرسمية):
+1: الرسالة غير مقروءة
+2: رسالة صادرة
+4: تم إنشاء رد على الرسالة
+8: رسالة تم وضع علامة عليها
+16: تم إرسال الرسالة عبر الدردشة
+32: تم إرسال الرسالة من قبل صديق. لا ينطبق على الرسائل من المحادثات الجماعية
+64: تم وضع علامة على الرسالة على أنها "بريد عشوائي"
+128: تم حذف الرسالة (في المهملات)
+256: رسالة فحصها المستخدم بحثًا عن بريد عشوائي
+512: رسالة تحتوي على محتوى وسائط
+65536: رسالة ترحيب من المجتمع. لا يلزم رفع الحوار الذي يحتوي على مثل هذه الرسالة في القائمة (اعرضه فقط عند فتح مربع الحوار مباشرة). علم غير متوفر للإصدارات<2.

نحتاج الآن إلى تعليم البرنامج كيفية التمييز بين الرسائل الصادرة من الرسائل الواردة. للتحقق مما إذا كانت علامة الرسالة تحتوي على الرقم الذي نحتاجه ، سنستخدم المعامل AND على مستوى البت ، وأنشئ مصفوفة تخزن مصطلحات العلم:

Summands = # مجموعة حيث سنقوم بتخزين المصطلحات flag = element # message flag لرقم في: # loop من خلال المصطلحات الممكنة إذا كانت العلامة & number: # تحقق مما إذا كان الرقم عبارة عن مصطلح باستخدام bitwise AND Summands.append (number) # if is ، قم بإضافته إلى المصفوفة
يبدو لي أنه من غير المجدي عرض معلومات حول الرسائل الصادرة ، لذلك سنضيف السطر

إذا لم يكن 2 في الملخصات:
الآن يبدو جزء البرنامج الذي يعمل مع الرسائل كما يلي:

Elif action_code == 4: Summands = # مصفوفة حيث سنقوم بتخزين المصطلحات flag = element # message flag للرقم في: # loop على المصطلحات الممكنة إذا كان flag & number: # تحقق مما إذا كان الرقم عبارة عن مصطلح باستخدام أحاديات AND. append (number) # إذا كان الأمر كذلك ، أضفه إلى المصفوفة إذا لم يكن 2 في الملخصات: إذا كان element - 2000000000> 0: # تحقق مما إذا كانت الرسالة قد تم إرسالها في المحادثة user_id = element ["from"] # معرف المرسل chat_id = عنصر - 2000000000 # chat id chat = calls.get ("https://api.vk.com/method/messages.getChat"، params = ("chat_id": chat_id، "access_token": token)). json () [ "response"] ["title"] # احصل على عنوان المحادثة user = calls.get ("https://api.vk.com/method/users.get"، params = ("user_ids": user_id، " name_case ":" gen ")). json () [" response "] # احصل على الاسم الأول والأخير للمستخدم الذي أرسل الرسالة time_ = element # مرة تم إرسال الرسالة text = element # نص الرسالة إذا كان نصًا: # تأكد من احتواء الرسالة على نص طباعة (time.ctime (time_). split () + ":" ، "Message from" ، المستخدم ["first_name"] ، المستخدم ["last_name"] ، "في المحادثة" () "". تنسيق (دردشة ) + ":"، text) else: user_id = element # id of the interlocutor user = calls.get ("https://api.vk.com/method/users.get"، params = ("user_ids": user_id ، "name_case": "gen")). json () ["response"] # احصل على الاسم الأول والأخير للمستخدم الذي أرسل الرسالة time_ = element # مرة تم إرسال الرسالة text = element # نص الرسالة إذا text: # تأكد من أن الرسالة تحتوي على طباعة نصية (time.ctime (time _). split () + ":"، "Message from"، user ["first_name"]، user ["last_name"] + ":"، نص)
الآن دعنا نتعلم كيفية العمل مع مرفقات الوسائط. في ما يلي مثال على تحديث يفيد بوصول رسالة مرفق بها صورة وأغنية وفيديو ومستند وموقع جغرافي: [. للوصول إلى هذه المرفقات ، ستحتاج إلى استخدام واجهة برمجة التطبيقات للحصول على رابط للملف. تم العثور على طرق لتنفيذ هذا الإجراء (photos.getById و docs.getById) للصور والمستندات فقط (تأتي الرسائل الصوتية كمستندات ، لذا يمكنك الحصول على رابط للاستماع إليها). بالنسبة للموسيقى ، لم تتوفر طريقة واحدة مؤخرًا بسبب حقوق النشر ، وبالنسبة للفيديو ، الطريقة المطلوبة ببساطة غير متوفرة. لمزيد من العمل مع المرفقات ، سنكتب رمزًا سينشئ صفيفتين (للصور والمستندات) مع روابط لعرض المرفقات.

إذا كان الرقم 512 في التلخيص: # التحقق مما إذا كان هناك فهرس مرفقات وسائط = 1 صورة = # مصفوفة لتخزين مستندات معرف الصورة = # مصفوفة لتخزين معرف المستند مرفق وسائط مع هذا الفهرس media_type = عنصر ["attach () _ type" .format (index)] # إذا كان موجودًا ، احفظ نوعه إذا كان media_type == "photo": # ما إذا كان المرفق عبارة عن صورة صور. العنصر ["attach ()". format (index)]) # إضافة معرف الصورة إلى المصفوفة elif media_type == "doc": # هو مرفق مستند docs.append (عنصر ["attach ()"). format (index)]) # إضافة معرف المستند إلى فهرس المصفوفة + = 1 # زيادة نوع الفهرس media_type = "attach () _ type" .format (index) change = lambda ids، type_: calls.get ("https: / /api.vk.com/method/ () .getById ".format (type_)، params = (type_: ids،" access_token ": token)). json () # function التي ترجع روابط إلى الكائنات إذا كانت الصور: # check إذا كانت المرفقات بها صور = تغيير ("،" .join (photos)، "photos") # إذا كان هناك ، فاكتب متغير الصور إلى القاموس إذا كان "response" في photos.keys (): photos = للمرفق في الصور ["response"]] # الكتابة فوق لطباعة الروابط ("تحتوي الرسالة على الصور التالية:"، "،". انضم (صور)) وإلا: مرر # على الأرجح حدث خطأ في الوصول في حالة المستندات: # تحقق مما إذا كانت هناك مستندات في المرفقات docs = change ( "،" .join (docs)، "docs") # إذا كان هناك ، فاكتب فوق متغير المستندات بالقاموس إذا كانت "response" في docs.keys (): docs = للمرفق في المستندات ["response"]] # الكتابة فوق الروابط طباعة ("الرسالة تحتوي على المستندات التالية:" ، "،". الانضمام (مستندات)) وإلا: تمرير # على الأرجح حدث خطأ في الوصول
دعونا نزيل الخطوط

إذا كان النص: بحيث يكون من الواضح عند عرض البيانات مرفقات الوسائط التي تنتمي إلى الرسائل.

سنقوم الآن بتعليم برنامجنا كيفية الرد على التغييرات في المحادثة: إنشاء محادثة جديدة ، وتحديث صورة ، وتغيير الأسماء ، وإضافة الأشخاص واستبعادهم. يتم تخزين المعلومات حول مثل هذه الأحداث في قاموس في الفهرس 6 في تحديثات برمز 4. فيما يلي أمثلة على الأحداث:

  • تغيير اسم المحادثة:
  • تحديث صورة المحادثة:
  • إضافة مستخدم إلى محادثة:
  • إزالة مستخدم من محادثة (ترك مستخدم خارج المحادثة):
  • إنشاء محادثة جديدة:
إليك برنامج يتعامل مع التغييرات من هذا النوع:

Elif action_code == 4: إذا لم يكن "source_act" في element.keys (): #<код, обрабатывающий сообщения> else: source_act = element if source_act ["source_act"] == "chat_title_update": # ما إذا كان التحديث ناتجًا عن تغيير في اسم المحادثة changer_id = source_act ["from"] # معرف الشخص الذي غيّر الاسم source_text = source_act ["source_text"] # اسم محادثة جديد source_old_text = source_act ["source_old_text"] # تغيير اسم المحادثة القديم = request.get ("https://api.vk.com/method/users.get"، params = ("user_ids": changer_id، "field": "sex")). json () ["response"] # احصل على الاسم الأول والأخير للمستخدم الذي قام بتغيير الاسم if changer ["sex"]: verb = " تم تغيير "آخر: فعل =" تم تغييره "طباعة (مغير [" الاسم_الأول "] ، مغير [" اسم_الأخير "] ، فعل ،" اسم المحادثة من تنسيق "()" إلى "()" ". (source_old_text ، source_text)) elif source_act ["source_act"] == "chat_photo_update": chat_id = element - 2000000000 # chat id chat = calls.get ("https://api.vk.com/method/messages.getChat"، params = ("chat_id": chat_id، "access_token": token)). Json () ["response"] ["title"] # get title المحادثات user_id = source_act ["from"] # معرف المستخدم الذي قام بتحديث الصورة photo_id = source_act ["attach1"] # معرف الصورة الصورة = request.get ("https://api.vk.com/method/ photos.getById "، params = (" photos ": photo_id،" access_token ": token)). json () # link to photo user = calls.get (" https://api.vk.com/method/users. get "، params = (" user_ids ": user_id،" field ":" sex ")). json () [" response "] # اسم ولقب المستخدم الذي قام بتحديث الصورة إذا لم يكن" الخطأ "في الصورة. keys (): # ما إذا كانت هناك أية أخطاء عند تلقي ارتباط إذا كان المستخدم ["sex"]: verb = "updated" else: verb = "updated" print (user ["first_name"] ، المستخدم ["last_name"] ، فعل ، "صورة المحادثة" () "على" تنسيق. (دردشة) ، صورة ["استجابة"] ["src_xbig"]) وإلا: مرر # ربما ليس لديك إذن بتنفيذ طلب elif source_act ["source_act "] ==" chat_invite_user ": chat_id = element - 2000000000 # محادثات معرف chat = calls.get (" https://api.vk.com/method/messages.getChat "، params = (" chat_id ": chat_id،" access_token ": token)). js on () ["response"] ["title"] # احصل على اسم المحادثة calling_id = source_act ["source_mid"] # معرف المدعو inviter_id = source_act ["from"] # معرف الداعي إذا تمت دعوته == inviter_id: # هل عاد المستخدم إلى المحادثة أو تمت إضافته بواسطة شخص من المشاركين user = request.get ("https://api.vk.com/method/users.get"، params = ("user_ids": inviter_id، "الحقول": "الجنس")) .json () ["response"] # تم إرجاع الاسم الأول والأخير إذا تم إرجاع المستخدم ["sex"]: verb = "return" else: verb = "return" print (user ["first_name "] ، المستخدم [" last_name "] ، فعل ،" في المحادثة "()" ". تنسيق (دردشة)) else: inviter_user = request.get (" https://api.vk.com/method/users.get "، params = (" user_ids ": inviter_id،" field ":" sex ")). json () [" response "] # اسم ولقب الشخص الذي أضاف calling_user = applications.get (" https: // api .vk.com / method / users.get "، params = (" user_ids ": calling_id،" name_case ":" acc ")). json () [" response "] # أضاف الاسم الأول واسم العائلة إذا inviter_user [" sex "]: verb =" added "else: verb =" added "print (inviter_user ["first_name"] ، inviter_user ["last_name"] ، فعل ، "للدردشة" () "". تنسيق (دردشة) ، مستخدم_مدعو ["الاسم_الأول"] ، مستخدم_مدعو ["اسم_الأخير"]) مصدر_إليف ["source_act"] == "chat_kick_user": chat_id = element - 2000000000 # chat id chat = calls.get ("https://api.vk.com/method/messages.getChat"، params = ("chat_id": chat_id، "access_token" : token)). json () ["response"] ["title"] # الحصول على اسم المحادثة remove_id = source_act ["source_mid"] # id of the المستبعد remover_id = source_act ["from"] # id of the مستبعد إذا تمت remove_id == remover_id: # سواء قام المستخدم بتسجيل الخروج أو تم استبعاده user = calls.get ("https://api.vk.com/method/users.get"، params = ("user_ids": remover_id، " الحقول ":" sex ")) .json () [" response "] # الاسم الأول والأخير لتسجيل الخروج إذا كان المستخدم [" sex "]: verb =" quit "else: verb =" quit "print (المستخدم [ "first_name"] ، مستخدم ["last_name"] ، فعل ، "من محادثة" () "". تنسيق (دردشة)) else: remover_user = request.get ("https://api.vk.com/method/users .get "، params = (" user_ids ": remover_id،" الحقول ":" sex ")). json () [" response "] # الاسم الأول والأخير للمستبعد المستبعد Remove_user = request.get (" https://api.vk.com/method/users.get "، params = (" user_ids ": remove_id،" name_case ":" acc ")). json () [" response "] # الاسم الأول والأخير للمستبعد إذا remover_user [" sex "]: verb =" استبعاد "else: verb =" استبعاد " print (remover_user ["first_name"] ، remover_user ["last_name"] ، فعل ، "من المحادثة" () "". تنسيق (دردشة) ، remove_user ["first_name"] ، remove_user ["last_name"]) elif source_act ["source_act"] == "chat_create": chat = source_act ["source_text"] # chat name creator_id = source_act ["from"] # creator id creator = request.get ("https://api.vk.com/ الطريقة / users.get "، params = (" user_ids ": creator_id، "field": "sex")). json () ["response"] # اسم المنشئ الأول واسم العائلة والجنس إذا كان المنشئ ["sex"] : verb = "created" else: verb = "created" print (Creator ["first_name"] ، المنشئ ["last_name"] ، الفعل ، "chat" () "". format (chat))


نجلب الجمال. الجزء الأخير

في هذا الجزء ، سننظر في تفصيلين فقط: خطأ عند طلب خادم استطلاع طويل وعرض العروض الخاصة. الشخصيات في الرسائل.

حول الخطأ: إذا قمت بتشغيل البرنامج كما هو الآن ، بعد فترة ، سيظهر KeyError في السطر 8: response = calls.get ("https: // (server)؟ Act = a_check & key = (key) & ts = (ts) & wait = 20 & mode = 2 & version = 2 ".format (server = data [" server "] ، key = data [" key "] ، ts = data [" ts "])) . json () ["response"] # إرسال طلب إلى خادم Long Poll مع وقت انتظار قدره 20 وخيارات استجابة 2. الحقيقة هي أن الخادم أعاد الخطأ "خطأ 2" لطلبنا ، مما يعني أن المعلمة المستخدمة & key قديمة ونحتاج إلى الحصول على معلمة جديدة. للقيام بذلك ، سنقوم بتغيير الكود الحالي قليلاً إلى:

Response = calls.get ("https: // (server)؟ Act = a_check & key = (key) & ts = (ts) & wait = 20 & mode = 2 & version = 2" .format (server = data [ "server"]، key = data ["key"]، ts = data ["ts"])). json () # إرسال طلب إلى خادم الاستقصاء الطويل مع وقت انتظار 20 وخيارات الاستجابة 2 حاول: التحديثات = response ["updates"] باستثناء KeyError: # إذا تم طرح استثناء KeyError في هذه المرحلة ، وبالتالي فإن المعلمة الرئيسية قديمة ، وتحتاج إلى الحصول على بيانات جديدة = request.get ("https: //api.vk. com / method / messages.getLongPollServer "، params = (" access_token ": token)) .json () [" response "] # تلقي استجابة من الخادم استمر # انتقل إلى التكرار التالي للحلقة لتقديم طلب ثان
تم حل المشكلة الآن! يبقى آخر شيء: خاص. الرموز في الرسائل. الحقيقة هي أن VK ترجع بعض الرموز ليست بالشكل الذي اعتدنا عليه. لذلك ، على سبيل المثال ، إذا كان هناك علامة عطف في الرسالة ، فسيتم استبدالها بـ & _amp (هناك حاجة إلى الشرطة السفلية حتى لا يستبدل هبر هذا النقش بآخر). هناك العديد من الرموز المتشابهة ويجب عرضها جميعًا بشكل صحيح. للقيام بذلك ، احفظ الرموز المتشابهة وأكوادها في قاموس ، ثم استبدل الرموز الموجودة في الرسالة برموز باستخدام الوظيفة الفرعية لمكتبة re (لا تنسَ استيرادها!).

استيراد re #<...>الرموز = ("
":" \ n "،" & _amp؛ ":" & "،" & _quot؛ ":" ""، "& _lt؛": "<", "&_gt;": ">"،" & _tilde؛ ":" ~ "،" & _circ؛ ":" "،" & _ndash؛ ":" - "،" & _mdash؛ ":" - "،" & _euro؛ ":" € "،" & _permil؛ ":" ‰ ") # قم بإزالة الشرطة السفلية من كل مفتاح من أجل الكود ، والقيمة في الرموز (): text = re.sub (كود ، قيمة ، نص)

بالطبع ، هناك الكثير من هذه الرموز أكثر مما أضفته إلى القاموس ، لكن من الصعب جدًا إعادة كتابتها جميعًا ، خاصة وأن بعضها غير قابل للاستنتاج. هذا يكمل إنشاء برنامجنا ، نسخته النهائية تبدو كالتالي:

رمز استيراد طلبات استيراد وقت الاستيراد = "" # هنا يجب عليك كتابة بيانات access_token الخاصة بك = request.get ("https://api.vk.com/method/messages.getLongPollServer"، params = ("access_token": token) ) .json () ["response"] # تلقي استجابة من الخادم بينما True: response = calls.get ("https: // (server)؟ act = a_check & key = (key) & ts = (ts) & انتظر = 20 & mode = 2 & version = 2 ".format (server = data [" server "]، key = data [" key "]، ts = data [" ts "])). Json () # send طلب إلى خادم الاستقصاء الطويل مع مهلة 20 وخيارات الاستجابة 2 ، جرب: التحديثات = استجابة ["تحديثات"] باستثناء KeyError: # إذا تم طرح استثناء KeyError في هذا المكان ، فإن المعلمة الرئيسية قديمة ، وتحتاج للحصول على بيانات جديدة = request.get ("https://api.vk.com /method/messages.getLongPollServer"، params = ("access_token": token)). json () ["response"] # تلقي استجابة من الخادم ، استمر # انتقل إلى التكرار التالي للحلقة لتقديم طلب ثانٍ إذا كانت التحديثات: # تحقق ، هل كانت هناك أي تحديثات للعنصر في التحديثات: # تمرير جميع التحديثات في الاستجابة action_code = element if action_code == 80: # فحص رمز الحدث طباعة ("أصبح عدد الرسائل غير المقروءة متساويًا" ، عنصر) # output elif action_code == 9: user_id = element * -1 # id للمستخدم الذي أصبح مستخدمًا غير متصل بالإنترنت = request.get ("https://api.vk.com/method/users.get"، params = ("user_ids": user_id، "field": "sex")). json () ["response"] # اسم المستخدم واللقب مع id = user_id timeout = bool (element) # ما إذا تم تعيين حالة عدم الاتصال بعد انتهاء المهلة last_visit = element # تاريخ آخر إجراء للمستخدم على الموقع إذا كان المستخدم [" sex "] == 1: الفعل = [" أصبح "،" تم الخروج "] وإلا: الفعل = [" أصبح "،" تم الخروج "] إذا انتهت المهلة: طباعة (المستخدم [" الاسم_الأول "] ، المستخدم [" اسم_الأخير "] ، فعل ، "غير متصل بعد انتهاء المهلة. وقت الإجراء الأخير على الموقع: "، time.ctime (last_visit) .split ()) else: print (user [" first_name "] ، user [" last_name "] ، فعل ،" من VK. وقت الإجراء الأخير على الموقع: '، time.ctime (last_visit) .split ()) elif action_code == 8: user_id = element * -1 # معرف المستخدم الذي أصبح مستخدمًا عبر الإنترنت = request.get (' https: / /api.vk.com/method/users .get '، params = (' user_ids ': user_id،' field ':' sex ')). json () [' response '] # اسم المستخدم واللقب مع id = user_id platform = element # user platform code last_visit = element # وقت الزيارة الأخيرة لوقت Unix إذا كان المستخدم ['sex'] == 1: verb = 'أصبح' else: verb = 'أصبح' # تعريف النظام الأساسي من خلال الكود الخاص به إذا كان النظام الأساسي = = 1: النظام الأساسي = "إصدار الجوال الرسمي لموقع الويب VK" منصة elif == 2: النظام الأساسي = "تطبيق VK الرسمي لـ iPhone" منصة elif == 3: platform = "تطبيق VK الرسمي لجهاز iPad" منصة elif == 4: المنصة = "تطبيق VK الرسمي لنظام Android" منصة elif == 5: المنصة = "مسؤول ial VK app for Windows Phone 'elif platform == 6: platform =' تطبيق VK الرسمي لنظام Windows 'elif platform == 7: platform = طباعة "إصدار ويب VK رسمي" (مستخدم [' first_name '] ، مستخدم [' last_name '] ، فعل ، "متصل عبر" ، نظام أساسي ، "في" ، time.ctime (last_visit) .split ()) elif action_code == 61: user = calls.get (' https://api.vk.com/ الطريقة / users.get '، params = (' user_ids ': element)). json () [' response '] # احصل على طباعة الاسم الأول والأخير للمستخدم (المستخدم [' first_name '] ، المستخدم [' last_name '] ، 'type message') elif action_code == 62: user = calls.get ('https://api.vk.com/method/users.get'، params = ('user_ids': element)). json () [ 'response'] # احصل على الاسم الأول والأخير للمستخدم الذي يكتب الرسالة chat = calls.get ('https://api.vk.com/method/messages.getChat'، params = ('chat_id': element، 'access_token': token)) .json () ['response'] ['title'] # احصل على اسم المحادثة طباعة (المستخدم ['first_name'] ، المستخدم ['last_name'] ، 'كتابة الرسالة في محادثة "()" "تنسيق (دردشة)) elif action_code == 4: إذا لم يكن 'source_act' في element.keys (): Summands = # مجموعة حيث سنقوم بتخزين المصطلحات flag = element # message flag للرقم في: # loop من خلال المصطلحات الممكنة إذا كانت العلامة & number: # check إذا كان الرقم عبارة عن مصطلح يستخدم أحاديًا AND Summands.append (رقم) # إذا كان كذلك ، أضفه إلى المصفوفة إذا لم يكن 2 في الملخصات: إذا كان العنصر - 2000000000> 0: # تحقق مما إذا كانت الرسالة قد تم إرسالها في المحادثة user_id = element ['from'] # معرف المرسل chat_id = element - 2000000000 # chat id chat = calls.get ('https://api.vk.com/method/messages.getChat'، params = ('chat_id': chat_id، 'access_token': token)). json () ['response'] ['title'] # احصل على عنوان المحادثة user = calls.get ('https://api.vk.com/method/users.get '، params = (' user_ids ': user_id،' name_case ':' gen ')). json () [' response '] # احصل على الاسم الأول والأخير للمستخدم الذي أرسل الرسالة time_ = element # time تم إرسال الرسالة text = element # message text الرموز = ('
<', '&_gt;': '>'،' & _tilde؛ ':' ~ '،' & _circ؛ ':' '،' & _ndash؛ ':' - '،' & _mdash؛ ':' - '،' & _euro؛ ':' € '،' & _permil؛ ':' ') # قم بإزالة الشرطة السفلية من كل مفتاح للرمز ، والقيمة في الرمز. ). انقسام () + ':' ، 'رسالة من' ، مستخدم ['first_name'] ، مستخدم ['last_name'] ، 'في المحادثة "()"'. تنسيق (دردشة) + ':' ، نص) وإلا : user_id = element # id لمستخدم المحادثة = request.get ('https://api.vk.com/method/users.get'، params = ('user_ids': user_id، 'name_case': 'gen') ). json () ['response'] # احصل على الاسم الأول والأخير للمستخدم الذي أرسل الرسالة time_ = element # مرة تم إرسال الرسالة text = element # text من رموز الرسالة = ('
':' n '،' & _amp؛ ':' & '،' & _quot؛ ':' ""، '& _lt؛': '<', '&_gt;': '> '،' & _tilde؛ ':' ~ '،' & _circ؛ ':' '،' & _ndash؛ ':' - '،' & _mdash؛ ':' - '،' & _euro؛ ':' € '،' & _permil؛ ':' ') # قم بإزالة الشرطة السفلية من كل مفتاح للرمز ، والقيمة في الرمز. ). Split () + ':'، 'Message from'، user ['first_name']، user ['last_name'] + ':'، text) إذا كان 512 في الملخص: # تحقق مما إذا كان هناك فهرس مرفقات وسائط = 1 photos = # مجموعة تخزين صور معرف docs = # مصفوفة لتخزين معرف المستند .format (index)] # إذا كان موجودًا ، احفظ نوعه إذا كان media_type == 'photo': # هو المرفق a photo.append (element ['attach ()'. format (index)]) # أضف معرف الصورة إلى المصفوفة elif media_type == 'doc': # هو مرفق مستند docs.append (عنصر ['attach ()'. format (index)]) # أضف معرف المستند إلى فهرس المصفوفة + = 1 # قم بزيادة مؤشر media_type = 'attach () _ type'.format (index) change = lambda ids، type_: calls.get (' https://api.vk.com/method/ () .getById'.format (type_)، params = (type_: ids، 'access_token': token)). json () # وظيفة تعيد روابط إلى الكائنات إذا كانت الصور: # تحقق مما إذا كانت هناك صور في المرفقات الصور = تغيير ('،'. الانضمام ( photos)، 'photos') # إذا كان هناك ، فاكتب متغير الصور للقاموس إذا كان "response" في photos.keys (): photos = for attachment in photos ['response']] # اكتب فوق الروابط طباعة (' تحتوي الرسالة على الصور التالية: '،'، '. Join (photos)) else: تمرير # على الأرجح حدث خطأ في الوصول إذا كان المستندات: # تحقق مما إذا كانت هناك مستندات في المرفقات docs = change ('، '.join (docs )، 'docs') # إذا كان الأمر كذلك ، اكتب فوق متغير المستندات بالقاموس إذا كانت "response" في docs.keys (): docs = للمرفق في المستندات ['response']] # اكتب فوق الروابط طباعة ("تحتوي الرسالة على المستندات التالية: '،'، '. Join (docs)) else: تجاوز # على الأرجح أوه ، كان هناك خطأ وصول آخر: source_act = element if source_act ['source_act'] == 'chat_title_update': # ما إذا كان التحديث ناتجًا عن تغيير في اسم المحادثة changer_id = source_act ['from'] # id الشخص الذي قام بتغيير الاسم source_text = source_act ['source_text'] # اسم محادثة جديد source_old_text = source_act ['source_old_text'] # تغيير اسم محادثة قديم = request.get ('https://api.vk.com/method/ users.get '، params = (' user_ids ': changer_id،' field ':' sex ')). json () [' response '] # احصل على الاسم الأول والأخير للمستخدم الذي قام بتغيير الاسم if changer [' sex ']: verb =' change 'else: verb =' تغيرت 'print (المغير [' first_name '] ، المغير [' last_name '] ، الفعل ،' اسم الدردشة من "()" إلى "()" '. تنسيق (source_old_text، source_text)) elif source_act ['source_act'] == 'chat_photo_update': chat_id = element - 2000000000 # chat id chat = calls.get ('https://api.vk.com/method/messages.getChat' ، params = ('chat_id': chat_id، 'access_token': token)) .json () ['response'] ['t itle '] # الحصول على اسم المحادثة user_id = source_act [' from '] # معرف المستخدم الذي قام بتحديث الصورة photo_id = source_act [' attach1 '] # معرف الصورة الصورة =طلبات .get (' https: / /api.vk.com/method /photos.getById '، params = (' photos ': photo_id،' access_token ': token)). json () # link to photo user = applications.get (' https: // api .vk.com / method / users .get '، params = (' user_ids ': user_id،' field ':' sex ')). json () [' response '] # الاسم الأول والأخير للمستخدم الذي قام بتحديث صورة إذا لم يكن 'error' في photo.keys (): # كان هناك أي أخطاء عند الحصول على الرابط إذا كان المستخدم ['sex']: verb = 'updated' else: verb = 'updated' print (user ['first_name'] ، المستخدم ['last_name']، الفعل، 'صورة المحادثة "()" to'.format (chat)، photo [' response '] [' src_xbig ']) وإلا: مرر # على الأرجح ليس لديك إذن لتنفيذ الطلب elif source_act ['source_act'] == 'chat_invite_user': chat_id = element - 2000000000 # chat id chat = calls.get ('https://api.vk.com/method/messages.getChat'، params = ('chat_id': chat_id ، 'access_token': token)). json () ['response'] ['title'] # احصل على اسم المحادثة calling_id = source_act ['source_mid'] # معرف المدعو inviter_id = source_act ['from'] # معرف الداعي إذا تمت دعوته_id == inviter_id: # ما إذا كان المستخدم قد عاد إلى المحادثة أو تمت إضافته من قبل مستخدم ما = request.get ('https://api.vk.com/method/users.get'، params = ('user_ids': inviter_id، 'الحقول': 'sex')). json () ['response'] # تم إرجاع الاسم الأول والأخير إذا كان المستخدم ['sex']: verb = 'return' else: verb = 'عاد 'print (user [' first_name ']، user [' last_name ']، فعل،' to chat "()" '. format (chat)) else: inviter_user = calls.get (' https: //api.vk. com / method / users.get '، params = (' user_ids ': inviter_id،' field ':' sex ')). json () [' response '] # اسم ولقب الشخص الذي أضاف المستخدمين المدعوين = request.get ('https://api.vk.com /method/users.get'، params = ('user_ids': calling_id، 'name_case': 'acc')). json () ['response'] تمت إضافة # اسم إذا inviter_user ['sex']: فعل = 'add
في هذا البرنامج التعليمي ، لم أفكر في جميع ميزات "الاستطلاع الطويل" ، مثل استبدال علامات الرسائل أو علامات "قراءة" و "غير مقروءة" بقيت غير متأثرة ، ولكن يمكنك دائمًا إنهاء البرنامج.
هذا كل شيء بالنسبة لي ، أتمنى أن تكون قد تعلمت شيئًا جديدًا لنفسك. اراك قريبا!

هذه ثغرة أمنية شائعة في فئة تضمين PHP. لكن ، قال لي الشخص الذي قمت بالتدقيق من أجله ، كما يقولون ، لا يمكن استغلال هذه الثغرة الأمنية ، لذلك لا يتم احتسابها. كان علي أن أتجادل معه

ما هو PHP-include

دعونا نجري برنامجًا تعليميًا صغيرًا حول هذه الثغرة الأمنية. PHP-include هي ثغرة أمنية تسمح لك "بتضمين" ملف عشوائي ، على سبيل المثال ، الكود التالي:

وحدة $ = $ _ REQUEST ["وحدة"] ؛ تشمل ("الوحدات النمطية /".$ module) ؛

ونظرًا لعدم وجود علامات php عادةً في ملف "etc / pаsswd / /" () ، ثم يتم عرضه في المتصفح ، وكذلك كود html الذي يتم عرضه خارج علامات php في المعتاد برنامج php... بالطبع ، قراءة الملفات هي مجرد تنفيذ محتمل لهذا الهجوم. الشيء الرئيسي هو كل نفس الشمول. الملفات المطلوبةمع كود php المطلوب.

دعنا نعود إلى المثال. دعونا نعقدها:

وحدة $ = $ _ REQUEST ["وحدة"] ؛ تشمل ("modules /". $ module. "/ module.class.php") ؛

وحدة $ = $ _REQUEST ["وحدة"] ؛

تشمل ("modules /". $ module. "/module.class.php") ؛

كما ترى ، تمت إضافة سطر إلى المتغير في النهاية ، مما يمنعنا من إضافة أي ملف. لذلك ، فإن العديد من وظائف php ليست آمنة ثنائية ، أي أن مثل هذه الوظائف تعتبر البايتات الفارغة كنهاية السلسلة. نشير إلى البرنامج النصي مثل هذا:

script.php؟ module = .. / .. / .. / .. / .. / .. / .. / .. / .. / .. / .. / etc / pаsswd٪ 00

وإذا تم تعطيل التوجيه magic_quotes ، فسنرى محتويات / etc / pаsswd مرة أخرى

هل هناك نقطة ضعف؟

دعنا نعود إلى الكود الخاص بنا:

وحدة $ = خطوط مائلة ($ _ REQUEST ["module"])؛ تشمل ("modules /". $ module. "/ module.class.php") ؛

$ module = addlashes ($ _REQUEST ["module"])؛

تشمل ("modules /". $ module. "/module.class.php") ؛

كما ترى ، فإن المتغير الخاص بنا يمر بالقوة من خلال "addlashes" وإذا حاولنا استخدام بايت NULL ، فسيتم تحويله إلى "\ 0" ولن يعمل التضمين.

لكن التقدم لا يزال قائما! اتضح أن بعض الأشخاص من USH قد وجدوا ميزة مثيرة للاهتمام لمتجهات هجوم نظام ملفات PHP في PHP. لتلخيص جوهر المقال بإيجاز ، تقوم php بمعالجة المسارات باستخدام عدة ميزات:

  • مسار مقطوع- اقتطاع php سلسلة المسار إلى الطول المحدد MAXPATHLEN (في Windows حتى 270 حرفًا ، على NIX - عادةً 4096 ، على BSD - عادةً 1024)
  • تطبيع المسار- يعالج php المسار بطريقة خاصة ، ويزيل الأحرف الزائدة "/" و "/." ومجموعاتهم المختلفة
  • تحديد العنوان المتعارف عليه- تتم إزالة الانتقالات غير الضرورية ، على سبيل المثال ، يتم تقليل "dir1 / dir2 /../ dir3" إلى "dir1 / dir3 /" بينما لا يتم التحقق من وجود الدليل "dir2" وتحولات أخرى مماثلة (أي استمرار التطبيع )

الآن ، بالترتيب ، ماذا يحدث للمسار الذي تم تمريره:

  1. إذا تم تمرير المسار نسبيًا ، فسيتم استبداله أولاً بالقيم من التوجيه include_path
  2. علاوة على ذلك ، يتم قطع المسار بطول معين ، اعتمادًا على النظام الأساسي
  3. تطبيع المسار قيد التقدم
  4. يتم تقليل المسار إلى الشكل المتعارف عليه

الآن دعونا نحاول الاستفادة من هذا. دعنا نحاول تضمين ملف معين "test.php" الموجود في الدليل "modules /". للقيام بذلك ، أضف "/" في النهاية. بحيث يُعرف الطول الإجمالي ، مع اسم الملف ، بالقيمة من include_path بأكثر من 4096 حرفًا.
script.php؟ module = test.php /././. [...] /././.

في هذه الحالة ، من الضروري التخمين بحيث ينتهي خط المسار بالكامل (المقطوع بالفعل) بنقطة (مهمة!) ، وليس بشرطة مائلة. للقيام بذلك ، يمكنك إضافة شرطة مائلة واحدة مثل هذا:

وسيعمل أحد هذه الخيارات بالتأكيد.

نحن نحلل

نحن ننظر بالترتيب ما هي التحولات التي ستحدث مع المسار
وحدات / test.php //././. [...] /./././ module.class.php
4200 حرفًا

أول ما يحدث للسلسلة هو إضافة القيمة من include_path إليها:
/home/site/public_html/modules/test.php//././. [...] /./././ module.class.php
4223 حرفًا

ثم يتم تسريع الخط إلى MAXPATHLEN (دعنا نقول 4096):
/home/site/public_html/modules/test.php//././ ./. [...] /./.
4096 حرفًا

يمكنك هنا معرفة سبب ضرورة إضافة شرطة مائلة أخرى (وإلا فسيتم قطع الخط بشرطة مائلة). الآن تم تسوية هذا الخط ، تتم أولاً إزالة الشرطات المائلة الإضافية:
/home/site/public_html/modules/test.php/././. [...] /./.
4095 حرفًا

نتيجة لذلك ، نحصل على المسار الصحيح للملف الذي نحتاجه ، وسيتم بالفعل نقل هذا المسار للتضمين ، وسيتم تضمين الملف الذي نحتاجه.

وبهذه الطريقة سنقوم بتضمين ملفنا "test.php" بنجاح.
script.php؟ module = test.php //././. [...] /././.

لذا فإن الضعف ليس نظريًا. نتيجة لذلك ، راهن موكلي ، وفزت بالمناقشة و 10 روبلات التي ناقشناها. بالطبع ، بالإضافة إلى 10 روبل ، فزت أيضًا بالثقة والاحترام في نظر العميل ، وهو أمر مهم أيضًا.

ملحوظات

هنا سوف ألقي نظرة على اثنين من مآثر مثيرة للاهتمام لهذه الثغرة الأمنية.

اخرج من الدليل

ضع في اعتبارك رمزًا مثل هذا:

) ;

دعنا نتخطى النقطة التي يمكنك من خلالها استخدام RFI وإرفاق ملف من خادم بعيد. لنفترض أن "allow_url_include = OFF" على الخادم.

ضع في اعتبارك الموقف عندما نحتاج إلى تضمين ملف من الدليل أدناه:
script.php؟ module = .. / test.php /././. [...] /././.

سيؤدي هذا الاستدعاء إلى إنشاء خطأ مثل الملف غير موجود. وللتغلب على هذا ، نحتاج إلى معالجة مثل هذا:
script.php؟ module = blabla /../../ test.php /././. [...: 5 /././.

لم أصف عبثًا عن تقديس المسارات. بفضلها ، لا يجب أن يكون دليل "blabla" موجودًا.

مضيفا فقط مائلة

ربما لاحظ القارئ اليقظ أنه في وصف التطبيع ، كتبت أنهم يقولون إن الخطوط المائلة الإضافية "/" والنقاط ذات الشرطات المائلة "/" تمت إزالتها ، فلماذا لا تستخدم فقط الشرطات المائلة لتجنب الأخطاء غير الضرورية عندما تصل النقطة النهاية.

الأمر كله يتعلق بالخوارزميات ، أي الشرطة المائلة بنقطة "/." إزالتها تماما. ولكن مع وجود شرطة مائلة بسيطة ، يكون الموقف أكثر تعقيدًا بعض الشيء ، أثناء التطبيع ، يتم استبدال كل شرطتين مائلتين بواحدة حتى يكون هناك شرطة مائلة واحدة (!) على اليسار ، على سبيل المثال:

/home/site/public_html/modules/test.php////////////////////
57 حرفًا

/home/site/public_html/modules/test.php/////////
48 حرفًا

/home/site/public_html/modules/test.php/////
44 حرفًا

/home/site/public_html/modules/test.php///
42 حرفًا

/home/site/public_html/modules/test.php//
41 حرفًا

/home/site/public_html/modules/test.php/
40 حرفًا

استطرادية صغيرة:

علاوة على ذلك ، إذا انتبهت للعديد من موارد الاختراق الشائعة ، فستلاحظ هذا الخطأ. كما أفهمها ، بدأ هذا الخطأ بمقال بواسطة Raz0r معين حيث اقترح متجهًا:
index.php؟ act = .. / .. / .. / .. / .. / etc / pаsswd ///// […] /////

وانتبهوا حتى للمجلة] [كرر أكير هذا الخطأ في مقالته. في الوقت نفسه ، حتى في مقالة USH الأصلية ، كتب بوضوح أنه من غير المرغوب فيه استخدام خطوط مائلة بسيطة ، ومن الضروري في النهاية ، قبل التطبيع ، أن يبقى رمز النقطة. والشرطات البسيطة (حتى بدون نقطة في النهاية) تعمل فقط في PHP مع Suhosin.

أي ، استخدم الشرطة المائلة مع نقطة "/". - طريقة أكثر شمولية ، لأنها ، على عكس الشرطة المائلة "/" ، تعمل مع جميع إصدارات php.

استنتاج

آمل أن تساعدك هذه المقالة على فهم أنه لا يمكنك ترك حتى أدنى نقاط الضعف في نصوصك ، حيث يمكنك عاجلاً أو آجلاً تطوير متجه الهجوم الخاص بك ، مما قد يؤدي إلى عواقب وخيمة.

يا خطيئة ، أوه ، عروق ، فنا. نفس الخاطئ (بمعنى 1). أفكار خاطئة. قاموس أوزيجوف التوضيحي. S.I. Ozhegov ، N.Yu. شفيدوفا. 1949 1992 ... قاموس أوزيجوف التوضيحي

ياء يصرف. اسم بواسطة القاموس التوضيحي الخاطئ لإفريموفا. تي اف افريموفا. 2000 ... القاموس التوضيحي الحديث للغة الروسية بواسطة إيفريموفا

الخطيئة هي انتهاك مباشر أو غير مباشر للعقائد الدينية (عهود الله أو الآلهة ، الوصفات والتقاليد) ؛ أقل انتهاكًا للقواعد الأخلاقية الأخلاقية السائدة والمعايير الراسخة في المجتمع. ينص التعريف على أن الخطيئة هي نتيجة فعل ... ... ويكيبيديا

إثم- الذنب خير و ... قاموس الهجاء الروسي

إثم- انظر الخطيئة. و؛ F. الخطيئة / براءة الأفكار ... قاموس للعديد من التعبيرات

الشر العام- ♦ (إنج) فهم أن كل الناس خطاة (رومية 3:23) ... قاموس وستمنستر للمصطلحات اللاهوتية

بالمعنى الشائع الاستخدام ، فعل مستهجن ، بالمعنى الديني ، انتهاك للمبادئ الأخلاقية الدينية ، تقييم ديني محدد لذنب الشخص ، ليس أمام المجتمع أو أي شخص آخر ، ولكن أمام الله. جنبا إلى جنب مع ... ... الموسوعة الجنسية

- ('Un positivo esistenzialism' ، 1948) لأباجنانو. لا يتم تفسير الوجودية على أنها "فلسفة اليأس" ، مع التركيز على حالات الأزمة للوجود البشري ، ولكن على أنها "إيجابية" ، وتمكين الشخص من تحقيق ... ...

فجور ، فجور ، فجور ، فجور ، فجور (أخلاق) ، رذيلة ، فجور ، إثم ، شهوانية ، خزي. تزوج ... قاموس مرادف

- (1844) تكوين Kierkegaard. في محاولة لدحض نظام هيجل الفلسفي ، في مقدمة PS. كتب Kierkegaard: تحدث Schleiermacher فقط عما يعرفه ، بينما Hegel ، على الرغم من كل صفاته الممتازة ومنحه الدراسية العملاقة ، في ... تاريخ الفلسفة: An Encyclopedia

كتب

  • الجوانب العامة لعلم النفس الأرثوذكسي ، بيتر فلاديميروفيتش دوبروسلسكي يقدم الكتاب نقاط مختلفة ... التصنيف: دراسات دينية السلسلة: مقالات عن الأنثروبولوجيا الأرثوذكسية الناشر: جريفين,
  • ماركة كاساندرا ، جنكيز أيتماتوف ، يتضمن كتاب الكاتب القرغيزي الشهير جنكيز أيتماتوف روايتين. تمت كتابة أول "واليوم أكثر من قرن" منذ خمسة عشر عامًا وهو مألوف بالفعل للعديد من القراء. في قلب الرواية - ... التصنيف: النثر الكلاسيكي والمعاصرالناشر:

فوكا,

"؛ صدى" سرقة الملف الشخصي شراء الحيوان!

"؛ صدى صوت"
"؛ صدى صوت" ماموث لطيف (100 نقطة)
"؛ if ($ user [" balls "]> = 100) (echo" Buy the animal

"؛) صدى صوت"
"؛ صدى" إيجابي القط (80 نقطة)
"؛ if ($ user [" balls "]> = 80) (echo" Buy the animal
"؛) else (echo" Buy animal
"؛) صدى صوت"
"؛ صدى" Cheerful Crab (50 نقطة)
"؛ if ($ user [" balls "]> = 50) (echo" Buy animal
"؛) else (echo" Buy animal
"؛) صدى صوت"
"؛ صدى" سلاحف ناريك))) (50 نقطة)
"؛ if ($ user [" balls "]> = 50) (echo" Buy animal
"؛) else (echo" Buy animal
"؛) صدى صوت"
"؛ صدى" التمساح الغاضب (50 نقطة)
"؛ if ($ user [" balls "]> = 50) (echo" Buy animal
"؛) else (echo" Buy animal
"؛) صدى صوت"
"؛ صدى" البطريق (50 نقطة)
"؛ if ($ user [" balls "]> = 50) (echo" Buy animal
"؛) else (echo" Buy animal
"؛) صدى صوت"
"؛ صدى" Blue elephant (50 نقطة)
"؛ if ($ user [" balls "]> = 50) (echo" Buy animal
"؛) else (echo" Buy animal
"؛) صدى صوت"

\ n "؛ صدى" " خلف
\ n "؛ صدى"
\ n "؛ break؛ case" ok ": $ select = abs (intval ($ _ GET [" select "])) ؛ إذا ($ select == 1) $ price = $ user [" balls "] - 100 ؛ if ($ select == 2) السعر بالدولار = المستخدم بالدولار ["الكرات"] - 80 ؛ إذا (اختر الدولار == ​​3) السعر = المستخدم بالدولار ["الكرات"] - 50 ؛ إذا (اختر الدولار == ​​4) السعر بالدولار الأمريكي = المستخدم بالدولار الأمريكي ["الكرات"] - 50 ؛ إذا (اختر الدولار == ​​5) السعر بالدولار الأمريكي = المستخدم بالدولار ["الكرات"] - 50 ؛ إذا (اختر الدولار == ​​6) السعر = المستخدم بالدولار ["الكرات "] - 50 ؛ إذا ($ select == 7) السعر = $ مستخدم [" balls "] - 50 ؛ if ($ select> = 1 AND $ select<= 7) { if ($price >= 0) (echo "تم شراء الحيوان بنجاح! ابحث في ملفك الشخصي
إلى الاستبيان → "؛ mysql_query (" UPDATE `pets` SET` pet_id` =" $ select "،` time` = "$ realtime" WHERE` user_id` = "". $ User ["id"]. "" " )؛ mysql_query ("UPDATE` user` SET` balls` = "$ price" WHERE` id` = "". $ user ["id"]. "" ")؛) else (صدى" Hacker ***! " ؛)) else (صدى "هذا الحيوان غير موجود!" ؛) كسر ؛ افتراضي: صدى "هل تريد الحصول على حيوان لطيف في ملفك الشخصي؟
شراء حيوان "؛ صدى صوت"
\ n "؛ صدى" " خلف
\ n "؛ صدى"
\ n "؛ if (! isset ($ fobian [" user_id "])) mysql_query (" INSERT INTO `pets` SET` user_id` =" ". $ user [" id "]." "")؛ break؛) include_once "../ sys / inc / tfoot.php" ؛؟>

كان هناك جدول للرمز بالطلب التالي:

إنشاء جدول إذا لم يكن EXISTS `حيوانات أليفة` (` id` INT (10) UNSIGNED NOT NULL AUTO_INCREMENT، `user_id` INT (10) UNSIGNED NOT NULL،` pet_id` INT (10) NOT NULL DEFAULT "0"، `time` text NOT NULL ، PRIMARY KEY (`id`)) Engine = MyISAM DEFAULT CHARSET = utf8 AUTO_INCREMENT = 1 ؛

حسنًا ، إليك مساعدة أخرى في الأرشيف حول تثبيت البرنامج النصي ، ما فعلته: حول البرنامج النصي - نص الحيوانات الرائعة في استبيان Dcms 6. *. * من fobian aka Dozz. الوظيفة: - شراء الحيوانات مقابل نقاط الموقع - مشاهدة حيوانات المستخدمين الآخرين - بعد 7 أيام يختفي الحيوان من الملف الشخصي ICQ: 4726991 البريد الإلكتروني: التثبيت: 1. املأ الجدول من ملف base.sql 2. سجل في ملف / info .php على حوالي 251 سطرًا برمز. $ fobian = mysql_fetch_array (mysql_query ("SELECT * FROM` pets` WHERE` user_id` = "". $ ank ["id"]. "" "))؛ if (isset ($ fobian ["user_id"]) AND $ fobian ["pet_id"]> = 1) ($ ost = $ realtime - $ fobian ["time"] ؛ if ($ ost> 604800) mysql_query ("UPDATE `الحيوانات الأليفة` SET` pet_id` =" 0 "،` time` = "0" WHERE` user_id` = "". $ ank ["id"]. "" ") ؛ echo" "؛) 3. التسجيل في ملف sys / inc / umenu.php في المكان الصحيح صدى "سوف يغير الحيوان
\ n "؛ استخدم صحتك =) ديمتري، أي أنه يبدو فارغًا!؟ ولكن كيف تجد طريقة للخروج من هذا الوضع؟