டோட்டா 2014க்கு மேட்ச்மேக்கிங் எழுதுகிறோம்

அனைவருக்கும் வணக்கம்.

இந்த வசந்த காலத்தில் நான் ஒரு திட்டத்தைக் கண்டேன், அதில் தோழர்கள் டோட்டா 2 சர்வர் பதிப்பு 2014 ஐ எவ்வாறு இயக்குவது என்பதைக் கற்றுக்கொண்டனர், அதன்படி, அதில் விளையாடுங்கள். நான் இந்த விளையாட்டின் தீவிர ரசிகன், எனது குழந்தைப் பருவத்தில் மூழ்கிவிட இந்த அரிய வாய்ப்பை என்னால் நழுவ விட முடியவில்லை.

நான் மிகவும் ஆழமாகப் புறப்பட்டேன், மேலும் விளையாட்டின் பழைய பதிப்பான மேட்ச்மேக்கிங்கில் ஆதரிக்கப்படாத கிட்டத்தட்ட அனைத்து செயல்பாடுகளுக்கும் பொறுப்பான ஒரு டிஸ்கார்ட் போட்டை எழுதினேன்.
போட் உடன் அனைத்து புதுமைகளுக்கும் முன், லாபி கைமுறையாக உருவாக்கப்பட்டது. ஒரு செய்திக்கு 10 எதிர்வினைகளைச் சேகரித்து, ஒரு சேவையகத்தை கைமுறையாகச் சேகரித்தோம் அல்லது உள்ளூர் லாபியை ஹோஸ்ட் செய்தோம்.

டோட்டா 2014க்கு மேட்ச்மேக்கிங் எழுதுகிறோம்

ஒரு புரோகிராமராக எனது இயல்பு இவ்வளவு கையேடு வேலையைத் தாங்க முடியவில்லை, ஒரே இரவில் நான் போட்டின் எளிய பதிப்பை வரைந்தேன், இது 10 பேர் இருக்கும்போது தானாகவே சேவையகத்தை உயர்த்தியது.

நான் உடனடியாக nodejs இல் எழுத முடிவு செய்தேன், ஏனென்றால் நான் உண்மையில் பைத்தானை விரும்பவில்லை, மேலும் இந்த சூழலில் நான் மிகவும் வசதியாக உணர்கிறேன்.

டிஸ்கார்டுக்கு ஒரு போட் எழுதுவது இது எனது முதல் அனுபவம், ஆனால் அது மிகவும் எளிமையானதாக மாறியது. உத்தியோகபூர்வ 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) தேடலைத் தொடங்க, அவர் கேட்வே=டிஸ்கார்டைப் பயன்படுத்துகிறார், அதாவது, செய்திக்கு எதிர்வினையை வைக்கிறார்:

டோட்டா 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 ஐ ஆர்டர் செய்கிறது.

டோட்டா 2014க்கு மேட்ச்மேக்கிங் எழுதுகிறோம்

8) யாராவது 3 நிமிடங்களுக்குள் விளையாட்டை நிராகரித்தால் அல்லது ஏற்கவில்லை என்றால், நாங்கள் அவர்களை வரிசையில் திரும்ப மாட்டோம். நாங்கள் அனைவரையும் வரிசையில் திரும்பி, மீண்டும் 10 பேர் இருக்கும் வரை காத்திருக்கிறோம். எல்லா வீரர்களும் விளையாட்டை ஏற்றுக்கொண்டால், சுவாரஸ்யமான பகுதி தொடங்குகிறது.

அர்ப்பணிக்கப்பட்ட சர்வர் கட்டமைப்பு

எங்கள் கேம்கள் விண்டோஸ் சர்வர் 2012 உடன் VDS இல் ஹோஸ்ட் செய்யப்படுகின்றன. இதிலிருந்து நாம் பல முடிவுகளை எடுக்கலாம்:

  1. அதில் டோக்கர் இல்லை, இது என் இதயத்தை தாக்கியது
  2. வாடகையில் சேமிக்கிறோம்

