ืื ื—ื ื• ื›ื•ืชื‘ื™ื ืฉื™ื“ื•ื›ื™ื ืœื“ื•ื˜ื” 2014

ืฉืœื•ื ืœื›ื•ืœื.

ื‘ืื‘ื™ื‘ ื”ื–ื” ื ืชืงืœืชื™ ื‘ืคืจื•ื™ืงื˜ ืฉื‘ื• ื”ื—ื‘ืจ'ื” ืœืžื“ื• ืื™ืš ืœื”ืจื™ืฅ ืืช ืฉืจืช ื”ื“ื•ื˜ื” 2 ื’ืจืกืช 2014 ื•ื‘ื”ืชืื, ืœืฉื—ืง ื‘ื”. ืื ื™ ืžืขืจื™ืฅ ื’ื“ื•ืœ ืฉืœ ื”ืžืฉื—ืง ื”ื–ื”, ื•ืœื ื™ื›ื•ืœืชื™ ืœื•ื•ืชืจ ืขืœ ื”ื”ื–ื“ืžื ื•ืช ื”ื™ื™ื—ื•ื“ื™ืช ื”ื–ื• ืœืฉืงื•ืข ื‘ื™ืœื“ื•ืชื™.

ืฆืœืœืชื™ ืขืžื•ืง ืžืื•ื“, ื•ื›ืš ืงืจื” ืฉื›ืชื‘ืชื™ ื‘ื•ื˜ ืฉืœ Discord ืฉืื—ืจืื™ ื›ืžืขื˜ ืขืœ ื›ืœ ื”ืคื•ื ืงืฆื™ื•ื ืœื™ื•ืช ืฉืื™ื ื” ื ืชืžื›ืช ื‘ื’ืจืกื” ื”ื™ืฉื ื” ืฉืœ ื”ืžืฉื—ืง, ื›ืœื•ืžืจ ืฉื™ื“ื•ื›ื™ื.
ืœืคื ื™ ื›ืœ ื”ื—ื™ื“ื•ืฉื™ื ืขื ื”ื‘ื•ื˜, ื”ืœื•ื‘ื™ ื ื•ืฆืจ ื‘ืื•ืคืŸ ื™ื“ื ื™. ืืกืคื ื• 10 ืชื’ื•ื‘ื•ืช ืœื”ื•ื“ืขื” ื•ื”ืจื›ื™ื‘ื ื• ืฉืจืช ื‘ืื•ืคืŸ ื™ื“ื ื™, ืื• ืื™ืจื—ื ื• ืœื•ื‘ื™ ืžืงื•ืžื™.

ืื ื—ื ื• ื›ื•ืชื‘ื™ื ืฉื™ื“ื•ื›ื™ื ืœื“ื•ื˜ื” 2014

ื”ื˜ื‘ืข ืฉืœื™ ื›ืžืชื›ื ืช ืœื ืขืžื“ ื‘ื›ืœ ื›ืš ื”ืจื‘ื” ืขื‘ื•ื“ื” ื™ื“ื ื™ืช, ื•ื‘ื™ืŸ ืœื™ืœื” ืฉืจื˜ื˜ืชื™ ืืช ื”ื’ืจืกื” ื”ืคืฉื•ื˜ื” ื‘ื™ื•ืชืจ ืฉืœ ื”ื‘ื•ื˜, ืฉื”ืขืœื” ืืช ื”ืฉืจืช ืื•ื˜ื•ืžื˜ื™ืช ื›ืฉื”ื™ื• 10 ืื ืฉื™ื.

ื”ื—ืœื˜ืชื™ ืžื™ื“ ืœื›ืชื•ื‘ ื‘-nodejs, ื›ื™ ืื ื™ ืœื ืžืžืฉ ืื•ื”ื‘ ืืช Python, ื•ืื ื™ ืžืจื’ื™ืฉ ื™ื•ืชืจ ื ื•ื— ื‘ืกื‘ื™ื‘ื” ื”ื–ื•.

