మేము Dota 2014 కోసం మ్యాచ్ మేకింగ్ వ్రాస్తున్నాము

అందరికీ నమస్కారం.

ఈ వసంతకాలంలో నేను ఒక ప్రాజెక్ట్‌ను చూశాను, దీనిలో అబ్బాయిలు Dota 2 సర్వర్ వెర్షన్ 2014ని ఎలా అమలు చేయాలో నేర్చుకున్నారు మరియు తదనుగుణంగా దానిపై ఆడతారు. నేను ఈ గేమ్‌కి పెద్ద అభిమానిని, నా బాల్యంలో లీనమయ్యే ఈ అపూర్వ అవకాశాన్ని వదులుకోలేకపోయాను.

నేను చాలా లోతుగా పావురం చేసాను మరియు గేమ్ యొక్క పాత వెర్షన్, మ్యాచ్ మేకింగ్‌లో సపోర్ట్ చేయని దాదాపు అన్ని కార్యాచరణలకు బాధ్యత వహించే డిస్కార్డ్ బాట్‌ను నేను వ్రాసాను.
బోట్‌తో అన్ని ఆవిష్కరణలకు ముందు, లాబీ మానవీయంగా సృష్టించబడింది. మేము సందేశానికి 10 ప్రతిచర్యలను సేకరించి, సర్వర్‌ను మాన్యువల్‌గా సమీకరించాము లేదా స్థానిక లాబీని హోస్ట్ చేసాము.

మేము Dota 2014 కోసం మ్యాచ్ మేకింగ్ వ్రాస్తున్నాము

ప్రోగ్రామర్‌గా నా స్వభావం చాలా మాన్యువల్ పనిని తట్టుకోలేకపోయింది మరియు రాత్రిపూట నేను బాట్ యొక్క సరళమైన సంస్కరణను గీసాను, ఇది 10 మంది వ్యక్తులు ఉన్నప్పుడు స్వయంచాలకంగా సర్వర్‌ను పెంచింది.

నేను వెంటనే నోడెజ్‌లలో వ్రాయాలని నిర్ణయించుకున్నాను, ఎందుకంటే నేను నిజంగా పైథాన్‌ను ఇష్టపడను మరియు ఈ వాతావరణంలో నేను మరింత సుఖంగా ఉన్నాను.

డిస్కార్డ్ కోసం బాట్ రాయడం ఇది నా మొదటి అనుభవం, కానీ ఇది చాలా సులభం. అధికారిక 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, సాధారణ/రేటెడ్ మరియు కొన్ని అనుకూల మోడ్‌లను జోడించాము. అందువల్ల, వినియోగదారు మరియు గేమ్ శోధన మధ్య ఒకే టన్ రూమ్ సర్వీస్ ఉంది.

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ని ఉపయోగిస్తాడు, అనగా, సందేశానికి ప్రతిస్పందనను ఉంచుతాడు:

మేము Dota 2014 కోసం మ్యాచ్ మేకింగ్ వ్రాస్తున్నాము

3) ఈ గేట్‌వే RoomServiceకి వెళ్లి "అసమ్మతి నుండి వినియోగదారు క్యూ, మోడ్: అన్‌రేట్ చేయని గేమ్‌లోకి ప్రవేశించాలనుకుంటున్నారు" అని చెబుతుంది.

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ని ఆదేశించింది.

మేము Dota 2014 కోసం మ్యాచ్ మేకింగ్ వ్రాస్తున్నాము

8) ఎవరైనా 3 నిమిషాలలోపు గేమ్‌ను తిరస్కరిస్తే లేదా అంగీకరించకపోతే, మేము వారిని క్యూలో తిరిగి ఇవ్వము. మేము అందరినీ తిరిగి క్యూలో ఉంచుతాము మరియు మళ్లీ 10 మంది వ్యక్తులు వచ్చే వరకు వేచి ఉంటాము. ఆటగాళ్ళందరూ ఆటను అంగీకరించినట్లయితే, ఆసక్తికరమైన భాగం ప్రారంభమవుతుంది.

