ÈÈѪ´«ÆæRunGateÔ´´úÂë·ÖÎö±Ê¼Ç£ºÍø¹ØSocketÄ£ÐÍÓë·â°üת·¢ÊµÂ¼

À´Ô´£º ×÷Õߣº µã»÷£º
RunGate ÔÚ´«Ææ·þÎñ¶ËÌåϵÀï¶ÔÓ¦ÓÎÏ·ÔËÐÐÍø¹Ø£¨³£¼ûĿ¼ MirServer\RunGate\RunGate.exe£¬¶ÔÍâ¶Ë¿Ú 7200£¬¶ÔÄÚÁ¬ M2Server µÄ 5000 ͨÐſڣ©£¬Ö°ÔðÊdzнÓÒѽøÈëÓÎÏ·½×¶ÎµÄ¿Í»§¶Ë TCP Á¬½Ó£¬°Ñ²Ù×÷Ö¸Áî£¨ÒÆ¶¯¡¢¹¥»÷¡¢Ê°È¡¡¢½»Òס¢¼¼ÄÜ£©×ª·¢¸ø M2£¬ÔÙ°Ñ M2 »Ø°ü±àÂëºóËͻؿͻ§¶Ë£»Õ˺ÅÑéÖ¤×ß LoginGate£¨7000→LoginSvr 5500£©£¬½ÇÉ«´´½¨Ñ¡Ôñ×ß SelGate / SelChrGate£¨7100→DBSvr 5100£©£¬RunGate Ö»¹Ü“½øÍ¼ÒÔºó”µÄÒµÎñÁ÷£¬²»²ÎÓëÕ˺ÅÉúÃüÖÜÆÚ ¡£

Ô´ÂëÐÎ̬·ÖÁ½Ö§£ºÔçÆÚ¹Ù·½Ð¹Â¶°æÊÇ Delphi£¨Pascal£©Ð´µÄ RunGate.exe£¬µ¥ÔªÎļþº¬ Main.pas¡¢GateShare.pas¡¢HUtil32.pas¡¢IPaddrFilter.pas¡¢OnLineHum.pas¡¢GameSpeed.pas£»ÏÖ´úÖØ¹¹°æ£¨OpenMir2¡¢mirbeta£©ÊÇ C# µÄ GameGate ¹¤³Ì£¬Ä¿Â¼ src/GameGate/GameGate.csproj£¬ÅäÖà appsettings.json£¬¼àÌý 7000/7100/7200 ÊÓ·ÖÖ§ÃüÃû¶ø¶¨ ¡£

Delphi Ô­°æºËÐĽṹ£ºÈý¸ö Socket ¶ÔÏó——ClientSocket£¨¼àê¿¿Í»§¶Ë 7200£©¡¢M2Socket£¨Á¬ M2Server ÄÚ²¿¿Ú£©¡¢ConsoleSocket£¨Á¬¿ØÖÆÌ¨/¹ÜÀíÆ÷·¢±£»î°ü£¬ÊÖ¹¤¶ÀÁ¢Æô¶¯Ê±¿ÉÎÞ£¬´¿Îª¹ÜÀí¶Ë̽»î£©¡£Êµ¼ÊÒµÎñÖ»¿¿Ç°Á½¸ö£¬µäÐÍÉú²úÕß-Ïû·ÑÕßÄ£ÐÍ£º¿Í»§¶ËÊÕ°ü → УÑé → Èë ReciveMsgList£»Timer ¶¨Ê±´ÓÁбíÈ¡ÏûÏ¢ → ·â TMsgHeader → ·¢ M2£»M2 »Ø°ü → °´ Socket Ë÷Òý²é»á»° → ±àÂëÏÂÐÐ ¡£