ื–ื• ื”ื”ืชื ืกื•ืช ื”ืจืืฉื•ื ื” ืฉืœื™ ื‘ื›ืชื™ื‘ืช ื‘ื•ื˜ ืœื“ื™ืกืงื•ืจื“, ืื‘ืœ ื”ืชื‘ืจืจ ืฉื–ื” ืžืื•ื“ ืคืฉื•ื˜. ืžื•ื“ื•ืœ npm ื”ืจืฉืžื™ discord.js ืžืกืคืง ืžืžืฉืง ื ื•ื— ืœืขื‘ื•ื“ื” ืขื ื”ื•ื“ืขื•ืช, ืื™ืกื•ืฃ ืชื’ื•ื‘ื•ืช ื•ื›ื•'.

ื›ืชื‘ ื•ื™ืชื•ืจ: ื›ืœ ื“ื•ื’ืžืื•ืช ื”ืงื•ื“ ื”ืŸ "ืขื“ื›ื ื™ื•ืช", ื›ืœื•ืžืจ ื”ืŸ ืขื‘ืจื• ืžืกืคืจ ืื™ื˜ืจืฆื™ื•ืช ืฉืœ ืฉื›ืชื•ื‘ ื‘ืœื™ืœื”.

ื”ื‘ืกื™ืก ืœืฉื™ื“ื•ื›ื™ื ื”ื•ื "ืชื•ืจ" ืฉื‘ื• ืฉื—ืงื ื™ื ืฉืจื•ืฆื™ื ืœืฉื—ืง ืžื•ื›ื ืกื™ื ื•ืžื•ืจื—ืงื™ื ื›ืฉื”ื ืœื ืจื•ืฆื™ื ืื• ืžื•ืฆืื™ื ืžืฉื—ืง.

ื›ืš ื ืจืื™ืช ื”ืžื”ื•ืช ืฉืœ "ืฉื—ืงืŸ". ื‘ืชื—ื™ืœื” ื–ื” ื”ื™ื” ืจืง โ€‹โ€‹ืžื–ื”ื” ืžืฉืชืžืฉ ื‘ื“ื™ืกืงื•ืจื“, ืื‘ืœ ื™ืฉ ืชื•ื›ื ื™ื•ืช ืœื”ืฉื™ืง/ืœื—ืคืฉ ืžืฉื—ืงื™ื ืžื”ืืชืจ, ืื‘ืœ ืงื•ื“ื ื›ืœ.

export enum Realm {
  DISCORD,
  EXTERNAL,
}

export default class QueuePlayer {
  constructor(public readonly realm: Realm, public readonly id: string) {}

  public is(qp: QueuePlayer): boolean {
    return this.realm === qp.realm && this.id === qp.id;
  }

  static Discord(id: string) {
    return new QueuePlayer(Realm.DISCORD, id);
  }

  static External(id: string) {
    return new QueuePlayer(Realm.EXTERNAL, id);
  }
}

ื•ื”ื ื” ืžืžืฉืง ื”ืชื•ืจ. ื›ืืŸ, ื‘ืžืงื•ื "ืฉื—ืงื ื™ื", ื ืขืฉื” ืฉื™ืžื•ืฉ ื‘ื”ืคืฉื˜ื” ื‘ืฆื•ืจืช "ืงื‘ื•ืฆื”". ืขื‘ื•ืจ ืฉื—ืงืŸ ื‘ื•ื“ื“, ื”ืงื‘ื•ืฆื” ืžื•ืจื›ื‘ืช ืžืขืฆืžื•, ื•ืœืฉื—ืงื ื™ื ื‘ืงื‘ื•ืฆื”, ื‘ื”ืชืืžื”, ืžื›ืœ ืฉื—ืงื ื™ ื”ืงื‘ื•ืฆื”.

export default interface IQueue extends EventEmitter {
  inQueue: QueuePlayer[]
  put(uid: Party): boolean;
  remove(uid: Party): boolean;
  removeAll(ids: Party[]): void;

  mode: MatchmakingMode
  roomSize: number;
  clear(): void
}

