Nou ap ekri matchmaking pou Dota 2014

Bonjou tout moun.

Prentan sa a mwen te vin atravè yon pwojè nan ki mesye yo te aprann ki jan yo kouri vèsyon an sèvè Dota 2 2014 epi, kòmsadwa, jwe sou li. Mwen se yon gwo fanatik jwèt sa a, epi mwen pa t 'kapab pase opòtinite inik sa a plonje tèt mwen nan anfans mwen.

Mwen pijon trè pwofondman, epi li te rive ke mwen te ekri yon bot Discord ki responsab pou prèske tout fonksyonalite ki pa sipòte nan ansyen vèsyon an nan jwèt la, sètadi matchmaking.
Anvan tout inovasyon yo ak bot la, gwoup la te kreye manyèlman. Nou te kolekte 10 reyaksyon sou yon mesaj epi nou te rasanble yon sèvè manyèlman, oswa nou te òganize yon gwoup lokal.

Nou ap ekri matchmaking pou Dota 2014

Nati mwen kòm yon pwogramè pa t 'kapab kenbe tèt ak anpil travay manyèl, ak lannwit lan mwen eskize vèsyon ki pi senp nan bot la, ki otomatikman leve sèvè a lè te gen 10 moun.

Mwen imedyatman deside ekri nan nodejs, paske mwen pa reyèlman renmen Python, epi mwen santi mwen pi alèz nan anviwònman sa a.

Sa a se premye eksperyans mwen ekri yon bot pou Discord, men li te vin trè senp. Ofisyèl npm modil discord.js bay yon koòdone pratik pou travay ak mesaj, kolekte reyaksyon, elatriye.

Limit responsabilite nou: Tout egzanp kòd yo "aktyèl", sa vle di yo te pase plizyè iterasyon nan reekri nan mitan lannwit.

Baz matchmaking se yon "keu" kote jwè ki vle jwe yo mete yo epi retire yo lè yo pa vle oswa jwenn yon jwèt.

Sa a se ki sans nan yon "jwè" sanble. Okòmansman li te jis yon id itilizatè nan Discord, men gen plan yo lanse / rechèch pou jwèt nan sit la, men premye bagay an premye.

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);
  }
}

Ak isit la se koòdone nan keu. Isit la, olye pou yo "jwè yo," yo itilize yon abstraksyon nan fòm yon "gwoup". Pou yon sèl jwè, gwoup la konsiste de tèt li, ak pou jwè nan yon gwoup, respektivman, nan tout jwè yo nan gwoup la.

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
}

Mwen deside sèvi ak evènman pou fè echanj kontèks. Li te apwopriye pou ka - sou evènman an "yo te jwenn yon jwèt pou 10 moun", ou ka voye mesaj ki nesesè bay jwè yo nan mesaj prive, epi pote soti nan lojik biznis debaz la - lanse yon travay yo tcheke preparasyon pou, prepare gwoup la. pou lansman, ak sou sa.

Pou IOC mwen itilize InversifyJS. Mwen gen yon eksperyans bèl travay ak bibliyotèk sa a. Vit ak fasil!

Nou gen plizyè moun kap kriye sou sèvè nou an - nou te ajoute 1x1, nòmal / rated, ak yon koup nan mòd koutim. Se poutèt sa, gen yon Singleton RoomService ki kouche ant itilizatè a ak rechèch la jwèt.

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)
          }
        });
      }
    );
  }

(Kode nouy yo bay yon lide sou kisa pwosesis yo apeprè sanble)

Isit la mwen inisyalize keu la pou chak nan mòd jwèt yo aplike, epi tou koute chanjman nan "gwoup" yo nan lòd yo ajiste keu yo epi evite kèk konfli.

Se konsa, byen fè, mwen mete moso nan kòd ki pa gen anyen fè ak sijè a, epi kounye a ann deplase sou dirèkteman nan matchmaking.

Ann konsidere ka a:

1) Itilizatè a vle jwe.