»á»°¹ÜÀí²»ÔÚ¶ÑÉ϶¯Ì¬ new£¬¶øÊDZàÒëÆÚ³£Á¿¶¨³¤Õ»Êý×é TSessionArr[MAXSESSION]£¬½á¹¹Ì庬 dwConnTime¡¢nPacketSize¡¢dwLastMoveTick¡¢dwLastCommTick¡¢nSocket¡¢nUserIdx µÈ£»ÐÂÁ¬½Ó½øÀ´É¨Î´ÓòÛλ³õʼ»¯£¬¶Ï¿ªÇå²Û¡£¶¨³¤Êý×é»»À´ O(1) Ë÷Òýµ«ÉÏÏÞÓ²¶¥£¬³¬Ô±Ö±½Ó¾ÜÁ¬£¬ÕâÊÇÀÏÍø¹Ø²¢·¢Éϲ»È¥µÄ¸ùÒò ¡£

·â°üÍ· TMsgHeader£¨packed record£¬Delphi Àï packed ·À¶ÔÆëÌî³ä£©£º

dwCode: LongWord; // ±êʶÂë Èç $AA55 »òÒýÇæÔ¼¶¨Ä§·¨Êý
nSocket: Integer; // M2 ²à»Ø°ü¶¨Î»¿Í»§¶ËÓõÄÍø¹ØÄÚ Socket ¾ä±ú
wGSocketIdx: Word; // Íø¹Ø»á»°Ë÷Òý
wIdent: Word; // ÏûÏ¢ÀàÐÍ CM_MOVE/CM_ATTACK/SM_UPDATE µÈ
wUserListIndex: Integer;
nLength: Integer; // ºóÐø body ³¤¶È

¿Í»§¶ËÉÏÐÐÔ­°ü¾­ Gate ¼ÓÍ·±äÄÚ²¿¸ñʽ·¢¸ø M2£»M2 ÏÂÐаü Gate °´ wGSocketIdx/nSocket ·´²é»á»°£¬°þÍ·£¬×ö EnDecode£¨XOR/±íÖû»£¬Àϰæ½âÃÜʵ¼ÊÂäÔÚ M2£¬Gate Ö»×ö͸´«Óë¼òµ¥Ð£Ñ飬ÕâÊǺóÀ´±»Ú¸²¡µÄÒ»µã£©ºóд»Ø¿Í»§¶Ë ¡£

Ö÷Ñ­»·²»ÊǶÀÁ¢Ïß³ÌÅÜ recv/send£¬¶øÊÇ¿¿ TTimer ÖÜÆÚ´¥·¢£¨Èç 50ms Ò»´Î£©É¨ ReciveMsgList Óë SendBuf£¬ÅäºÏ WSAEventSelect »ò select Ä£ÐÍÊÕ·¢°ü¡£ÓŵãÊÇÎÞËø¼òµ¥£¬È±µãÊÇ Timer ¾«¶ÈÓë½çÃæÏûÏ¢¶ÓÁа󶨣¬¿Í»§¶ËÁ¿´óʱÑÓ³Ù¶¶¶¯Ã÷ÏÔ£»ÉçÇø¸Ä·¨Ò»°ãÊDzð IOCP / ¶ÀÁ¢ÊÕ·¢Ïß³Ì + ÎÞËø»·ÐζÓÁÐÌæ´ú Timer ¡£

M2 ²à¶ÔÓ¦½á¹¹£¨C++ °æ¿ò¼Ü²Î¿¼£©£ºGameServer ά»¤ m_RunGateMap<SOCKET, CRunGate*>£¬RunGate Á¬ÉÏÀ´ accept ºó new CRunGate ½Ó¹Ü£»CRunGate ÄÚά»¤ m_CPlayerMap<SOCKET, CPlayer*> Óë m_strRecvBuf£¬ProcessData() ´Ó»º³åÇÐÍêÕû°ü → ParsePkg() → CPacketParser::ProcessPkgFromClient(pPlayer, data, len) Âäµ½ÓÎÏ·Âß¼­£»¿Í»§¶ËÉÏÏß RunGate ·¢Í¨Öª½¨ CPlayer£¬¶ÏÏß·¢Í¨ÖªÉ¾¶ÔÏó£¬M2 ²»Ö±½Ó³Ö¿Í»§¶Ë TCP ¡£