ื”ื—ืœื˜ืชื™ ืœื”ืฉืชืžืฉ ื‘ืื™ืจื•ืขื™ื ื›ื“ื™ ืœื”ื—ืœื™ืฃ ื”ืงืฉืจ. ื–ื” ื”ืชืื™ื ืœืžืงืจื™ื - ื‘ืื™ืจื•ืข "ื ืžืฆื ืžืฉื—ืง ืœ-10 ืื ืฉื™ื", ื ื™ืชืŸ ืœืฉืœื•ื— ืืช ื”ื”ื•ื“ืขื” ื”ื“ืจื•ืฉื” ืœืฉื—ืงื ื™ื ื‘ื”ื•ื“ืขื•ืช ืคืจื˜ื™ื•ืช, ื•ืœื‘ืฆืข ืืช ื”ื”ื™ื’ื™ื•ืŸ ื”ืขืกืงื™ ื”ื‘ืกื™ืกื™ - ืœื”ืคืขื™ืœ ืžืฉื™ืžื” ืœื‘ื“ื™ืงืช ืžื•ื›ื ื•ืช, ืœื”ื›ื™ืŸ ืืช ื”ืœื•ื‘ื™ ืœื”ืฉืงื” ื•ื›ืŸ ื”ืœืื”.

ืขื‘ื•ืจ IOC ืื ื™ ืžืฉืชืžืฉ ื‘-InversifyJS. ื™ืฉ ืœื™ ื—ื•ื•ื™ื” ื ืขื™ืžื” ื‘ืขื‘ื•ื“ื” ืขื ื”ืกืคืจื™ื™ื” ื”ื–ื•. ืžื”ื™ืจ ื•ืงืœ!

ื™ืฉ ืœื ื• ืžืกืคืจ ืชื•ืจื™ื ื‘ืฉืจืช ืฉืœื ื• - ื”ื•ืกืคื ื• 1x1, ืจื’ื™ืœ/ืžื“ื•ืจื’, ื•ื›ืžื” ืžืฆื‘ื™ื ืžื•ืชืืžื™ื ืื™ืฉื™ืช. ืœื›ืŸ, ืงื™ื™ื RoomService Singleton ืฉื ืžืฆื ื‘ื™ืŸ ื”ืžืฉืชืžืฉ ืœื—ื™ืคื•ืฉ ื”ืžืฉื—ืง.

constructor(
    @inject(GameServers) private gameServers: GameServers,
    @inject(MatchStatsService) private stats: MatchStatsService,
    @inject(PartyService) private partyService: PartyService
  ) {
    super();
    this.initQueue(MatchmakingMode.RANKED);
    this.initQueue(MatchmakingMode.UNRANKED);
    this.initQueue(MatchmakingMode.SOLOMID);
    this.initQueue(MatchmakingMode.DIRETIDE);
    this.initQueue(MatchmakingMode.GREEVILING);
    this.partyService.addListener(
      "party-update",
      (event: PartyUpdatedEvent) => {
        this.queues.forEach((q) => {
          if (has(q.queue, (t) => t.is(event.party))) {
            // if queue has this party, we re-add party
            this.leaveQueue(event.qp, q.mode)
            this.enterQueue(event.qp, q.mode)
          }
        });
      }
    );

    this.partyService.addListener(
      "party-removed",
      (event: PartyUpdatedEvent) => {
        this.queues.forEach((q) => {
          if (has(q.queue, (t) => t.is(event.party))) {
            // if queue has this party, we re-add party
            q.remove(event.party)
          }
        });
      }
    );
  }

(ืงื•ื“ ืื˜ืจื™ื•ืช ื›ื“ื™ ืœืชืช ืžื•ืฉื’ ืื™ืš ื”ืชื”ืœื™ื›ื™ื ื ืจืื™ื ื‘ืขืจืš)

ื›ืืŸ ืื ื™ ืžืืชื—ืœ ืืช ื”ืชื•ืจ ืขื‘ื•ืจ ื›ืœ ืื—ื“ ืžืžืฆื‘ื™ ื”ืžืฉื—ืง ื”ืžื™ื•ืฉืžื™ื, ื•ื’ื ืžืงืฉื™ื‘ ืœืฉื™ื ื•ื™ื™ื ื‘"ืงื‘ื•ืฆื•ืช" ืขืœ ืžื ืช ืœื”ืชืื™ื ืืช ื”ืชื•ืจื™ื ื•ืœื”ื™ืžื ืข ืžื›ืžื” ื”ืชื ื’ืฉื•ื™ื•ืช.

