Tha sinn a’ sgrìobhadh matchmaking airson Dota 2014

Halo a h-uile duine.

As t-earrach seo thàinig mi tarsainn air pròiseact anns an do dh'ionnsaich na balaich mar a ruitheadh ​​​​iad an tionndadh frithealaiche Dota 2 2014 agus, mar sin, cluich air. Tha mi dèidheil air a’ gheama seo, agus cha b’ urrainn dhomh an cothrom sònraichte seo a thoirt seachad airson mo bhogadh nam òige.

Bidh mi a ’dol gu domhainn, agus mar sin thachair gun do sgrìobh mi bot Discord a tha an urra ri cha mhòr a h-uile gnìomh nach eil a’ faighinn taic san t-seann dreach den gheama, is e sin maids.
Ro a h-uile innleachdas leis a ’bot, chaidh an lobaidh a chruthachadh le làimh. Chruinnich sinn 10 ath-bheachdan air teachdaireachd agus chruinnich sinn frithealaiche le làimh, no chùm sinn coiteachadh ionadail.

Tha sinn a’ sgrìobhadh matchmaking airson Dota 2014

Cha b’ urrainn dha mo nàdar mar phrogramaiche seasamh ri uimhir de dh’ obair làimhe, agus thar oidhche rinn mi sgeidse a-mach air an dreach as sìmplidh den bot, a thog gu fèin-ghluasadach am frithealaiche nuair a bha 10 neach ann.

Cho-dhùin mi sa bhad sgrìobhadh ann an nodejs, oir cha toil leam Python gu mòr, agus tha mi a’ faireachdainn nas comhfhurtail san àrainneachd seo.

Is e seo a’ chiad eòlas agam a ’sgrìobhadh bot airson Discord, ach thionndaidh e a-mach gu robh e gu math sìmplidh. Tha am modal npm oifigeil discord.js a’ toirt seachad eadar-aghaidh goireasach airson obrachadh le teachdaireachdan, cruinneachadh ath-bheachdan, msaa.

Àicheadh: Tha a h-uile eisimpleir còd “gnàthach”, a’ ciallachadh gu bheil iad air a dhol tro ghrunn ath-sgrìobhadh air an oidhche.

Is e “ciudha” a th’ ann am bun-stèidh maidsidh anns am bi cluicheadairean a tha airson cluich air an cur a-steach agus air an toirt air falbh nuair nach eil iad ag iarraidh no a’ lorg geama.

Seo cò ris a tha brìgh “cluicheadair” coltach. An toiseach cha robh ann ach id neach-cleachdaidh ann an Discord, ach tha planaichean ann airson geamannan a chuir air bhog / a lorg bhon làrach, ach a’ chiad rud an-toiseach.

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

Agus seo an eadar-aghaidh ciudha. An seo, an àite “cluicheadairean,” thathas a’ cleachdadh tarraing ann an cruth “buidheann”. Airson aon chluicheadair, tha a 'bhuidheann air a dhèanamh suas de fhèin, agus airson cluicheadairean ann am buidheann, fa leth, a h-uile cluicheadairean anns a' bhuidheann.

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
}

Cho-dhùin mi tachartasan a chleachdadh gus co-theacsa iomlaid. Bha e freagarrach airson cùisean - air an tachartas “chaidh geama airson 10 neach a lorg”, faodaidh tu an teachdaireachd riatanach a chuir gu na cluicheadairean ann am teachdaireachdan prìobhaideach, agus an loidsig gnìomhachais bunaiteach a choileanadh - gnìomh a chuir air bhog gus dèanamh cinnteach gu bheil thu deiseil, ullachadh an lobaidh airson cur air bhog, agus mar sin air adhart.

Airson IOC bidh mi a’ cleachdadh InversifyJS. Tha eòlas tlachdmhor agam ag obair leis an leabharlann seo. Fast agus furasta!

Tha grunn ciudhaichean againn air an t-seirbheisiche againn - tha sinn air 1 × 1, àbhaisteach / rangachadh, agus modhan àbhaisteach no dhà a chuir ris. Mar sin, tha seòmar singilte ann a tha na laighe eadar an neach-cleachdaidh agus an sgrùdadh geama.

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

(Còd nòtan gus beachd a thoirt seachad air cò ris a tha na pròiseasan coltach)

An seo bidh mi a’ tòiseachadh a’ chiudha airson gach aon de na modhan geama a chaidh a chuir an gnìomh, agus cuideachd ag èisteachd airson atharrachaidhean ann am “buidhnean” gus na ciudhaichean atharrachadh agus còmhstrithean a sheachnadh.

Mar sin, gu math, chuir mi a-steach pìosan còd aig nach eil gnothach sam bith ris a’ chuspair, agus a-nis gluaisidh sinn air adhart gu dìreach gu bhith a’ dèanamh maids.

Beachdaichidh sinn air a 'chùis:

1) Tha an neach-cleachdaidh ag iarraidh cluich.

2) Gus an rannsachadh a thòiseachadh, bidh e a’ cleachdadh Gateway = Discord, is e sin, a’ cur freagairt ris an teachdaireachd:

Tha sinn a’ sgrìobhadh matchmaking airson Dota 2014

3) Bidh an geata seo a’ dol gu RoomService agus ag ràdh “Tha neach-cleachdaidh bho discord ag iarraidh a dhol a-steach don ciudha, modh: geama gun rangachadh.”

4) Bidh RoomService a’ gabhail ri iarrtas a’ gheata agus a’ putadh an neach-cleachdaidh (nas mionaidiche, am buidheann luchd-cleachdaidh) a-steach don chiudha a tha thu ag iarraidh.

5) Bidh an ciudha a’ sgrùdadh a h-uile uair a tha cluicheadairean gu leòr ann airson cluich. Ma ghabhas e dèanamh, cuir a-mach tachartas:

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

6) Tha e soilleir gu bheil RoomService toilichte a bhith ag èisteachd ris a h-uile ciudha le dùil draghail mun tachartas seo. Bidh sinn a’ faighinn liosta de chluicheadairean mar chuir a-steach, cruthaich “seòmar” brìgheil bhuapa, agus, gu dearbh, cuir a-mach tachartas:

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) Mar sin ràinig sinn an t-ùghdarras “as àirde” - an clas Bot. San fharsaingeachd, bidh e a’ dèiligeadh ris a’ cheangal eadar geataichean (chan urrainn dhomh tuigsinn cho èibhinn sa tha e a’ coimhead ann an Ruisis) agus loidsig gnìomhachais a’ gheama. Bidh am bot a’ cumail sùil air an tachartas agus ag òrdachadh DiscordGateway sgrùdadh ullachaidh a chuir chun a h-uile neach-cleachdaidh.

Tha sinn a’ sgrìobhadh matchmaking airson Dota 2014

8) Ma dhiùltas cuideigin no mura gabh e ris a’ gheama taobh a-staigh 3 mionaidean, CHAN EIL sinn gan tilleadh chun ciudha. Bidh sinn a’ tilleadh a h-uile duine eile chun ciudha agus a’ feitheamh gus am bi 10 neach ann a-rithist. Ma tha a h-uile cluicheadair air gabhail ris a’ gheama, tòisichidh am pàirt inntinneach.

Rèiteachadh frithealaiche sònraichte

Tha na geamannan againn air an cumail air VDS le Windows server 2012. Bhon seo is urrainn dhuinn grunn cho-dhùnaidhean a tharraing:

  1. Chan eil docair air, a bhuail mi anns a 'chridhe
  2. Bidh sinn a 'sàbhaladh air màl

Is e an obair pròiseas a ruith air VDS bho VPS air Linux. Sgrìobh mi frithealaiche sìmplidh ann am Flasg. Seadh, cha toil leam Python, ach dè as urrainn dhut a dhèanamh? Tha e nas luaithe agus nas fhasa am frithealaiche seo a sgrìobhadh air.

Bidh e a’ coileanadh 3 gnìomhan:

  1. A 'tòiseachadh air frithealaiche le rèiteachadh - a' taghadh mapa, an àireamh de chluicheadairean airson an geama a thòiseachadh, agus seata de plugins. Cha sgrìobh mi mu dheidhinn plugins a-nis - is e sgeulachd eadar-dhealaichte a tha sin le liotairean de chofaidh air an oidhche measgaichte le deòir agus falt air a reubadh.
  2. A’ stad/ath-thòiseachadh an fhrithealaiche gun fhios nach bi ceanglaichean soirbheachail, nach urrainn dhuinn a làimhseachadh ach le làimh.

Tha a h-uile dad sìmplidh an seo, chan eil eisimpleirean còd eadhon iomchaidh. Sgriobt 100 loidhne

Mar sin, nuair a thàinig daoine 10 còmhla agus ghabh iad ris a’ gheama, chaidh am frithealaiche a chuir air bhog agus bha a h-uile duine dèidheil air cluich, chaidh ceangal airson ceangal ris a’ gheama a chuir ann am teachdaireachdan prìobhaideach.

Tha sinn a’ sgrìobhadh matchmaking airson Dota 2014

Le bhith a’ briogadh air a’ cheangal, bidh an cluicheadair a’ ceangal ri frithealaiche a’ gheama, agus an uairsin sin e. Às deidh ~ 25 mionaidean, thèid an “seòmar” brìgheil le cluicheadairean a ghlanadh.

Tha mi duilich ro-làimh airson cho neònach sa tha an artaigil, cha do sgrìobh mi an seo airson ùine mhòr, agus tha cus còd ann airson earrannan cudromach a shoilleireachadh. Noodles, ann an ùine ghoirid.

Ma chì mi ùidh anns a’ chuspair, bidh dàrna pàirt ann - bidh mo chràdh ann le plugins airson srcds (frithealaiche sònraichte airson Stòr), agus, is dòcha, siostam rangachadh agus mion-dotabuff, làrach le staitistig geama.

Cuid de cheanglaichean:

  1. An làrach-lìn againn (staitistig, bòrd stiùiridh, duilleag tighinn air tìr beag agus luchdachadh sìos teachdaiche)
  2. Frithealaiche discord

Source: www.habr.com

Cuir beachd ann