İçeriğe atla

Oda tarifleri

Sohbet komutları

Güvenilir oyuncuların odayı sohbetten yönetmesine izin verin ve komutları sohbetten gizleyin.

Bu oda, ! ile başlayan mesajları okur, bunları komut olarak çalıştırır ve diğer oyunculardan gizler. Bir oyuncu, sadece sizin bildiğiniz bir parola göndererek yönetici olur.

Komut tablosu

Her komut, yönetici gerektirip gerektirmediğini bildirir ve gönderen ile argümanlarını alır:

commands.mjs
export function createCommands(room, { passphrase }) {
  const findPlayer = (name) =>
    room
      .getPlayerList()
      .find(
        (p) => p.name.toLowerCase() === name?.toLowerCase(),
      );

  return {
    help: {
      admin: false,
      run: (player) =>
        room.sendAnnouncement(
          'Commands: !help, !admin <passphrase>, !start, ' +
            '!stop, !swap, !mute <name>',
          player.id,
        ),
    },
    admin: {
      admin: false,
      run: async (player, [attempt]) => {
        if (attempt !== passphrase)
          return room.sendAnnouncement(
            'Wrong passphrase.',
            player.id,
          );
        await room.setPlayerAdmin(player.id, true);
        await room.sendAnnouncement(
          `${player.name} is now an admin.`,
        );
      },
    },
    start: { admin: true, run: () => room.startGame() },
    stop: { admin: true, run: () => room.stopGame() },
    swap: {
      admin: true,
      run: async () => {
        for (const p of room.getPlayerList()) {
          if (p.team !== 0)
            await room.setPlayerTeam(
              p.id,
              p.team === 1 ? 2 : 1,
            );
        }
      },
    },
    mute: {
      admin: true,
      run: async (player, [name]) => {
        const target = findPlayer(name);
        if (!target)
          return room.sendAnnouncement(
            `No player named ${name}.`,
            player.id,
          );
        await room.setPlayerMuted(target.id, true);
      },
    },
  };
}

Sohbete bağlayın

onPlayerChat, bir mesajın gösterilip gösterilmeyeceğine eşzamanlı olarak karar vermelidir; bu yüzden komutu önce gizleyin, sonra çalıştırın:

host.mjs
import { createRoom } from 'ball2d/node';
import { createCommands } from './commands.mjs';

const room = await createRoom({
  apiKey: process.env.BALL2D_API_KEY,
  roomName: 'Pickup football',
  noPlayer: true,
  public: true,
});

const commands = createCommands(room, {
  passphrase: process.env.ROOM_PASSPHRASE,
});

room.onPlayerChat = (player, text) => {
  if (!text.startsWith('!')) return;
  const [name, ...args] = text.slice(1).trim().split(/\s+/);
  const command = commands[name?.toLowerCase()];
  if (!command) {
    void room.sendAnnouncement(
      `Unknown command. Try !help`,
      player.id,
    );
  } else if (
    command.admin &&
    !room.getPlayer(player.id)?.admin
  ) {
    void room.sendAnnouncement(
      'Only admins can do that.',
      player.id,
    );
  } else {
    Promise.resolve(command.run(player, args)).catch((error) =>
      room.sendAnnouncement(
        `Command failed: ${error.message}`,
        player.id,
      ),
    );
  }
  // Never show commands, the passphrase included, to the room.
  return false;
};

room.onError = (message) => console.error(message);
console.log(room.roomLink);

Parola, oda içinde diğer sohbet mesajları gibi iletilir ve oda hostu bunu okuyabilir. Bu parolayı yalnızca bu oda için kullanın, yeni bir ROOM_PASSPHRASE ile yeniden başlatarak değiştirin ve gerçek bir parolayı asla yeniden kullanmayın.

Her komutta admin neden kontrol edilir

Yönetici hakları, bir mesaj yoldayken değişebilir. Komut çalıştığı anda room.getPlayer(player.id)?.admin okumak, oyuncunun katıldığı andaki bir kopyayı değil, odanın güncel durumunu kullanır.