ืื–, ื›ืœ ื”ื›ื‘ื•ื“, ื”ื›ื ืกืชื™ ืคื™ืกื•ืช ืงื•ื“ ืฉืœื ืงืฉื•ืจื•ืช ืœื ื•ืฉื, ื•ืขื›ืฉื™ื• ื ืขื‘ื•ืจ ื™ืฉื™ืจื•ืช ืœืฉื™ื“ื•ื›ื™ื.

ื‘ื•ืื• ื ื‘ื—ืŸ ืืช ื”ืžืงืจื”:

1) ื”ืžืฉืชืžืฉ ืจื•ืฆื” ืœืฉื—ืง.

2) ื›ื“ื™ ืœื”ืชื—ื™ืœ ืืช ื”ื—ื™ืคื•ืฉ, ื”ื•ื ืžืฉืชืžืฉ ื‘-Gateway=Discord, ื›ืœื•ืžืจ, ืžื›ื ื™ืก ืชื’ื•ื‘ื” ืœื”ื•ื“ืขื”:

ืื ื—ื ื• ื›ื•ืชื‘ื™ื ืฉื™ื“ื•ื›ื™ื ืœื“ื•ื˜ื” 2014

3) ืฉืขืจ ื–ื” ืขื•ื‘ืจ ืœ-RoomService ื•ืื•ืžืจ "ืžืฉืชืžืฉ ืž-discord ืจื•ืฆื” ืœื”ื™ื›ื ืก ืœืชื•ืจ, ืžืฆื‘: ืžืฉื—ืง ืœื ืžื“ื•ืจื’."

4) RoomService ืžืงื‘ืœ ืืช ื‘ืงืฉืช ื”ืฉืขืจ ื•ื“ื•ื—ืฃ ืืช ื”ืžืฉืชืžืฉ (ืœื™ืชืจ ื“ื™ื•ืง, ืงื‘ื•ืฆืช ื”ืžืฉืชืžืฉื™ื) ืœืชื•ืจ ื”ืจืฆื•ื™.

5) ื”ืชื•ืจ ื‘ื•ื“ืง ื‘ื›ืœ ืคืขื ืฉื™ืฉ ืžืกืคื™ืง ืฉื—ืงื ื™ื ืœืฉื—ืง. ืื ืืคืฉืจ, ืฉืœื— ืื™ืจื•ืข:

private onRoomFound(players: Party[]) {
    this.emit("room-found", {
      players,
    });
  }

6) RoomService ื›ืžื•ื‘ืŸ ืžืงืฉื™ื‘ ื‘ืฉืžื—ื” ืœื›ืœ ืชื•ืจ ื‘ืฆื™ืคื™ื™ื” ื—ืจื“ื” ืœืื™ืจื•ืข ื”ื–ื”. ืื ื• ืžืงื‘ืœื™ื ืจืฉื™ืžื” ืฉืœ ืฉื—ืงื ื™ื ื›ืงืœื˜, ื™ื•ืฆืจื™ื ืžื”ื "ื—ื“ืจ" ื•ื™ืจื˜ื•ืืœื™, ื•ื›ืžื•ื‘ืŸ, ืžื•ืฆื™ืื™ื ืื™ืจื•ืข:

queue.addListener("room-found", (event: RoomFoundEvent) => {
      console.log(
        `Room found mode: [${mode}]. Time to get free room for these guys`
      );
      const room = this.getFreeRoom(mode);
      room.fill(event.players);

      this.onRoomFormed(room);
    });

7) ืื– ื”ื’ืขื ื• ืœืกืžื›ื•ืช "ื”ื’ื‘ื•ื”ื” ื‘ื™ื•ืชืจ" - ื”ื›ื™ืชื” ื‘ื•ื˜. ื‘ื›ืœืœ, ื”ื•ื ืขื•ืกืง ื‘ื—ื™ื‘ื•ืจ ื‘ื™ืŸ ืฉืขืจื™ื (ืื ื™ ืœื ืžืฆืœื™ื— ืœื”ื‘ื™ืŸ ื›ืžื” ื–ื” ื ืจืื” ืžืฆื—ื™ืง ื‘ืจื•ืกื™ืช) ืœื‘ื™ืŸ ื”ื”ื™ื’ื™ื•ืŸ ื”ืขืกืงื™ ืฉืœ ืฉื™ื“ื•ื›ื™ื. ื”ื‘ื•ื˜ ืฉื•ืžืข ืืช ื”ืื™ืจื•ืข ื•ืžื•ืจื” ืœ-DiscordGateway ืœืฉืœื•ื— ื‘ื“ื™ืงืช ืžื•ื›ื ื•ืช ืœื›ืœ ื”ืžืฉืชืžืฉื™ื.