லினக்ஸில் VPS இலிருந்து VDS இல் ஒரு செயல்முறையை இயக்குவதே பணி. நான் ஒரு எளிய சர்வரை பிளாஸ்கில் எழுதினேன். ஆம், எனக்கு பைத்தானைப் பிடிக்கவில்லை, ஆனால் நீங்கள் என்ன செய்யலாம்? இந்தச் சேவையகத்தை அதில் எழுதுவது வேகமாகவும் எளிதாகவும் இருக்கிறது.

இது 3 செயல்பாடுகளை செய்கிறது:

  1. உள்ளமைவுடன் சேவையகத்தைத் தொடங்குதல் - ஒரு வரைபடத்தைத் தேர்ந்தெடுப்பது, விளையாட்டைத் தொடங்குவதற்கான வீரர்களின் எண்ணிக்கை மற்றும் செருகுநிரல்களின் தொகுப்பு. நான் இப்போது செருகுநிரல்களைப் பற்றி எழுதமாட்டேன் - இது இரவில் கண்ணீர் மற்றும் கிழிந்த தலைமுடியுடன் லிட்டர் கணக்கில் காபியுடன் ஒரு வித்தியாசமான கதை.
  2. தோல்வியுற்ற இணைப்புகளின் போது சேவையகத்தை நிறுத்துதல்/மறுதொடக்கம் செய்தல், அதை நாம் கைமுறையாக மட்டுமே கையாள முடியும்.

இங்கே எல்லாம் எளிது, குறியீடு எடுத்துக்காட்டுகள் கூட பொருத்தமானவை அல்ல. 100 வரி ஸ்கிரிப்ட்

எனவே, 10 பேர் சேர்ந்து விளையாட்டை ஏற்றுக்கொண்டபோது, ​​​​சர்வர் தொடங்கப்பட்டது மற்றும் அனைவரும் விளையாட ஆர்வமாக இருந்தனர், கேமுடன் இணைக்க ஒரு இணைப்பு தனிப்பட்ட செய்திகளில் அனுப்பப்பட்டது.

டோட்டா 2014க்கு மேட்ச்மேக்கிங் எழுதுகிறோம்

இணைப்பைக் கிளிக் செய்வதன் மூலம், வீரர் கேம் சர்வருடன் இணைகிறார், பின்னர் அவ்வளவுதான். ~25 நிமிடங்களுக்குப் பிறகு, பிளேயர்களுடன் கூடிய மெய்நிகர் "அறை" அழிக்கப்பட்டது.

கட்டுரையின் மோசமான தன்மைக்கு நான் முன்கூட்டியே மன்னிப்பு கேட்டுக்கொள்கிறேன், நான் நீண்ட காலமாக இங்கு எழுதவில்லை, மேலும் முக்கியமான பகுதிகளை முன்னிலைப்படுத்த அதிக குறியீடு உள்ளது. நூடுல்ஸ், சுருக்கமாக.

நான் தலைப்பில் ஆர்வத்தைக் கண்டால், இரண்டாவது பகுதி இருக்கும் - அதில் srcds (மூல அர்ப்பணிக்கப்பட்ட சேவையகம்) க்கான செருகுநிரல்கள் மற்றும், அநேகமாக, ஒரு மதிப்பீட்டு அமைப்பு மற்றும் மினி-டோபஃப், விளையாட்டு புள்ளிவிவரங்களைக் கொண்ட தளம் ஆகியவற்றுடன் எனது வேதனை இருக்கும்.

சில இணைப்புகள்:

  1. எங்கள் வலைத்தளம் (புள்ளிவிவரங்கள், லீடர்போர்டு, சிறிய இறங்கும் பக்கம் மற்றும் கிளையன்ட் பதிவிறக்கம்)
  2. டிஸ்கார்ட் சர்வர்

ஆதாரம்: www.habr.com

கருத்தைச் சேர்