Tunaandika kutengeneza mechi kwa Dota 2014

Sema kila mtu

Katika chemchemi hii niligundua mradi ambao wavulana walijifunza jinsi ya kuendesha toleo la seva ya Dota 2 2014 na, ipasavyo, kucheza juu yake. Mimi ni shabiki mkubwa wa mchezo huu, na sikuweza kuacha fursa hii ya kipekee ya kuzama katika utoto wangu.

Nilizama sana, na ikawa kwamba niliandika bot ya Discord ambayo inawajibika kwa karibu utendaji wote ambao hauhimiliwi katika toleo la zamani la mchezo, ambayo ni kutengeneza mechi.
Kabla ya uvumbuzi wote na roboti, chumba cha kushawishi kiliundwa kwa mikono. Tulikusanya maoni 10 kwa ujumbe na tukakusanya seva wenyewe, au tukaandaa chumba cha kushawishi cha ndani.

Tunaandika kutengeneza mechi kwa Dota 2014

Asili yangu kama programu haikuweza kuhimili kazi nyingi za mikono, na mara moja nilichora toleo rahisi zaidi la bot, ambalo liliinua seva kiotomatiki wakati kulikuwa na watu 10.

Mara moja niliamua kuandika katika nodejs, kwa sababu siipendi sana Python, na ninahisi vizuri zaidi katika mazingira haya.

Huu ni uzoefu wangu wa kwanza kuandika bot kwa Discord, lakini iligeuka kuwa rahisi sana. Moduli rasmi ya npm discord.js hutoa kiolesura rahisi cha kufanya kazi na ujumbe, kukusanya maoni, n.k.

Kanusho: Mifano yote ya msimbo ni "ya sasa", kumaanisha kuwa wamepitia marudio kadhaa ya kuandika upya usiku.

Msingi wa kupanga mechi ni "foleni" ambayo wachezaji wanaotaka kucheza huwekwa ndani na kuondolewa wakati hawataki au kupata mchezo.

Hivi ndivyo kiini cha "mchezaji" kinavyoonekana. Hapo awali ilikuwa kitambulisho cha mtumiaji katika Discord, lakini kuna mipango ya kuzindua/kutafuta michezo kutoka kwa tovuti, lakini mambo ya kwanza kwanza.

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

Na hapa kuna kiolesura cha foleni. Hapa, badala ya "wachezaji," kifupi katika mfumo wa "kundi" hutumiwa. Kwa mchezaji mmoja, kikundi kinajumuisha yeye mwenyewe, na kwa wachezaji katika kikundi, kwa mtiririko huo, wa wachezaji wote katika kikundi.

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
}

Niliamua kutumia matukio kubadilishana muktadha. Ilifaa kwa kesi - kwenye hafla "mchezo wa watu 10 ulipatikana", unaweza kutuma ujumbe unaohitajika kwa wachezaji katika ujumbe wa kibinafsi, na kutekeleza mantiki ya kimsingi ya biashara - anza kazi ya kuangalia utayari, kuandaa kushawishi. kwa uzinduzi, na kadhalika.

Kwa IOC mimi hutumia InversifyJS. Nina uzoefu mzuri wa kufanya kazi na maktaba hii. Haraka na rahisi!

Tuna foleni kadhaa kwenye seva yetu - tumeongeza 1x1, ya kawaida/iliyokadiriwa, na aina kadhaa maalum. Kwa hiyo, kuna singleton RoomService ambayo iko kati ya mtumiaji na utafutaji wa mchezo.

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

(Nambari za noodles kutoa wazo la jinsi michakato inavyoonekana)

Hapa ninaanzisha foleni kwa kila aina ya mchezo unaotekelezwa, na pia kusikiliza mabadiliko katika "vikundi" ili kurekebisha foleni na kuepuka migogoro fulani.

Kwa hivyo, umefanya vizuri, niliingiza vipande vya msimbo ambavyo havina uhusiano wowote na mada, na sasa wacha tuendelee moja kwa moja kwenye ulinganishaji.

Hebu fikiria kesi:

1) Mtumiaji anataka kucheza.

2) Ili kuanza utaftaji, hutumia Gateway=Discord, ambayo ni, kuweka majibu kwa ujumbe:

Tunaandika kutengeneza mechi kwa Dota 2014

3) Lango hili huenda kwa RoomService na kusema "Mtumiaji kutoka kwa discord anataka kuingia kwenye foleni, modi: mchezo ambao haujakadiriwa."

4) RoomService inakubali ombi la lango na kumsukuma mtumiaji (kwa usahihi zaidi, kikundi cha watumiaji) kwenye foleni inayotaka.

5) Foleni hukagua kila wakati kuna wachezaji wa kutosha wa kucheza. Ikiwezekana, toa tukio:

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

6) RoomService ni dhahiri inasikiza kwa furaha kila foleni kwa kutazamia kwa hamu tukio hili. Tunapokea orodha ya wachezaji kama ingizo, kuunda "chumba" pepe kutoka kwao, na, bila shaka, kutoa tukio:

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) Kwa hivyo tulifika kwa mamlaka "ya juu" - darasa boT. Kwa ujumla, anahusika na uunganisho kati ya lango (siwezi kuelewa jinsi ya kuchekesha inavyoonekana kwa Kirusi) na mantiki ya biashara ya mechi. Kijibu husikia tukio na kuamuru DiscordGateway kutuma ukaguzi wa utayari kwa watumiaji wote.

Tunaandika kutengeneza mechi kwa Dota 2014

8) Iwapo mtu atakataa au hakubali mchezo ndani ya dakika 3, basi HATUWARUDISHI kwenye foleni. Tunarudisha kila mtu kwenye foleni na kusubiri hadi kuwe na watu 10 tena. Ikiwa wachezaji wote wamekubali mchezo, basi sehemu ya kuvutia huanza.

Usanidi maalum wa seva

Michezo yetu inapangishwa kwenye VDS na seva ya Windows 2012. Kutokana na hili tunaweza kufikia hitimisho kadhaa:

  1. Hakuna docker juu yake, ambayo ilinipiga moyoni
  2. Tunaokoa kwa kukodisha

Kazi ni kuendesha mchakato kwenye VDS kutoka VPS kwenye Linux. Niliandika seva rahisi katika Flask. Ndiyo, siipendi Python, lakini unaweza kufanya nini? Ni haraka na rahisi kuandika seva hii juu yake.

Inafanya kazi 3:

  1. Kuanzisha seva kwa usanidi - kuchagua ramani, idadi ya wachezaji wa kuanzisha mchezo, na seti ya programu-jalizi. Sitaandika kuhusu programu-jalizi sasa - hiyo ni hadithi tofauti na lita za kahawa usiku iliyochanganywa na machozi na nywele zilizochanika.
  2. Kusimamisha/kuwasha tena seva iwapo miunganisho haikufaulu, ambayo tunaweza kushughulikia kwa mikono pekee.

Kila kitu ni rahisi hapa, mifano ya nambari haifai hata. Hati 100 za mstari

Kwa hivyo, watu 10 walipokusanyika na kukubali mchezo, seva ilizinduliwa na kila mtu alikuwa na hamu ya kucheza, kiungo cha kuunganisha kwenye mchezo kilitumwa kwa ujumbe wa faragha.

Tunaandika kutengeneza mechi kwa Dota 2014

Kwa kubofya kiungo, mchezaji huunganisha kwenye seva ya mchezo, na kisha ndivyo. Baada ya ~ dakika 25, "chumba" pepe chenye wachezaji huondolewa.

Ninaomba msamaha mapema kwa shida ya makala, sijaandika hapa kwa muda mrefu, na kuna kanuni nyingi za kuonyesha sehemu muhimu. Noodles, kwa ufupi.

Ikiwa nitaona nia ya mada, kutakuwa na sehemu ya pili - itakuwa na mateso yangu na programu-jalizi za srcds (Seva iliyojitolea ya Chanzo), na, pengine, mfumo wa ukadiriaji na mini-dotabuff, tovuti iliyo na takwimu za mchezo.

Baadhi ya viungo:

  1. Tovuti yetu (takwimu, ubao wa wanaoongoza, ukurasa mdogo wa kutua na upakuaji wa mteja)
  2. Seva ya discord

Chanzo: mapenzi.com

Kuongeza maoni