ืื ื—ื ื• ื›ื•ืชื‘ื™ื ืฉื™ื“ื•ื›ื™ื ืœื“ื•ื˜ื” 2014

8) ืื ืžื™ืฉื”ื• ื“ื•ื—ื” ืื• ืœื ืžืงื‘ืœ ืืช ื”ืžืฉื—ืง ืชื•ืš 3 ื“ืงื•ืช, ืื– ืื ื—ื ื• ืœื ืžื—ื–ื™ืจื™ื ืื•ืชื• ืœืชื•ืจ. ืื ื—ื ื• ืžื—ื–ื™ืจื™ื ืืช ื›ืœ ื”ืฉืืจ ืœืชื•ืจ ื•ืžื—ื›ื™ื ืขื“ ืฉื™ื”ื™ื• ืฉื•ื‘ 10 ืื ืฉื™ื. ืื ื›ืœ ื”ืฉื—ืงื ื™ื ืงื™ื‘ืœื• ืืช ื”ืžืฉื—ืง, ืื– ื”ื—ืœืง ื”ืžืขื ื™ื™ืŸ ืžืชื—ื™ืœ.

ืชืฆื•ืจืช ืฉืจืช ื™ื™ืขื•ื“ื™

ื”ืžืฉื—ืงื™ื ืฉืœื ื• ืžืชืืจื—ื™ื ื‘-VDS ืขื Windows server 2012. ืžื›ืืŸ ื ื•ื›ืœ ืœื”ืกื™ืง ืžืกืคืจ ืžืกืงื ื•ืช:

  1. ืื™ืŸ ื‘ื• ื“ื•ืงืจ, ืžื” ืฉืคื’ืข ืœื™ ื‘ืœื‘
  2. ืื ื—ื ื• ื—ื•ืกื›ื™ื ื‘ืฉื›ืจ ื“ื™ืจื”

ื”ืžืฉื™ืžื” ื”ื™ื ืœื”ืคืขื™ืœ ืชื”ืœื™ืš ืขืœ VDS ืž-VPS ืขืœ ืœื™ื ื•ืงืก. ื›ืชื‘ืชื™ ืฉืจืช ืคืฉื•ื˜ ื‘-Flask. ื›ืŸ, ืื ื™ ืœื ืื•ื”ื‘ ืืช Python, ืื‘ืœ ืžื” ืืชื” ื™ื›ื•ืœ ืœืขืฉื•ืช? ื–ื” ืžื”ื™ืจ ื™ื•ืชืจ ื•ืงืœ ื™ื•ืชืจ ืœื›ืชื•ื‘ ืืช ื”ืฉืจืช ื”ื–ื” ืขืœื™ื•.

ื”ื•ื ืžื‘ืฆืข 3 ืคื•ื ืงืฆื™ื•ืช:

  1. ื”ืคืขืœืช ืฉืจืช ืขื ืงื•ื ืคื™ื’ื•ืจืฆื™ื” - ื‘ื—ื™ืจืช ืžืคื”, ืžืกืคืจ ื”ืฉื—ืงื ื™ื ืœื”ืคืขืœืช ื”ืžืฉื—ืง ื•ืขืจื›ืช ืชื•ืกืคื™ื. ืื ื™ ืœื ืื›ืชื•ื‘ ืขื›ืฉื™ื• ืขืœ ืชื•ืกืคื™ื - ื–ื” ื›ื‘ืจ ืกื™ืคื•ืจ ืื—ืจ ืขื ืœื™ื˜ืจื™ื ืฉืœ ืงืคื” ื‘ืœื™ืœื” ืžื”ื•ืœื™ื ื‘ื“ืžืขื•ืช ื•ืฉื™ืขืจ ืงืจื•ืข.
  2. ืขืฆื™ืจื”/ื”ืคืขืœื” ืžื—ื“ืฉ ืฉืœ ื”ืฉืจืช ื‘ืžืงืจื” ืฉืœ ื—ื™ื‘ื•ืจื™ื ืœื ืžื•ืฆืœื—ื™ื, ืฉื ื•ื›ืœ ืœื˜ืคืœ ื‘ื”ื ืจืง ื‘ืื•ืคืŸ ื™ื“ื ื™.