2) Pou kòmanse rechèch la, li itilize Gateway=Discord, sa vle di, li mete yon reyaksyon sou mesaj la:

Nou ap ekri matchmaking pou Dota 2014

3) Pòtay sa a ale nan RoomService epi li di "Yon itilizatè ki soti nan diskòd vle antre nan keu a, mòd: jwèt san klasman."

4) RoomService aksepte demann pòtay la epi pouse itilizatè a (pi presizeman, gwoup itilizatè a) nan keu vle a.

5) keu la tcheke chak fwa gen ase jwè yo jwe. Si sa posib, emèt yon evènman:

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

6) RoomService se evidamman san pwoblèm mwen tap koute chak keu nan antisipasyon enkyete nan evènman sa a. Nou resevwa yon lis jwè kòm opinyon, fòme yon "chanm" vityèl nan men yo, epi, nan kou, bay yon evènman:

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) Se konsa, nou te rive nan "pi wo" otorite - klas la Bot. An jeneral, li fè fas ak koneksyon ki genyen ant pòtay (mwen pa ka konprann ki jan komik li sanble nan Ris) ak lojik biznis la nan matchmaking. Bot la tande evènman an epi li bay lòd pou DiscordGateway voye yon chèk preparasyon pou tout itilizatè yo.

Nou ap ekri matchmaking pou Dota 2014

8) Si yon moun rejte oswa pa aksepte jwèt la nan 3 minit, Lè sa a, nou PA retounen yo nan keu la. Nou retounen tout lòt moun nan keu a epi tann jiskaske gen 10 moun ankò. Si tout jwè yo te aksepte jwèt la, Lè sa a, pati enteresan an kòmanse.

Konfigirasyon sèvè dedye

Jwèt nou yo òganize sou VDS ak Windows sèvè 2012. Apati sa a nou ka tire plizyè konklizyon:

  1. Pa gen okenn docker sou li, ki frape m 'nan kè a
  2. Nou ekonomize sou lwaye

Travay la se kouri yon pwosesis sou VDS soti nan yon VPS sou Linux. Mwen te ekri yon sèvè senp nan Flask. Wi, mwen pa renmen Python, men kisa ou ka fè?Li pi vit ak pi fasil pou ekri sèvè sa a sou li.

Li fè 3 fonksyon:

  1. Kòmanse yon sèvè ak yon konfigirasyon - chwazi yon kat jeyografik, kantite jwè yo kòmanse jwèt la, ak yon seri grefon. Mwen pa pral ekri sou grefon kounye a - sa a se yon istwa diferan ak lit kafe nan mitan lannwit melanje ak dlo nan je ak cheve chire.
  2. Sispann / rekòmanse sèvè a nan ka ta gen koneksyon san siksè, ki nou ka sèlman okipe manyèlman.

Tout bagay se senp isit la, egzanp kòd yo pa menm apwopriye. Script 100 liy

Se konsa, lè 10 moun te reyini ansanm ak aksepte jwèt la, sèvè a te lanse ak tout moun te anvi jwe, yon lyen pou konekte nan jwèt la te voye nan mesaj prive.

Nou ap ekri matchmaking pou Dota 2014

Lè w klike sou lyen an, jwè a konekte ak sèvè jwèt la, epi sa a se li. Apre ~25 minit, "chanm" vityèl ak jwè yo netwaye.

Mwen eskize davans pou malèz atik la, mwen pa ekri la a depi lontan, epi gen twòp kòd pou mete aksan sou seksyon enpòtan yo. Nouy, ​​nan kout.

Si mwen wè enterè nan sijè a, pral gen yon dezyèm pati - li pral genyen touman mwen an ak grefon pou srcds (Sous sèvè dedye), ak, pwobableman, yon sistèm evalyasyon ak mini-dotabuff, yon sit ak estatistik jwèt.

Kèk lyen:

  1. Sit entènèt nou an (estatistik, leaderboard, ti paj aterisaj ak telechaje kliyan)
  2. Sèvè Discord

Sous: www.habr.com

Add nouvo kòmantè