Em ji bo Dota 2014 hevberdanê dinivîsin

Hê her kesî

Vê biharê ez rastî projeyek hatim ku tê de xort fêr bûn ka meriv çawa guhertoya servera Dota 2 2014-ê dimeşîne û, li gorî vê, li ser wê bilîze. Ez heyranokek mezin a vê lîstikê me, û min nikarîbû vê fersenda bêhempa ji dest xwe berde ku ez di zaroktiya xwe de biçim.

Min pir kûr kew kir, û wusa çêbû ku min botek Discord nivîsand ku berpirsiyarê hema hema hemî fonksiyonên ku di guhertoya kevn a lîstikê de nayê piştgirî kirin, ango hevgirtinê ye.
Berî hemî nûbûnên bi botê, lobî bi destan hate afirandin. Me 10 reaksiyonên peyamek berhev kir û bi destan serverek berhev kir, an jî lobiyek herêmî mêvandar kir.

Em ji bo Dota 2014 hevberdanê dinivîsin

Xwezaya min a bernamesaz nikaribû ewqas xebata destan rabigire, û di şevekê de min guhertoya herî hêsan a botê xêz kir, ku dema ku 10 kes hebûn server bixweber bilind kir.

Min tavilê biryar da ku ez di nodejs de binivîsim, ji ber ku ez bi rastî ji Python hez nakim, û ez di vê hawîrdorê de xwe rehettir hîs dikim.

Ev yekem ezmûna min a nivîsandina botek ji bo Discord e, lê ew pir hêsan derket. Modula fermî ya npm discord.js ji bo xebata bi peyaman, berhevkirina reaksiyonên, hwd re navgînek hêsan peyda dike.

Daxuyanî: Hemî mînakên kodê "niha" ne, tê vê wateyê ku wan bi şev çend dubareyên ji nû ve nivîsandinê derbas kirine.

Bingeha hevberdanê "dozek" e ku tê de lîstikvanên ku dixwazin bilîzin tê de têne danîn û dema ku ew nexwazin an lîstikek bibînin têne derxistin.

Ev e ku cewhera "lîstikvanek" xuya dike. Di destpêkê de ew tenê nasnameya bikarhênerek di Discord de bû, lê plan hene ku ji malperê lîstikan bidin destpêkirin/lêgerîn, lê pêşî tiştên pêşîn.

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

Û li vir pêwendiya dorê ye. Li vir, li şûna "lîstikvan", abstrakasyonek di forma "kom" de tête bikar anîn. Ji bo lîstikvanek yekane, kom ji xwe, û ji bo lîstikvanên di komekê de, bi rêzê ve, ji hemî lîstikvanên di komê de pêk tê.

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
}

Min biryar da ku bûyeran bikar bînim da ku çarçove biguherînim. Ew ji bo dozan maqûl bû - li ser bûyera "lîstikek ji bo 10 kesan hate dîtin", hûn dikarin di peyamên taybet de peyama pêwîst ji lîstikvanan re bişînin, û mantiqa karsaziya bingehîn pêk bînin - dest bi peywirek ji bo kontrolkirina amadebûnê bikin, lobiyê amade bikin. ji bo destpêkirinê, û hwd.

Ji bo IOC ez InversifyJS bikar tîne. Ez bi vê pirtûkxaneyê re kar dikim ezmûnek xweş heye. Bi lez û bez!

Li ser servera me çend rêz hene - me 1x1, normal/nirxand, û çend modên xwerû lê zêde kirine. Ji ber vê yekê, RoomService yekta ye ku di navbera bikarhêner û lêgerîna lîstikê de ye.

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

(Noodles kod bikin da ku ramanek bidin pêvajoyên ku bi qasî xuya dikin)

Li vir ez rêzê ji bo her yek ji modên lîstikê yên hatine bicîh kirin dest pê dikim, û di heman demê de guhê xwe didim guhertinên di "koman" de da ku rêzan rast bikim û ji hin nakokiyan dûr bixim.

Ji ber vê yekê, baş kir, min perçeyên kodê yên ku ti têkiliya wan bi mijarê re tune ye, xistiye nav xwe, û naha em rasterast derbasî hevberdanê bibin.

Ka em li dozê binêrin:

1) Bikarhêner dixwaze bilîze.

2) Ji bo ku dest bi lêgerînê bike, ew Gateway=Discord bikar tîne, ango bertekek li peyamê dide:

Em ji bo Dota 2014 hevberdanê dinivîsin

3) Ev dergeh diçe RoomService û dibêje "Bikarhênerek ji nakokî dixwaze têkeve rêzê, modê: lîstika bênirx."

4) RoomService daxwaza dergehê qebûl dike û bikarhêner (bi rastî, koma bikarhêner) dixe nav rêza xwestî.

5) Dorê her carê ku têra lîstikvanan hene ku bilîzin kontrol dike. Ger gengaz be, bûyerek biweşîne:

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

6) RoomService bi dilxweşî li hêviya vê bûyerê bi dilxweşî li her rêzê guhdarî dike. Em navnîşek lîstikvanan wekî têketinê distînin, ji wan "odeyek" virtual ava dikin, û, bê guman, bûyerek derdixin:

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) Ji ber vê yekê em gihîştin desthilatdariya "herî bilind" - pola bot. Bi gelemperî, ew bi girêdana di navbera derwazeyan de (ez nikarim fam bikim ka ew bi rûsî çiqas xweş xuya dike) û mantiqa karsaziya hevberdanê re mijûl dibe. Bot bûyerê dibihîze û ferman dide DiscordGateway ku ji hemî bikarhêneran re kontrolek amadebûnê bişîne.

Em ji bo Dota 2014 hevberdanê dinivîsin

8) Ger kesek di nav 3 hûrdeman de lîstikê red bike an qebûl neke, wê hingê em wan NA vegerînin dorê. Em her kesê din vedigerînin dorê û li bendê ne ku dîsa 10 kes bin. Ger hemî lîstikvanan lîstik qebûl kiribe, wê hingê beşa balkêş dest pê dike.

Veavakirina serverê ya taybetî

Lîstikên me bi servera Windows 2012-ê li ser VDS-ê têne mêvandar kirin. Ji vê yekê em dikarin çend encaman derxînin:

  1. Dokerek li ser tune, ku li dilê min xist
  2. Em li ser kirê xilas dikin

Kar ev e ku meriv pêvajoyek li ser VDS-ê ji VPS-ê li Linux-ê bimeşîne. Min serverek hêsan di Flask de nivîsand. Erê, ez ji Python hez nakim, lê ez dikarim çi bikim? Nivîsandina vê serverê li ser wê zûtir û hêsantir e.

Ew 3 fonksiyonan pêk tîne:

  1. Destpêkirina serverek bi veavakirinê - Hilbijartina nexşeyek, hejmara lîstikvanan ji bo destpêkirina lîstikê, û komek pêvekan. Ez ê naha li ser pêvekan binivîsim - ew çîrokek cûda ye bi lître qehweya ku bi şev bi hêsir û porê çiryayî tê tevlihev kirin.
  2. Rawestandina/ji nû ve destpêkirina serverê di rewşa girêdanên neserkeftî de, ku em tenê dikarin bi destan bi rê ve bibin.

Li vir her tişt hêsan e, mînakên kodê jî ne guncan in. 100 script line

Ji ber vê yekê, dema ku 10 kes li hev civiyan û lîstik qebûl kirin, server hate destpêkirin û her kes dilzîz bû ku bilîze, girêdanek ji bo girêdana lîstikê di peyamên taybet de hate şandin.

Em ji bo Dota 2014 hevberdanê dinivîsin

Bi tikandina li ser zencîreyê, lîstikvan bi servera lîstikê ve girêdide, û paşê ew e. Piştî ~ 25 hûrdem, "odeya" virtual ya bi lîstikvanan re tê paqij kirin.

Ez pêşiyê lêborîna xwe dixwazim ji bo nerehetiya gotarê, min demek dirêj li vir nenivîsandiye, û kodek pir zêde heye ku beşên girîng ronî bike. Noodles, bi kurtî.

Ger ez eleqeya mijarê bibînim, dê beşek duyemîn hebe - ew ê êşkenceya min bi pêvekên ji bo srcds (Pêvek serverê veqetandî), û, belkî, pergalek nirxandinê û mini-dotabuff, malperek bi statîstîkên lîstikê ve bigire.

Hin girêdan:

  1. Malpera me (îstatîstîk, lîder, rûpela dakêşana piçûk û dakêşana xerîdar)
  2. Pêşkêşkara Discord

Source: www.habr.com

Add a comment