ื”ื›ืœ ืคืฉื•ื˜ ื›ืืŸ, ื“ื•ื’ืžืื•ืช ืงื•ื“ ืืคื™ืœื• ืœื ืžืชืื™ืžื•ืช. ืชืกืจื™ื˜ ื‘ืŸ 100 ืฉื•ืจื•ืช

ืื– ื›ืฉ-10 ืื ืฉื™ื ื”ืชืืกืคื• ื•ืงื™ื‘ืœื• ืืช ื”ืžืฉื—ืง, ื”ืฉืจืช ื”ื•ืฉืง ื•ื›ื•ืœื ื”ื™ื• ืœื”ื•ื˜ื™ื ืœืฉื—ืง, ื ืฉืœื— ืงื™ืฉื•ืจ ืœื—ื™ื‘ื•ืจ ืœืžืฉื—ืง ื‘ื”ื•ื“ืขื•ืช ืคืจื˜ื™ื•ืช.

ืื ื—ื ื• ื›ื•ืชื‘ื™ื ืฉื™ื“ื•ื›ื™ื ืœื“ื•ื˜ื” 2014

ื‘ืœื—ื™ืฆื” ืขืœ ื”ืงื™ืฉื•ืจ, ื”ืฉื—ืงืŸ ืžืชื—ื‘ืจ ืœืฉืจืช ื”ืžืฉื—ืง, ื•ืื– ื–ื”ื•. ืœืื—ืจ ~ 25 ื“ืงื•ืช, "ื”ื—ื“ืจ" ื”ื•ื•ื™ืจื˜ื•ืืœื™ ืขื ื”ืฉื—ืงื ื™ื ื ื•ืงื”.

ืื ื™ ืžืชื ืฆืœ ืžืจืืฉ ืขืœ ื”ืกืจื‘ื•ืœ ืฉืœ ื”ืžืืžืจ, ืœื ื›ืชื‘ืชื™ ื›ืืŸ ื”ืจื‘ื” ื–ืžืŸ, ื•ื™ืฉ ื™ื•ืชืจ ืžื“ื™ ืงื•ื“ ื›ื“ื™ ืœื”ื“ื’ื™ืฉ ืงื˜ืขื™ื ื—ืฉื•ื‘ื™ื. ื ื•ื“ืœืก, ื‘ืงื™ืฆื•ืจ.

ืื ืื ื™ ืจื•ืื” ืขื ื™ื™ืŸ ื‘ื ื•ืฉื, ื™ื”ื™ื” ื—ืœืง ืฉื ื™ - ื”ื•ื ื™ื›ื™ืœ ืืช ื”ื™ืกื•ืจื™ื ืฉืœื™ ืขื ืชื•ืกืคื™ื ืœ-srcds (ืฉืจืช ื™ื™ืขื•ื“ื™ ืžืงื•ืจ), ื•ื›ื ืจืื” ื’ื ืžืขืจื›ืช ื“ื™ืจื•ื’ ื•-mini-dotabuff, ืืชืจ ืขื ืกื˜ื˜ื™ืกื˜ื™ืงื•ืช ืžืฉื—ืง.

ื›ืžื” ืงื™ืฉื•ืจื™ื:

  1. ื”ืืชืจ ืฉืœื ื• (ืกื˜ื˜ื™ืกื˜ื™ืงื”, Leaderboard, ื“ืฃ ื ื—ื™ืชื” ืงื˜ืŸ ื•ื”ื•ืจื“ืช ืœืงื•ื—)
  2. ืฉืจืช ื“ื™ืกืงื•ืจื“

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”