قابلیت‌های مدیر - سرویس بلادرنگ

در این مستند قصد داریم تا با قابلیت‌های مدیر بلادرنگ آشنا شویم. قابلیت‌های مدیر به امکاناتی می‌گویند که توسعه‌دهنده‌ی بازی در سرویس رایانش و به کمک sdk آن می‌تواند از آن‌ها بهره‌مند شود و با آن‌ها بر روی فرآیند بازی و نتیجه‌ی آن تأثیر بگذارد. این قابلیت‌ها به چند بخش تقسیم می‌شوند که در ادامه به یکایک آن‌ها می‌پردازیم.

پیش‌نیازها

  1. در صورتی که با سرویس بلادرنگ آشنایی ندارید، به معرفی سرویس بلادرنگ مراجعه کنید.
  2. در صورتی که هنوز با تنظیمات پنل سرویس بلادرنگ آشنا نشده اید، به تنظیمات پنل سرویس بلادرنگ مراجعه کنید.

کاربران آنلاین

فرض کنید می‌خواهید در سرویس رایانش مطلع شوید که در این لحظه چه کاربرانی آنلاین هستند. کاربر آنلاین به کاربری گفته می‌شود که به سرویس بلادرنگ متصل شده است. (برای اتصال به سرویس بلادرنگ در اندروید به اینجا و در یونیتی به اینجا مراجعه کنید.) برای این کار ابتدا باید شیء زیر ساخته شود:

var onlineUser = new Backtory.OnlineUser();

و از این شیء برای صدازدن توابع مربوطه استفاده شود. تابع اول که وضعیت یک تک کاربر را بررسی می‌کند، به صورت زیر است:

onlineUser.checkUserStatus(userId, {
    success: function(response) {
        /* response is like this:
         * { online: true }
         */
        context.log(response);
    },
    error: function(error) {
        context.log(error);
    }
});

همان‌طور که واضح است، مقدار بولین response.online مشخص می‌کند که کاربر مشخص شده آنلاین هست یا خیر.

تابع دوم که وضعیت لیستی از کاربران را بررسی می‌کند، به این صورت است:

onlineUser.checkUserListStatus([userId1, userId2, ...], {
    success: function(response) {
        /* response is like this:
         * {
         *    areOnline: [true, false, ...]
         * }
         */
        context.log(response);
    },
    error: function(error) {
        context.log(error);
    }
});

این تابع لیستی از userIdها را می‌گیرد و در قالب یک لیست با همان اندازه‌ی لیست ورودی، وضعیت آنلاین بودن کاربران را به همان ترتیب برمی‌گرداند.

چت گروهی

مدیر بلادرنگ می‌توانند کارهایی از جمله ایجاد گروه، افزودن کاربر به آن، حذف کاربر، و تغییر نقش کاربر از member به owner را انجام دهد. در این قسمت به نحوه‌ی انجام این کارها توسط مدیر می‌پردازیم.

ایجاد گروه

برای ایجاد یک گروه چت به شیوه‌ی زیر عمل می‌کنیم:

var groupChat = new Backtory.GroupChat();
groupChat.setName("MyGroup")
      /* .setPrivate(true) */
         .createNewGroup(ownerUserId, {
              success: function(groupId) {
                 context.log('GroupId is ', groupId);
              },
              error: function(error) {
                 context.log(error);
              }
});

در این کد، بر اساس نام تعیین شده برای گروه و نوع دسترسی به گروه (نوع دسترسی public که حالت پیش‌فرض است و البته می‌توان با صدا زدن تابع setPrivate با ورودی false نیز آن را ایجاد کرد؛ و نوع دسترسی private که با صدا زدن setPrivate با ورودی true می‌توان آن را اعمال کرد) و صدا زدن تابع createNewGroup، گروه جدیدی ساخته می‌شود و groupId آن نیز در شیء groupChat نگهداری می‌شود. هم‌چنین، همان‌طور که در کد مشخص شده است، groupId در تابع success هم به دست ما داده می‌شود.

هنگام صدا زدن توابع مدیریت کاربر (افزودن، حذف و تغییر نقش) لازم است که شیء مربوط به چت گروهی ساخته شده باشد و groupId آن نیز ست شده باشد. برای این منظور، یا باید مشابه کد بالا یک گروه جدید ایجاد کرد، یا برای یک گروه موجود که groupId آن را می‌دانیم، مشابه زیر عمل کنیم:

var groupChat = new Backtory.GroupChat().setGroupId("59a1458de4b03a309805137d");

یا:

var groupChat = new Backtory.GroupChat("59a1458de4b03a309805137d");

حال که شیء groupChat موجود و groupId آن تعیین شده است، روی این شیء می‌توان توابع مدیریت کاربر را صدا زد. توضیح این توابع در ادامه می‌آید.

افزودن کاربر به گروه

برای اضافه کردن یک کاربر به گروه به شیوه‌ی زیر عمل می‌کنیم:

var groupChat = ...; // initialize it as explained above
groupChat.addMember(newMemberId, adderUserId, isMemberOwner, {
    success: function() {
        context.log('Member is added successfully.');
    },
    error: function(error) {
        context.log(error);
    }
});

پارامترهای تابع فوق به شرح زیر می‌باشد:

  1. newMemberId: آی‌دی کاربری که می‌خواهیم به گروه اضافه شود.
  2. adderUserId: آی‌دی کاربری که عضو جدید را به گروه اضافه می‌کند. دقت کنید که اگر نوع دسترسی گروه private باشد، این کاربر حتما باید owner گروه باشد. در غیر این‌صورت درخواست با خطا مواجه می‌شود.
  3. isMemberOwner: یک متغیر بولین که تعیین می‌کند آیا این عضو جدید owner هست یا خیر.

حذف کاربر از گروه

برای حذف کردن یک کاربر از یک گروه به شیوه‌ی زیر عمل می‌کنیم:

var groupChat = ...; // initialize it as explained above
groupChat.removeMember(removedUserId, removerUserId, {
    success: function() {
        context.log('Member is removed successfully.');
    },
    error: function(error) {
        context.log(error);
    }
});

پارامترهای تابع فوق به شرح زیر می‌باشد:

  1. removedUserId: آی‌دی کاربری که می‌خواهیم از گروه حذف شود.
  2. removerUserId: آی‌دی کاربری که می‌خواهد کاربر را از گروه حذف کند. دقت کنید که اگر نوع دسترسی گروه private باشد، این کاربر حتما باید owner گروه باشد. در غیر این‌صورت درخواست با خطا مواجه می‌شود.

تغییر نقش کاربر عادی به owner

برای تغییر نقش کاربر در گروه از عادی به owner به شیوه‌ی زیر عمل می‌کنیم:

var groupChat = ...; // initialize it as explained above
groupChat.makeMemberOwner(memberUserId, ownerUserId, {
    success: function() {
        context.log('Member is set as new admin successfully.');
    },
    error: function(error) {
        context.log(error);
    }
});

پارامترهای تابع فوق به شرح زیر می‌باشد:

  1. memberUserId: آی‌دی کاربری که می‌خواهیم مدیر جدید گروه شود.
  2. ownerUserId: آی‌دی کاربری که می‌خواهد این عمل تغییر نقش را انجام دهد. دقت کنید که اگر نوع دسترسی گروه private باشد، این کاربر حتما باید owner گروه باشد. در غیر این‌صورت درخواست با خطا مواجه می‌شود.

مدیریت بازی بلادرنگ

شما به کمک سرویس رایانش می‌توانید یک بازی بلادرنگ را در حین وقوع آن مدیریت کنید و بر روی آن اثرگذار باشید. برای این هدف ابتدا باید این شیء ساخته شود:

var game = new Backtory.RealtimeGame("<REALTIME-GAME-ID>");

همان‌طور که می‌بینید،آرگومان ورودی کانستراکتور بالا آی‌دی بازی ریل‌تایم است که در وب‌هوک‌های Join ،Challenge Ready ،Match Found و Start می‌توانید آن را دریافت کنید. در ادامه کارهایی که می‌توانید به کمک این شیء انجام دهید، توضیح داده می‌شود.

گرفتن اطلاعات بازی

به کمک تابع زیر می‌توانید اطلاعات بازی بلادرنگ را دریافت کنید:

game.getInfo({
    success: function(info) {
        /*
         * info is like this:
         *  {
         *    address: "<REALTIME-GAME-ADDRESS>",
         *    state: "<STATE>",
         *    matchParticipants: [
         *       {
         *          "userId": "<USER-ID-1>"
         *       },
         *       {
         *          "userId": "<USER-ID-2>"
         *       },
         *       ...
         *    ]
         *  }
         */
        context.log(info);
    },
    error: function(error) {
        context.log(error);
    }
});

در کد بالا، پارامترهای شیء info را مشاهده می‌کنید؛ پارامتر address نشان دهنده‌ی آدرس بازی بلادرنگ در بکتوری است. پارامتر matchParticipants بازیکنان موجود در بازی را نشان می‌دهد. پارامتر state نیز وضعیت بازی را نشان می‌دهد و همواره یکی از مقادیر زیر است:

دقت کنید که در صورتی که در تنظیمات سرویس بلادرنگ، تیک «امکان ارسال نتیجه توسط کلاینت» زده نشده باشد، با اعلام نتیجه از سمت سرور، بازی از وضعیت active مستقیما به وضعیت ended منتقل می‌شود.

اضافه کردن یک بازیکن بعد از شکل‌گیری بازی

در بعضی از سناریوهای خاص پیش می‌آید که کاربری جزو بازیکنان موجود در انطباق یا چالش نبوده است، اما می‌خواهیم در میانه‌ی بازی آن بازیکنان وارد شود. برای این هدف، از تابع زیر کمک می‌گیریم:

game.addPlayer(userId, {
    success: function(response) {
        context.log(response);
    },
    error: function(error) {
        context.log(error);
    }
});

در صورت موفقیت، response ای دریافت می‌کنید که ساختار آن مشابه info در گرفتن اطلاعات بازی است.

شروع دستی بازی

همان‌طور که در مستندات گفته شده، بعد از انطباق یا چالش موفق، سرویس بلادرنگ بکتوری بازی بلادرنگ را می‌سازد و منتظر می‌ماند تا تمامی بازیکنان موجود در انطباق یا چالش به آن join شوند. اما در صورتی که یک بازیکن عامدانه نخواهد join شود، یا مثلا به دلیل قطعی دسترسی به اینترنت نتواند درخواست join را به بکتوری بفرستد، بازی آغاز نخواهد شد.

شما به عنوان مدیر بازی بلادرنگ می‌توانید با شروع دستی بازی کاری کنید که بازی با همان تعداد نفراتی که join شده‌اند، آغاز شود و منتظر باقی نفرات نمانیم. بدین منظور از کد زیر می‌توانید استفاده کنید:

game.start({
    success: function() {
        context.log('game started successfully.');
    },
    error: function(error) {
        context.log(error);
    }
});

ارسال پیام مدیر به یک کاربر خاص

برای این‌که مدیر بلادرنگ یک پیام خاص را به کاربری ارسال کند، به شیوه‌ی زیر می‌توان عمل کرد:

game.sendServerMessageToUser(userId, message, data, {
    success: function() {
        context.log('Message was sent to user successfully.');
    },
    error: function(error) {
        context.log(error);
    }
});

پارامترهای تابع فوق به شرح زیر می‌باشد:

  1. userId: آی‌دی کاربری که می‌خواهیم پیام به او ارسال شود.
  2. message: رشته‌ای که می‌خواهیم به عنوان پیام به کاربر ارسال شود.
  3. data: یک json حاوی هر اطلاعاتی که به همراه پیام می‌تواند ارسال شود.

در صورتی که این متد با موفقیت اجرا شود، لیسنر onMasterMessage در اندروید و لیسنر OnServerMessage در یونیتی برای کاربر خاص هدف صدا زده می‌شوند.

ارسال پیام مدیر به کل بازیکنان بازی بلادرنگ

برای این‌که مدیر بلادرنگ یک پیام خاص را به همه‌ی کاربران بازی آنلاین ارسال کند، کد زیر را می‌توان استفاده کرد:

game.sendServerMessage(message, data, {
    success: function() {
        context.log('Message was sent to all users successfully.');
    },
    error: function(error) {
        context.log(error);
    }
});

پارامترهای تابع فوق به شرح زیر می‌باشد:

  1. message: رشته‌ای که می‌خواهیم به عنوان پیام به کاربران ارسال شود.
  2. data: یک json حاوی هر اطلاعاتی که به همراه پیام می‌تواند ارسال شود.

مشابه قسمت قبل، در صورتی که این متد با موفقیت اجرا شود، لیسنر onMasterMessage در اندروید و لیسنر OnServerMessage در یونیتی برای هر کاربر بازی صدا زده می‌شوند.

ارسال پیام مدیر به صورت بالک به کل بازیکنان بازی‌های مختلف

در دو قسمت قبل دیدیم که چطور مدیر بلادرنگ پیام‌هایی را به «یک» بازی می‌فرستد. در این قسمت نشان می‌دهیم که مدیر هم‌چنین می‌تواند به همه‌ی بازیکنان «چند» بازی مختلف پیام ارسال کند. از آن‌جایی که این پیام‌ها با صدا زدن یک متد sdk رایانش و به صورت «یک‌جا» ارسال می‌شوند، به این نحو از ارسال پیام‌های مدیر «بالک» (‌Bulk) گفته می‌شود. برای ارسال پیام مدیر به صورت بالک کد زیر مورد استفاده قرار می‌گیرد:

game.addToServerMessageBulk(realtimeGameId, message, data);
game.addToServerMessageBulk(realtimeGameId2, message2, data2);
...
game.sendServerMessageBulk({
   success: function() {
       context.log('Message was sent to all users of different realtime games successfully.');
   },
   error: function(error) {
       context.log(error);
   }
});

دقت کنید که در این حالت، realtimeGameId ای که در موقع ساخت شیء game پاس داده شده است، اهمیت ندارد و realtimeGameId ای که پیام و دیتا باید به آن ارسال شود، موقع صدا زدن addToServerMessageBulk گرفته می‌شود. هم‌چنین تمام پیام‌هایی که توسط addToServerMessageBulk به مجموعه اضافه شده‌اند،‌ با یکبار صدا زدن sendServerMessageBulk ارسال می‌شوند.

ارسال پیام به صورت بالک می‌تواند در شرایط خاصی مورد استفاده قرار بگیرد. مثلا فرض کنید یک bot به کمک تابع رایانش نوشته‌اید و زمان‌بندی آن به گونه‌ای است که هر ۵ دقیقه اجرا می‌شود؛ با هر بار اجرا، همه‌ی بازی‌های در حال اجرا را از دیتابیس می‌خواند و به همه‌ی آن‌ها پیام مشخصی را ارسال می‌کند. برای ارسال این پیام مشخص به همه‌ی بازی‌های بلادرنگ می‌تواند تنها یک‌بار متد sendServerMessageBulk را صدا بزند.

ارسال رویداد بلادرنگ به کل بازیکنان بازی

مدیر می‌تواند از طریق کد زیر به همه‌ی بازیکنان درگیر در یک بازی Event ارسال کند:

game.sendEvent(senderUserId, message, data, {
   success: function() {
       context.log('Realtime game event was sent to all players successfully.');
   },
   error: function(error) {
       context.log(error);
   }
});

پارامترهای تابع فوق به شرح زیر می‌باشد:

  1. senderUserId: آی‌دی کاربری که می‌خواهیم از طرف او پیام را ارسال کنیم.
  2. message: رشته‌ای که می‌خواهیم به عنوان پیام به کاربران ارسال شود.
  3. data: یک json حاوی هر اطلاعاتی که به همراه پیام می‌تواند ارسال شود.

در صورتی که این متد با موفقیت اجرا شود، لیسنر onMatchEvent در اندروید و لیسنر OnGameEvent در یونیتی برای همه‌ی بازیکنان صدا زده می‌شوند.

ارسال رویداد بلادرنگ به صورت بالک به کل بازیکنان بازی‌های مختلف

برای ارسال Event به صورت بالک به صورت زیر می‌توان عمل کرد:

game.addToEventBulk(realtimeGameId, senderUserId, message, data);
game.addToEventBulk(realtimeGameId2, senderUserId2, message2, data2);
...
game.sendEventBulk({
   success: function() {
       context.log('Game event was sent to all users of different realtime games successfully.');
   },
   error: function(error) {
       context.log(error);
   }
});

دقت کنید که در این حالت، realtimeGameId ای که در موقع ساخت شیء game پاس داده شده است، اهمیت ندارد و realtimeGameId ای که پیام و دیتا باید به آن ارسال شود، موقع صدا زدن addToEventBulk گرفته می‌شود. هم‌چنین تمام پیام‌هایی که توسط addToEventBulk به مجموعه اضافه شده‌اند،‌ با یکبار صدا زدن sendEventBulk ارسال می‌شوند.

تعیین برندگان و پایان بازی بلادرنگ

به صورت پیش‌فرض شما می‌توانید نتیجه‌ی بازی را در سمت سرور مشخص کنید. بدین منظور، به کمک تابع زیر می‌توانید نتیجه را برای همه‌ی بازیکنان ارسال کرده و پایان بازی را اعلام کنید.

game.sendWinners([userId, userId2, ...], {
   success: function() {
       context.log('Winners was sent successfully.');
   },
   error: function(error) {
       context.log(error);
   }
});

تنها پارامتر تابع فوق آرایه‌ای از آی‌دی‌های کاربرانی است که می‌خواهیم به عنوان برنده اعلام کنیم.

به این ترتیب شما با بیشتر اعمالی که مدیر بلادرنگ می‌تواند انجام دهد، آشنا شدید. تنها مسئله‌ای که باقی‌مانده، مدیریت خصوصیات بازی است که در مستند بعدی به آن پرداخته می‌شود.

گام بعدی