ÅäÖÃÎļþ RunGate.ini / MirGate.ini ¹Ø¼ü×ֶΣºServerAddr£¨M2 IP£¬±¾µØ 127.0.0.1£©¡¢ServerPort£¨ÄÚ²¿Í¨ÐÅ¿Ú 5000£©¡¢GatePort£¨¶ÔÍâ 7200£©¡¢MaxSession¡¢BlockIPList.txt£¨ºÚÃûµ¥£©¡¢WordFilter.txt£¨ÁÄÌì¹ýÂË£©¡¢KeepAliveTick£¨±£»î¼ä¸ô£©¡£C# °æ¸Ä appsettings.json µÄ UpstreamGameSvr¡¢ListenPort¡¢AntiSpeed¡¢PacketLimit ¡£

¸¨ÖúÄ£¿é£ºIPaddrFilter.pas ×ö IP ºÚÃûµ¥/°×Ãûµ¥ÓëÁ¬½ÓƵÂÊÏÞÖÆ£»GameSpeed.pas ͳ¼Æ¿Í»§¶ËÒÆ¶¯¼ä¸ôÅж¨±äËÙÆ÷£»OnLineHum.pas ά»¤ÔÚÏßÈËÊýÓë»á»°ÁÐ±í¹©¿ØÖÆÌ¨¶Á£»GateShare.pas ·ÅÈ«¾Ö³£Á¿¡¢TMsgHeader ¶¨Òå¡¢EnDecode ±í¡¢ÈÕÖ¾ºê¡£EDoceTool ÊÇÔËÐÐÆÚÈÕÖ¾Â䵨£¬MakeKey Éú³ÉͨÐÅÃÜÔ¿£¬OLÑéÖ¤Æ÷×öÔÚÏߺϷ¨ÐÔ̽»î ¡£

Æô¶¯Ë³ÐòÓ²Ô¼Êø£ºDBServer → LoginSvr → M2Server£¨Mir200£© → LoginGate → SelGate → RunGate£¬×îºóÆðµÇ¼Æ÷£»Gate Á¬²»ÉÏÉÏÓλá´òÈÕÖ¾²¢ÖÜÆÚÖØÁ¬£¬²»»á×ÔÍË ¡£

Êý¾ÝÁ÷Ò»¾ä»°´®£º¿Í»§¶Ë TCP 7200 → RunGate.ClientSocket → УÑé/Èë¶Ó → TMsgHeader ·â×° → M2Socket → M2Server ½âÍ·ÅÜÂß¼­ → »Ø°ü´ø nSocket/wGSocketIdx → RunGate ·´²é»á»° → ±àÂëÏÂÐÐ → ¿Í»§¶Ë¡£µÇ¼ǰÁ´£ºClient → 7000 LoginGate → 5500 LoginSvr → 7100 SelGate → 5100 DBSvr → Ï·¢½ÇÉ«Áбí → Ñ¡¶¨ºóÓÉ M2 ÊÚȨ RunGate ½¨»á»° → Çе½ 7200 Ö÷ͨÐÅ ¡£

¶ÁÔ´Â뽨Òé˳Ðò£ºGateShare.pas£¨½á¹¹¶¨Ò壩→ Main.pas£¨Socket ʼþ¡¢Timer£©→ Session Êý×é¹ÜÀí → ReciveMsgList/SendList → TMsgHeader ·â×°²ð½â → M2Socket ·¢ËÍ → Console ±£»î¡£Delphi °æ±äÁ¿Ãû±£Áô dw/n/w ÐÙÑÀÀûǰ׺£¬C# °æ¿´ ChannelMessageHandler.cs Óë GateConnection.cs ¶ÔÕÕ¿´×î¿ì¡£