అంకితమైన సర్వర్ కాన్ఫిగరేషన్

Windows సర్వర్ 2012తో VDSలో మా ఆటలు హోస్ట్ చేయబడ్డాయి. దీని నుండి మనం అనేక తీర్మానాలను తీసుకోవచ్చు:

  1. దానిపై డాకర్ లేడు, అది నా హృదయాన్ని తాకింది
  2. మేము అద్దెపై ఆదా చేస్తాము

Linuxలో VPS నుండి VDSలో ఒక ప్రక్రియను అమలు చేయడమే పని. నేను ఫ్లాస్క్‌లో సాధారణ సర్వర్‌ని వ్రాసాను. అవును, నాకు పైథాన్ ఇష్టం లేదు, కానీ మీరు ఏమి చేయగలరు? ఈ సర్వర్‌ని దానిపై వ్రాయడం వేగంగా మరియు సులభంగా ఉంటుంది.

ఇది 3 విధులు నిర్వహిస్తుంది:

  1. కాన్ఫిగరేషన్‌తో సర్వర్‌ను ప్రారంభించడం - మ్యాప్‌ను ఎంచుకోవడం, గేమ్‌ను ప్రారంభించాల్సిన ఆటగాళ్ల సంఖ్య మరియు ప్లగిన్‌ల సెట్. నేను ఇప్పుడు ప్లగిన్‌ల గురించి వ్రాయను - అది రాత్రిపూట కన్నీళ్లు మరియు చిరిగిన జుట్టుతో కలిపి లీటరు కాఫీతో విభిన్నమైన కథ.
  2. విజయవంతం కాని కనెక్షన్‌ల విషయంలో సర్వర్‌ని ఆపడం/పునఃప్రారంభించడం, మేము మాన్యువల్‌గా మాత్రమే నిర్వహించగలము.

ఇక్కడ ప్రతిదీ చాలా సులభం, కోడ్ ఉదాహరణలు కూడా తగినవి కావు. 100 లైన్ స్క్రిప్ట్

కాబట్టి, 10 మంది వ్యక్తులు ఒకచోట చేరి, గేమ్‌ను అంగీకరించినప్పుడు, సర్వర్ ప్రారంభించబడింది మరియు ప్రతి ఒక్కరూ ఆడటానికి ఆసక్తిగా ఉన్నారు, గేమ్‌కు కనెక్ట్ అయ్యే లింక్ ప్రైవేట్ సందేశాలలో పంపబడింది.

మేము Dota 2014 కోసం మ్యాచ్ మేకింగ్ వ్రాస్తున్నాము

లింక్‌పై క్లిక్ చేయడం ద్వారా, ఆటగాడు గేమ్ సర్వర్‌కి కనెక్ట్ అవుతాడు, ఆపై అంతే. ~25 నిమిషాల తర్వాత, ప్లేయర్‌లతో కూడిన వర్చువల్ “గది” క్లియర్ చేయబడింది.

వ్యాసం యొక్క ఇబ్బందికి నేను ముందుగానే క్షమాపణలు కోరుతున్నాను, నేను చాలా కాలం పాటు ఇక్కడ వ్రాయలేదు మరియు ముఖ్యమైన విభాగాలను హైలైట్ చేయడానికి చాలా కోడ్ ఉంది. నూడుల్స్, సంక్షిప్తంగా.

నేను టాపిక్‌పై ఆసక్తిని చూసినట్లయితే, రెండవ భాగం ఉంటుంది - ఇది srcds (మూలం అంకితమైన సర్వర్) కోసం ప్లగిన్‌లతో నా వేదనను కలిగి ఉంటుంది మరియు బహుశా రేటింగ్ సిస్టమ్ మరియు మినీ-డోటాబఫ్, గేమ్ గణాంకాలతో కూడిన సైట్.

కొన్ని లింకులు:

  1. మా వెబ్‌సైట్ (గణాంకాలు, లీడర్‌బోర్డ్, చిన్న ల్యాండింగ్ పేజీ మరియు క్లయింట్ డౌన్‌లోడ్)
  2. డిస్కార్డ్ సర్వర్

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి