-
-
Flux d'Activité
-
0
Renouveau
RENOUVEAU — Un nouveau projet Metin2 est en développement Metin2 a marqué beaucoup d’entre nous. Ses royaumes. Ses Metins. Ses guerres. Ses classes. Ses musiques. Ses heures passées à essayer d’obtenir ce foutu +9. Mais avec les années, une question nous est venue : Et si Metin2 avait continué à évoluer autrement ? C’est de cette idée qu’est né RENOUVEAU. Renouveau n’a pas pour objectif de transformer Metin2 en un autre MMORPG. Notre volonté est au contraire de conserver son identité, son ambiance et ce qui fait son charme… tout en repensant profondément certains systèmes devenus vieillissants. Le projet est actuellement en développement. Nous travaillons notamment sur : une progression des personnages entièrement repensée un véritable système de quêtes et d’histoire une interface modernisée et plus agréable à utiliser une amélioration progressive de l’environnement et du rendu du jeu des classes pensées pour rester viables aussi bien en PvE qu’en PvP de nouveaux choix de builds et de spécialisations à haut niveau de nombreux systèmes historiques de Metin2 modernisés Et ce n’est qu’une petite partie de ce qui est prévu. Nous ne voulons pas annoncer une date d’ouverture prématurément. Nous préférons prendre le temps de construire quelque chose de solide, tester nos idées et vous montrer progressivement l’évolution réelle du projet. Dans les prochaines semaines, nous commencerons donc à publier des DevLogs, des captures du développement et la présentation des différents systèmes de Renouveau. Certaines choses sont déjà fonctionnelles. D’autres sont encore au stade de conception. Et beaucoup restent encore à découvrir. RENOUVEAU Nous ne voulons pas remplacer Metin2. Nous voulons imaginer ce qu’il aurait pu devenir. Le développement ne fait que commencer. Image renouveau -
0
OldEraMT2 recrute – la bêta ouverte est en cours
Bonjour à tous, OldEraMT2 est maintenant en bêta ouverte. Le serveur, le client avec un lanceur pour Windows, Mac et Linux, le wiki en jeu et le marché tournent, le jeu et le site existent en huit langues. Il nous manque maintenant des personnes pour la suite. Le concept en bref Metin2 classique jusqu'au niveau 99, 4 classes, 3 royaumes Taux de base à 100 %, pas de taux d'événement. Jusqu'à ta première Ascension, tu farmes à 1,5x Ascension : au niveau 99, tu peux revenir au niveau 1 jusqu'à trois fois. Tu obtiens un sceau, un rang et plus de place dans l'inventaire et l'entrepôt, mais aucune valeur de combat, et le farm devient plus lent Drops comme en 2012 : l'équipement tombe uniquement en +0, les armes de niveau 75 viennent seulement du coffre du dernier boss de la Tour des Démons Hub en jeu (F5) : wiki, marché avec enchères et demandes d'achat, contacts, support Nous cherchons des testeurs qui signalent les bugs proprement des maîtres du jeu et du support (Discord et en jeu) de l'aide pour la communauté : Discord, forums, événements des francophones natifs pour relire les textes du jeu des quêtes et des événements du design et du client (interface, graphismes) Tu connais Metin2, tu as du temps régulièrement et tu es sur Discord ? Il faut parler anglais ou allemand pour l'équipe. Intéressé ? Envoie-moi un court message sur Discord : ce que tu aimerais faire, les langues que tu parles et le temps que tu as à peu près. Discord : [Hidden Content] Site : [Hidden Content] SA_Dev_Null -
0
OldEraMT2 | Classique 2009 Oldschool | Niveau 99 | 7 langues | Sans pay2win | Bêta ouverte
Le serveur est ouvert aux joueurs de la bêta dès maintenant – télécharge, inscris-toi et commence à jouer aujourd’hui. Chaque nouveau membre nous fait plaisir ! "> OldEraMT2 – classique 2009 sans pay2win · bêta-testeurs et équipe recherchés NIVEAU 99 · 4 CLASSES · 3 ROYAUMES · 7 LANGUES Présentation bêta – Ceci est la présentation de la bêta. La grande présentation suivra après des tests bêta approfondis – avec tout ce que vous nous aurez remonté d’ici là. Présentation · Équipement · Téléchargement · Discord · Inscription Par SA_Dev_Null, l’administrateur — Pourquoi OldEra existe. Il y a une quinzaine d’années, mon premier serveur Metin2 tournait dans une chambre d’enfant – via Hamachi, pour une poignée d’amis. Depuis, j’ai joué à Metin2 pendant des années, sur de grands et de petits serveurs, et j’ai toujours vu la même chose : à un moment, c’est le portefeuille qui décide, pas le temps de jeu. Le rêve est resté : un serveur qui se sent comme en 2009, sans pay2win – et que je ne conçois pas seul à un bureau, mais avec les gens qui y jouent. Ce qui est bon reste. Ce qui coince change. Ouvertement et de façon traçable. Ces derniers mois, c’est devenu OldEra : serveur, client, launcher, un wiki dans le jeu, le Hub, un marché des joueurs qui fonctionne aussi hors ligne et une bêta en sept langues. Beaucoup est fini, certaines choses restent brutes. C’est exactement à ça que sert la bêta. Si tu connais Metin2 et que tu veux dire honnêtement ce qui sonne juste et ce qui ne l’est pas – tu es au bon endroit. Et si tu veux plus que tester : nous cherchons des gens pour l’équipe. Tests, communauté, traductions, quêtes, client ou design. L’épreuve de courage – à mains nues. Tout le monde commence pareil : cinq chiens sauvages, sans arme. Tant que tu combats sans arme, tes poings frappent très fort. Ensuite tu reçois l’équipement de départ de ta classe. » Voir en interactif (avec les infobulles du jeu) Aucune arme n’est pareille. Épée de pleine lune, Épée empoisonnée et compagnie fonctionnent comme avant : chacune reçoit au drop son propre jet de dégâts moyens (DM) et dégâts de compétence (DC). Plus de DM signifie moins de DC – et inversement. Lance toi-même : la même formule que sur le serveur. Exemple sur l’image : 30 % DM / −12 % DC Ce vers quoi tu travailles. Les armes dont tout le monde parle – et comment les obtenir. Coûts, chances et matériaux viennent directement des tables du jeu. Une arme de niveau 65 en +9 ? Le forgeron la transforme en arme de niveau 80 – 100 % de réussite, avec des parchemins de bénédiction et un traité d’escrime. Dès le niveau 75, la Faucheuse t’attend au 9e étage de la Tour des Démons. Son coffre contient les armes de niveau 70 de toutes les classes – avec la vraie chance de chacune. » Voir en interactif (avec les infobulles du jeu) Des petites choses qui changent tout. Ce qui rend le quotidien dans OldEra plus agréable – en vraies fenêtres du jeu. » Voir en interactif (avec les infobulles du jeu) Ce qui existe déjà Un wiki dans le jeu avec les sources des objets et un guide pour ta prochaine étape Le Hub : recherche, commerce, wiki, classements et liste de souhaits dans un seul menu Un marché des joueurs qui continue hors ligne – avec courrier commercial Messager avec amis, discussions de groupe, courrier et tickets directs à l’équipe Chaque arme et armure avec les vraies valeurs sur le site – infobulle comme dans le jeu Pas de pay2win – les paiements en argent réel sont désactivés dans la bêta Classique 2009 : niveau 1–99, trois royaumes, quatre classes Les changements se font avec la communauté Sept langues, téléchargement sans mot de passe Qui nous cherchons Des bêta-testeurs qui disent honnêtement ce qui sonne juste et ce qui ne l’est pas. Et des gens pour l’équipe : tests, communauté, traductions, quêtes, client ou design. Dis-nous en quelques mots ce que tu veux faire, quelles langues tu parles et combien de temps tu as à peu près. Bêta ouverte depuis le 23.09.2026, pas encore de date de lancement officielle. Téléchargement et inscription ouverts. Chaque image est une vraie fenêtre du jeu – générée directement depuis le client, sans montage. Elles se mettent à jour à chaque patch. Présentation · Équipement · Téléchargement · Discord · Inscription -
-
6
problème de connexion à mon serveur local (je suis débutant dans ce genre d'entreprise )
Salut, si ton serveur démarre correctement mais que ton client reste sur « erreur lors de la connexion au serveur », je regarderais d’abord la partie IP/ports. Si ton serveur tourne dans une VM, vérifie que l’IP renseignée dans ton serverinfo.py correspond bien à l’IP de la VM et pas forcément à 127.0.0.1. Vérifie aussi que les ports indiqués côté client correspondent bien à ceux de tes CONFIG (auth + channels). Regarde également les syserr/syslog du serveur au moment où tu essayes de te connecter, ainsi que le syserr du client, ça permettra de voir si la connexion arrive jusqu’au serveur ou non. Si tu peux, poste ton serverinfo.py, les ports de tes CONFIG et les dernières lignes du syserr après une tentative de connexion. On pourra sûrement repérer rapidement ce qui bloque. -
2
problème de lancement serveur
Salut, d’après ta capture les connexions MySQL ont l’air de fonctionner : PLAYER, ACCOUNT, COMMON et HOTBACKUP passent en Success. Donc à première vue ce n’est pas ton IP qui empêche les channels de démarrer. Le process semble plutôt s’arrêter juste après, au moment du chargement des protos, puisqu’on voit item_proto_test.txt juste avant le retour au shell. Regarde surtout le fichier syserr du channel qui ne démarre pas, par exemple dans le dossier channel1/core1 ou équivalent, et poste les dernières lignes. Vérifie aussi que item_proto_test.txt est bien présent, au bon emplacement et compatible avec tes sources/files 2016. Si les files et les sources ne correspondent pas exactement, une différence dans le format de l’item_proto peut aussi faire fermer le game au démarrage. Envoie le syserr, ce sera beaucoup plus simple pour identifier l’erreur exacte. -
26
Metin2 40250 / 2014 Serverfiles + Client + SRC [ 15 Langues ]
Merci beaucoup pour les files -
9
-
0
[PVM/PVP] ATLAX2 - EASY PLAY
ATLAX L’ESSENCE CLASSIQUE DE METIN2, PRÉPARÉE POUR UNE NOUVELLE GÉNÉRATION. NIVEAU 120 • CHAMPION 30 • YOHARA INTERNATIONAL • SANS PAY-TO-WIN ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SERVEUR EN LIGNE Ouvert officiellement depuis le 31 juillet 2026 SITE WEB https://atlax2.com/ PRÉSENTATION COMPLÈTE https://welcome.atlax2.com/ DISCORD https://discord.com/invite/rd62BJC6Yj ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BIENVENUE SUR ATLAX ATLAX a été conçu pour offrir une expérience Metin2 équilibrée, authentique et durable, inspirée de l’essence classique du jeu tout en profitant des améliorations modernes. Que vous soyez un ancien joueur de Metin2 ou que vous recherchiez simplement une nouvelle aventure à long terme, ATLAX vous propose une progression basée sur votre activité, votre connaissance du jeu et votre investissement. Aucun Pay-to-Win. Commencez votre aventure au niveau 1, progressez jusqu’au niveau 120, débloquez le Champion 30 et découvrez les terres de Yohara. De nouveaux systèmes, des défis élémentaires, la Volonté Sung Ma et un véritable contenu end-game vous attendent. GUERRIER • NINJA • SURA • CHAMANE • LYCAN ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SERVEUR INTERNATIONAL ATLAX accueille des joueurs du monde entier. Português • English • Français • Español Deutsch • Italiano • Türkçe ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ COMMENCEZ VOTRE AVENTURE Chaque joueur commence avec un équipement équilibré permettant de rendre le début du jeu plus agréable sans supprimer le plaisir de la progression. ÉQUIPEMENT DE DÉPART • Arme niveau 1 +9 • Armure, accessoires et chaussures +9 • Cheval armé — Niveau 11 • Monture de départ • Familier de départ • Costume et coiffure temporaires • Coffre d’apprenti • Langues en M1 • Appel du cheval au niveau 10 PROGRESSION DÉBUTANT AMÉLIORÉE • Armes gratuites tous les 10 niveaux jusqu’au niveau 70 • Missions de chasse améliorées • Objectifs plus clairs • Meilleures récompenses • Progression plus fluide • Moins d’attente inutile ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ PROGRESSION & SYSTÈMES MISSIONS DU BIOLOGISTE Les missions du Biologiste vous accompagnent du niveau 30 jusqu’au Champion 30. Elles permettent d’obtenir des bonus permanents importants : • Valeur d’attaque et Défense • PV maximum • Dégâts et Résistance contre les Boss • Force contre les pierres Metin • Dégâts de compétence • Dégâts moyens • Résistance contre toutes les classes • Puissance élémentaire • Valeurs de Volonté Sung Ma SYSTÈMES PRINCIPAUX • Progression du cheval jusqu’au niveau 40 • 6e et 7e bonus • Alchimie des Pierres-Dragon améliorée • Raffinage automatique • Talismans et puissance élémentaire • Système de titres • Effets de set permanents • Reliques d’âme • Familiers évolutifs • Système Aura • Écharpes d’épaule • Pierres spirituelles pour chaussures • World Boss toutes les 8 heures ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CONFORT DE JEU ATLAX conserve l’identité de Metin2 tout en réduisant les tâches répétitives grâce à plusieurs fonctionnalités modernes. • Inventaire avancé divisé par catégories • Barre de compétences étendue • Auto-Chasse configurable • Filtre de butin • Système de courrier • Recherche de boutiques intégrée • Map de commerce réorganisée • Aperçu des coffres • Ouverture multiple de coffres • Vente rapide de plusieurs objets • Démantèlement rapide d’équipement • Anti-EXP • Informations détaillées des donjons • Aperçu direct des drops • Wiki intégré • Aperçu 3D des costumes, familiers et montures • Taille du texte ajustable • Code PIN de sécurité RACCOURCIS F8 — Biologiste F9 — Wiki K — Auto-Chasse P — Familier ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ MAPS & EXPLORATION Votre aventure commence dans les terres classiques de Metin2 avant de vous conduire vers des régions beaucoup plus dangereuses. ANCIEN CONTINENT Seungryong Valley • Temple Hwang • Mont Sohan Désert Yongbi • Doyyumhwan • Forêt Fantôme Forêt Rouge • Grottes des Araignées • Grotte de l’Exil NIVEAUX 90 — 120 Cape Dragon Fire • Baie de Nephrite Montagnes du Tonnerre • Falaise Gautama Temple Ochao • Forêt Enchantée MONDE ÉLÉMENTAIRE Domaine Élémentaire de la Foudre Domaine Élémentaire du Feu Domaine Élémentaire des Ténèbres Plateau des Forces Anciennes ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ YOHARA Atteindre le système Champion ouvre un tout nouveau chapitre de votre aventure. Explorez Yohara, développez votre Volonté Sung Ma et préparez-vous à affronter certains des contenus les plus avancés d’ATLAX. • Forteresse Abandonnée • Plaine de Dong Gwang • Terres Désolées de Seo Gwang • Gouffre de Nam Gwang • Passage de Yilad • Ravin du Vent du Nord • Gorge des Âmes • Temple du Serpent De nouvelles maps et de nouveaux contenus Yohara continueront d’être ajoutés au fur et à mesure de l’évolution d’ATLAX. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ DONJONS ZODIAQUE Niveau 20+ TOUR DES DÉMONS Niveau 40+ ANTRE DE LA BARONNE ARAIGNÉE Niveau 50+ CATACOMBES DU DIABLE Niveau 75+ DRAGON BERAN-SETAOU Niveau 75+ REPAIRE DE MELEY Niveau 75+ / 90+ DÉFENSE DU NAVIRE Niveau 90+ EREBUS Niveau 95+ FORTERESSE DU DRAGON ROUGE Niveau 100+ TOUR DE NEMERE Niveau 100+ PLATEAU DE L’ILLUSION Niveau 110+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ FAILLES TEMPORELLES & ÉVEIL À partir du niveau 110, des défis familiers reviennent dans des versions plus difficiles avec des ennemis renforcés et des récompenses avancées. DONJONS DE YOHARA • Tour Sung Mahi • Profondeurs du Vent du Nord • Temple du Serpent ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CONTENU DE GUILDE Rassemblez les membres de votre guilde et entrez dans le PALAIS DU ROI DRAGON À mesure que votre guilde progresse, de nouveaux Boss deviennent disponibles. AKZADUR Guilde Niveau 21+ NAFAROTH Guilde Niveau 24+ EXEDYAR Guilde Niveau 27+ RUILITH Guilde Niveau 30+ TYOLDURAN Guilde Niveau 35+ Préparation, coordination et maîtrise des puissances élémentaires seront indispensables. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ÉVÉNEMENTS & ACTIVITÉS AU MOINS UN ÉVÉNEMENT ACTIF CHAQUE JOUR • World Boss • Jeu de cartes Okey • Attrapez le Roi • Yut Nori • Trio de Monstres • Duel du Voyant • Rituel du Sang • Puzzle de Pêche • Flower Power • Boss Reaper • Chasse au Trésor • Fièvre des Metins • Otherworld • Événements de Noël • Événements de Pâques • Événements du Ramadan • Tournois PvP • Événements communautaires Tous les événements programmés sont visibles directement dans le Calendrier d’Événements en jeu. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ UN SERVEUR CONSTRUIT AVEC SA COMMUNAUTÉ ATLAX est conçu comme un projet à long terme. De nouveaux contenus, systèmes, événements et améliorations seront régulièrement ajoutés. Des sondages seront également organisés afin que les suggestions et les retours de la communauté participent réellement à l’évolution du serveur. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ÊTES-VOUS PRÊT À COMMENCER ? ATLAX EST EN LIGNE SITE WEB https://atlax2.com/ PRÉSENTATION https://welcome.atlax2.com/ REJOINDRE LE DISCORD https://discord.com/invite/rd62BJC6Yj ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ATLAX LA LÉGENDE COMMENCE AVEC VOUS.
-

Question
CHAPPiE 6
Bonsoir, en voulant compiler mon game, 3 erreurs m'empêchent de continuer.
Après avoir vérifié les lignes ressorties, je n'aperçois aucune erreur!
De plus, je n'ai pas touché une fois à ce fichier lors de l'implantation du système...
main.cpp:728: error: a function-definition is not allowed here before '{' token main.cpp:738: error: a function-definition is not allowed here before '{' token' main.cpp:1166: error: expected `}' at end of inputEt voici le main.cpp
#include "stdafx.h" #include "constants.h" #include "config.h" #include "event.h" #include "minilzo.h" #include "packet.h" #include "desc_manager.h" #include "item_manager.h" #include "char.h" #include "char_manager.h" #include "mob_manager.h" #include "motion.h" #include "sectree_manager.h" #include "shop_manager.h" #include "regen.h" #include "text_file_loader.h" #include "skill.h" #include "pvp.h" #include "party.h" #include "questmanager.h" #include "profiler.h" #include "lzo_manager.h" #include "messenger_manager.h" #include "db.h" #include "log.h" #include "p2p.h" #include "guild_manager.h" #include "dungeon.h" #include "cmd.h" #include "refine.h" #include "banword.h" #include "priv_manager.h" #include "war_map.h" #include "building.h" #include "login_sim.h" #include "target.h" #include "marriage.h" #include "wedding.h" #include "fishing.h" #include "item_addon.h" #include "TrafficProfiler.h" #include "locale_service.h" #include "arena.h" #include "OXEvent.h" #include "monarch.h" #include "polymorph.h" #include "blend_item.h" #include "castle.h" #include "passpod.h" #include "ani.h" #include "BattleArena.h" #include "over9refine.h" #include "horsename_manager.h" #include "pcbang.h" #include "MarkManager.h" #include "spam.h" #include "panama.h" #include "threeway_war.h" #include "auth_brazil.h" #include "DragonLair.h" #include "HackShield.h" #include "skill_power.h" #include "SpeedServer.h" #include "XTrapManager.h" #include "DragonSoul.h" #include #ifdef NEW_PET_SYSTEM #include "fstream" #endif #ifndef __WIN32__ #include "limit_time.h" #endif //#define __FILEMONITOR__ #if defined (__FreeBSD__) && defined(__FILEMONITOR__) #include "FileMonitor_FreeBSD.h" #endif #ifdef __AUCTION__ #include "auction_manager.h" #endif #ifndef __WIN32__ #include #endif #ifdef USE_STACKTRACE #include #endif // ????? ???? ?? ?? ??? ?? #ifdef _WIN32 //#define _USE_SERVER_KEY_ #endif #include "check_server.h" #ifdef __MELEY_LAIR_DUNGEON__ #include "MeleyLair.h" #endif extern void WriteVersion(); //extern const char * _malloc_options; #if defined(__FreeBSD__) && defined(DEBUG_ALLOC) extern void (*_malloc_message)(const char* p1, const char* p2, const char* p3, const char* p4); // FreeBSD _malloc_message replacement void WriteMallocMessage(const char* p1, const char* p2, const char* p3, const char* p4) { FILE* fp = ::fopen(DBGALLOC_LOG_FILENAME, "a"); if (fp == NULL) { return; } ::fprintf(fp, "%s %s %s %s\n", p1, p2, p3, p4); ::fclose(fp); } #endif // TRAFFIC_PROFILER static const DWORD TRAFFIC_PROFILE_FLUSH_CYCLE = 3600; ///< TrafficProfiler ? Flush cycle. 1?? ?? // END_OF_TRAFFIC_PROFILER // ??? ???? ?? volatile int num_events_called = 0; int max_bytes_written = 0; int current_bytes_written = 0; int total_bytes_written = 0; BYTE g_bLogLevel = 0; socket_t tcp_socket = 0; socket_t udp_socket = 0; socket_t p2p_socket = 0; LPFDWATCH main_fdw = NULL; int io_loop(LPFDWATCH fdw); int start(int argc, char **argv); int idle(); void destroy(); void test(); enum EProfile { PROF_EVENT, PROF_CHR_UPDATE, PROF_IO, PROF_HEARTBEAT, PROF_MAX_NUM }; static DWORD s_dwProfiler[PROF_MAX_NUM]; int g_shutdown_disconnect_pulse; int g_shutdown_disconnect_force_pulse; int g_shutdown_core_pulse; bool g_bShutdown=false; extern int speed_server; #ifdef __AUCTION__ extern int auction_server; #endif extern void CancelReloadSpamEvent(); void ContinueOnFatalError() { #ifdef USE_STACKTRACE void* array[200]; std::size_t size; char** symbols; size = backtrace(array, 200); symbols = backtrace_symbols(array, size); std::ostringstream oss; oss << std::endl; for (std::size_t i = 0; i < size; ++i) { oss << " Stack> " << symbols[i] << std::endl; } free(symbols); sys_err("FatalError on %s", oss.str().c_str()); #else sys_err("FatalError"); #endif } void ShutdownOnFatalError() { if (!g_bShutdown) { sys_err("ShutdownOnFatalError!!!!!!!!!!"); { char buf[256]; strlcpy(buf, LC_TEXT("??? ???? ??? ???? ???? ??????."), sizeof(buf)); SendNotice(buf); strlcpy(buf, LC_TEXT("10?? ???? ??? ????,"), sizeof(buf)); SendNotice(buf); strlcpy(buf, LC_TEXT("5? ?? ????? ????? ????."), sizeof(buf)); SendNotice(buf); } g_bShutdown = true; g_bNoMoreClient = true; g_shutdown_disconnect_pulse = thecore_pulse() + PASSES_PER_SEC(10); g_shutdown_disconnect_force_pulse = thecore_pulse() + PASSES_PER_SEC(20); g_shutdown_core_pulse = thecore_pulse() + PASSES_PER_SEC(30); } } namespace { struct SendDisconnectFunc { void operator () (LPDESC d) { if (d->GetCharacter()) { if (d->GetCharacter()->GetGMLevel() == GM_PLAYER) d->GetCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "quit Shutdown(SendDisconnectFunc)"); } } }; struct DisconnectFunc { void operator () (LPDESC d) { if (d->GetType() == DESC_TYPE_CONNECTOR) return; if (d->IsPhase(PHASE_P2P)) return; d->SetPhase(PHASE_CLOSE); } }; } extern std::map g_sim; // first: AID extern std::map g_simByPID; extern std::vector g_vec_save; unsigned int save_idx = 0; void heartbeat(LPHEART ht, int pulse) { DWORD t; t = get_dword_time(); num_events_called += event_process(pulse); s_dwProfiler[PROF_EVENT] += (get_dword_time() - t); t = get_dword_time(); // 1??? if (!(pulse % ht->passes_per_sec)) { #ifdef ENABLE_LIMIT_TIME if ((unsigned)get_global_time() >= GLOBAL_LIMIT_TIME) { g_bShutdown = true; } #endif if (g_bAuthServer && LC_IsBrazil() && !test_server) auth_brazil_log(); if (!g_bAuthServer) { TPlayerCountPacket pack; pack.dwCount = DESC_MANAGER::instance().GetLocalUserCount(); db_clientdesc->DBPacket(HEADER_GD_PLAYER_COUNT, 0, &pack, sizeof(TPlayerCountPacket)); } else { DESC_MANAGER::instance().ProcessExpiredLoginKey(); DBManager::instance().FlushBilling(); /* if (!(pulse % (ht->passes_per_sec * 600))) DBManager::instance().CheckBilling(); */ } { int count = 0; itertype(g_sim) it = g_sim.begin(); while (it != g_sim.end()) { if (!it->second->IsCheck()) { it->second->SendLogin(); if (++count > 50) { sys_log(0, "FLUSH_SENT"); break; } } it++; } if (save_idx < g_vec_save.size()) { count = MIN(100, g_vec_save.size() - save_idx); for (int i = 0; i < count; ++i, ++save_idx) db_clientdesc->DBPacket(HEADER_GD_PLAYER_SAVE, 0, &g_vec_save[save_idx], sizeof(TPlayerTable)); sys_log(0, "SAVE_FLUSH %d", count); } } } // // 25 PPS(Pulse per second) ?? ??? ? // // ? 1.16??? if (!(pulse % (passes_per_sec + 4))) CHARACTER_MANAGER::instance().ProcessDelayedSave(); //4? ?? #if defined (__FreeBSD__) && defined(__FILEMONITOR__) if (!(pulse % (passes_per_sec * 5))) { FileMonitorFreeBSD::Instance().Update(pulse); } #endif // ? 5.08??? if (!(pulse % (passes_per_sec * 5 + 2))) { ITEM_MANAGER::instance().Update(); DESC_MANAGER::instance().UpdateLocalUserCount(); } s_dwProfiler[PROF_HEARTBEAT] += (get_dword_time() - t); DBManager::instance().Process(); AccountDB::instance().Process(); CPVPManager::instance().Process(); if (g_bShutdown) { if (thecore_pulse() > g_shutdown_disconnect_pulse) { const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet(); std::for_each(c_set_desc.begin(), c_set_desc.end(), ::SendDisconnectFunc()); g_shutdown_disconnect_pulse = INT_MAX; } else if (thecore_pulse() > g_shutdown_disconnect_force_pulse) { const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet(); std::for_each(c_set_desc.begin(), c_set_desc.end(), ::DisconnectFunc()); } else if (thecore_pulse() > g_shutdown_disconnect_force_pulse + PASSES_PER_SEC(5)) { thecore_shutdown(); } } } static bool g_isInvalidServer = false; bool Metin2Server_IsInvalid() { return g_isInvalidServer; } void Metin2Server_Check() { #ifdef _SERVER_CHECK_ #ifdef _USE_SERVER_KEY_ if (false == CheckServer::CheckIp(g_szPublicIP)) { #ifdef _WIN32 fprintf(stderr, "check ip failed\n"); #endif g_isInvalidServer = true; } return; #endif if (LC_IsEurope() || test_server) return; // ??? ip if (strncmp (g_szPublicIP, "189.112.1", 9) == 0) { return; } // ??? ip if (strncmp (g_szPublicIP, "74.200.6", 8) == 0) { return; } return; static const size_t CheckServerListSize = 1; static const char* CheckServerList[] = { "202.31.178.251"}; static const int CheckServerPort = 7120; socket_t sockConnector = INVALID_SOCKET; for (size_t i = 0 ; i < CheckServerListSize ; i++) { sockConnector = socket_connect( CheckServerList[i], CheckServerPort ); if (0 < sockConnector) break; } if (0 > sockConnector) { if (true != LC_IsEurope()) // ??? ??? ?? ??? ??? ??? ?? g_isInvalidServer = true; return; } char buf[256] = { 0, }; socket_read(sockConnector, buf, sizeof(buf) - 1); sys_log(0, "recv[%s]", buf); if (strncmp(buf, "OK", 2) == 0) g_isInvalidServer = false; else if (strncmp(buf, "CK", 2) == 0) g_isInvalidServer = true; socket_close(sockConnector); #else g_isInvalidServer = false; return; #endif } static void CleanUpForEarlyExit() { CancelReloadSpamEvent(); } int main(int argc, char **argv) { #ifdef DEBUG_ALLOC DebugAllocator::StaticSetUp(); #endif #ifndef __WIN32__ // start unit tests if option is set if ( argc > 1 ) { if ( strcmp( argv[1], "unittest" ) == 0 ) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } } #endif ilInit(); // DevIL Initialize WriteVersion(); SECTREE_MANAGER sectree_manager; CHARACTER_MANAGER char_manager; ITEM_MANAGER item_manager; CShopManager shop_manager; CMobManager mob_manager; CMotionManager motion_manager; CPartyManager party_manager; CSkillManager skill_manager; CPVPManager pvp_manager; LZOManager lzo_manager; DBManager db_manager; AccountDB account_db; LogManager log_manager; MessengerManager messenger_manager; P2P_MANAGER p2p_manager; CGuildManager guild_manager; CGuildMarkManager mark_manager; CDungeonManager dungeon_manager; CRefineManager refine_manager; CBanwordManager banword_manager; CPrivManager priv_manager; CWarMapManager war_map_manager; building::CManager building_manager; CTargetManager target_manager; marriage::CManager marriage_manager; marriage::WeddingManager wedding_manager; CItemAddonManager item_addon_manager; CArenaManager arena_manager; COXEventManager OXEvent_manager; CMonarch Monarch; CHorseNameManager horsename_manager; CPCBangManager pcbang_manager; DESC_MANAGER desc_manager; TrafficProfiler trafficProfiler; CTableBySkill SkillPowerByLevel; CPolymorphUtils polymorph_utils; CProfiler profiler; CPasspod passpod; CBattleArena ba; COver9RefineManager o9r; SpamManager spam_mgr; CThreeWayWar threeway_war; CDragonLairManager dl_manager; CHackShieldManager HSManager; CXTrapManager XTManager; CSpeedServerManager SSManager; DSManager dsManager; #ifdef __AUCTION__ AuctionManager auctionManager; #endif if (!start(argc, argv)) { CleanUpForEarlyExit(); return 0; } #ifdef __MELEY_LAIR_DUNGEON__ MeleyLair::CMgr MeleyLair_manager; #endif quest::CQuestManager quest_manager; if (!quest_manager.Initialize()) { CleanUpForEarlyExit(); return 0; } MessengerManager::instance().Initialize(); CGuildManager::instance().Initialize(); fishing::Initialize(); OXEvent_manager.Initialize(); if (speed_server) CSpeedServerManager::instance().Initialize(); Cube_init(); Acce_init(); Blend_Item_init(); ani_init(); PanamaLoad(); #ifdef NEW_PET_SYSTEM std::string temp_exp_line; std::ifstream exppet_table_open("/share/exppettable.txt"); /*if (!exp_table_open.is_open()) return 0;*/ int exppet_table_counter = 0; int tmppet_exp = 0; while (!exppet_table_open.eof()) { exppet_table_open >> temp_exp_line; str_to_number(exppet_table_common[exppet_table_counter], temp_exp_line.c_str()); if (exppet_table_common[exppet_table_counter] < 2147483647) { sys_log(0, "Livelli Pet caricati da exppettable.txt: %d !", exppet_table_common[exppet_table_counter]); exppet_table_counter++; } else { fprintf(stderr, "[main] Impossibile caricare la tabella exp valore non valido\n"); break; } } #endif Metin2Server_Check(); #if defined(_WIN32) && defined(_USE_SERVER_KEY_) if (CheckServer::IsFail()) { return 1; } #endif if ( g_bTrafficProfileOn ) TrafficProfiler::instance().Initialize( TRAFFIC_PROFILE_FLUSH_CYCLE, "ProfileLog" ); //if game server if (!g_bAuthServer) { //hackshield if (isHackShieldEnable) { if (!HSManager.Initialize()) { fprintf(stderr, "Failed To Initialize HS"); CleanUpForEarlyExit(); return 0; } } //xtrap if(bXTrapEnabled) { if (!XTManager.LoadXTrapModule()) { CleanUpForEarlyExit(); return 0; } #if defined (__FreeBSD__) && defined(__FILEMONITOR__) //PFN_FileChangeListener pNotifyFunc = boost::bind( &CXTrapManager::NotifyMapFileChanged, CXTrapManager::instance(), _1 ); PFN_FileChangeListener pNotifyFunc = &(CXTrapManager::NotifyMapFileChanged); const std::string strMap1Name = "map1.CS3"; const std::string strMap2Name = "map2.CS3"; FileMonitorFreeBSD::Instance().AddWatch( strMap1Name, pNotifyFunc ); FileMonitorFreeBSD::Instance().AddWatch( strMap2Name, pNotifyFunc ); #endif #ifdef __MELEY_LAIR_DUNGEON__ MeleyLair_manager.Initialize(); #endif } // Client PackageCrypt //TODO : make it config const std::string strPackageCryptInfoDir = "package/"; if( !desc_manager.LoadClientPackageCryptInfo( strPackageCryptInfoDir.c_str() ) ) { sys_err("Failed to Load ClientPackageCryptInfo File(%s)", strPackageCryptInfoDir.c_str()); } #if defined (__FreeBSD__) && defined(__FILEMONITOR__) PFN_FileChangeListener pPackageNotifyFunc = &(DESC_MANAGER::NotifyClientPackageFileChanged); //FileMonitorFreeBSD::Instance().AddWatch( strPackageCryptInfoName, pPackageNotifyFunc ); #endif while (idle()); sys_log(0, " Starting..."); g_bShutdown = true; g_bNoMoreClient = true; if (g_bAuthServer) { DBManager::instance().FlushBilling(true); int iLimit = DBManager::instance().CountQuery() / 50; int i = 0; do { DWORD dwCount = DBManager::instance().CountQuery(); sys_log(0, "Queries %u", dwCount); if (dwCount == 0) break; usleep(500000); if (++i >= iLimit) if (dwCount == DBManager::instance().CountQuery()) break; } while (1); } sys_log(0, " Destroying CArenaManager..."); arena_manager.Destroy(); sys_log(0, " Destroying COXEventManager..."); OXEvent_manager.Destroy(); sys_log(0, " Disabling signal timer..."); signal_timer_disable(); sys_log(0, " Shutting down CHARACTER_MANAGER..."); char_manager.GracefulShutdown(); sys_log(0, " Shutting down ITEM_MANAGER..."); item_manager.GracefulShutdown(); sys_log(0, " Flushing db_clientdesc..."); db_clientdesc->FlushOutput(); sys_log(0, " Flushing p2p_manager..."); p2p_manager.FlushOutput(); sys_log(0, " Destroying CShopManager..."); shop_manager.Destroy(); sys_log(0, " Destroying CHARACTER_MANAGER..."); char_manager.Destroy(); sys_log(0, " Destroying ITEM_MANAGER..."); item_manager.Destroy(); sys_log(0, " Destroying DESC_MANAGER..."); desc_manager.Destroy(); sys_log(0, " Destroying quest::CQuestManager..."); quest_manager.Destroy(); sys_log(0, " Destroying building::CManager..."); building_manager.Destroy(); if (!g_bAuthServer) { if (isHackShieldEnable) { sys_log(0, " Releasing HackShield manager..."); HSManager.Release(); } #ifdef __MELEY_LAIR_DUNGEON__ sys_log(0, " Destroying MeleyLair_manager."); MeleyLair_manager.Destroy(); #endif } sys_log(0, " Flushing TrafficProfiler..."); trafficProfiler.Flush(); destroy(); #ifdef DEBUG_ALLOC DebugAllocator::StaticTearDown(); #endif return 1; } void usage() { printf("Option list\n" "-p : bind port number (port must be over 1024)\n" "-l : sets log level\n" "-v : log to stdout\n" "-r : do not load regen tables\n" "-t : traffic proflie on\n"); } int start(int argc, char **argv) { std::string st_localeServiceName; bool bVerbose = false; char ch; //_malloc_options = "A"; #if defined(__FreeBSD__) && defined(DEBUG_ALLOC) _malloc_message = WriteMallocMessage; #endif #ifdef ENABLE_LIMIT_TIME if ((unsigned)get_global_time() >= GLOBAL_LIMIT_TIME) { return 0; } #endif while ((ch = getopt(argc, argv, "npverltI")) != -1) { char* ep = NULL; switch (ch) { case 'I': // IP strlcpy(g_szPublicIP, argv[optind], sizeof(g_szPublicIP)); printf("IP %s\n", g_szPublicIP); optind++; optreset = 1; break; case 'p': // port mother_port = strtol(argv[optind], &ep, 10); if (mother_port <= 1024) { usage(); return 0; } printf("port %d\n", mother_port); optind++; optreset = 1; break; case 'l': { long l = strtol(argv[optind], &ep, 10); log_set_level(l); optind++; optreset = 1; } break; // LOCALE_SERVICE case 'n': { if (optind < argc) { st_localeServiceName = argv[optind++]; optreset = 1; } } break; // END_OF_LOCALE_SERVICE case 'v': // verbose bVerbose = true; break; case 'r': g_bNoRegen = true; break; // TRAFFIC_PROFILER case 't': g_bTrafficProfileOn = true; break; // END_OF_TRAFFIC_PROFILER } } // LOCALE_SERVICE config_init(st_localeServiceName); // END_OF_LOCALE_SERVICE #ifdef __WIN32__ // In Windows dev mode, "verbose" option is [on] by default. bVerbose = true; #endif if (!bVerbose) freopen("stdout", "a", stdout); bool is_thecore_initialized = thecore_init(25, heartbeat); if (!is_thecore_initialized) { fprintf(stderr, "Could not initialize thecore, check owner of pid, syslog\n"); exit(0); } if (false == CThreeWayWar::instance().LoadSetting("forkedmapindex.txt")) { if (false == g_bAuthServer) { fprintf(stderr, "Could not Load ThreeWayWar Setting file"); exit(0); } } signal_timer_disable(); main_fdw = fdwatch_new(4096); if ((tcp_socket = socket_tcp_bind(g_szPublicIP, mother_port)) == INVALID_SOCKET) { perror("socket_tcp_bind: tcp_socket"); return 0; } #ifndef __UDP_BLOCK__ if ((udp_socket = socket_udp_bind(g_szPublicIP, mother_port)) == INVALID_SOCKET) { perror("socket_udp_bind: udp_socket"); return 0; } #endif // if internal ip exists, p2p socket uses internal ip, if not use public ip //if ((p2p_socket = socket_tcp_bind(*g_szInternalIP ? g_szInternalIP : g_szPublicIP, p2p_port)) == INVALID_SOCKET) if ((p2p_socket = socket_tcp_bind(g_szPublicIP, p2p_port)) == INVALID_SOCKET) { perror("socket_tcp_bind: p2p_socket"); return 0; } fdwatch_add_fd(main_fdw, tcp_socket, NULL, FDW_READ, false); #ifndef __UDP_BLOCK__ fdwatch_add_fd(main_fdw, udp_socket, NULL, FDW_READ, false); #endif fdwatch_add_fd(main_fdw, p2p_socket, NULL, FDW_READ, false); db_clientdesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, db_addr, db_port, PHASE_DBCLIENT, true); if (!g_bAuthServer) { db_clientdesc->UpdateChannelStatus(0, true); } if (g_bAuthServer) { if (g_stAuthMasterIP.length() != 0) { fprintf(stderr, "SlaveAuth"); g_pkAuthMasterDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, g_stAuthMasterIP.c_str(), g_wAuthMasterPort, PHASE_P2P, true); P2P_MANAGER::instance().RegisterConnector(g_pkAuthMasterDesc); g_pkAuthMasterDesc->SetP2P(g_stAuthMasterIP.c_str(), g_wAuthMasterPort, g_bChannel); } else { fprintf(stderr, "MasterAuth %d", LC_GetLocalType()); } } /* game server to teen server */ else { if (teen_addr[0] && teen_port) g_TeenDesc = DESC_MANAGER::instance().CreateConnectionDesc(main_fdw, teen_addr, teen_port, PHASE_TEEN, true); extern unsigned int g_uiSpamBlockDuration; extern unsigned int g_uiSpamBlockScore; extern unsigned int g_uiSpamReloadCycle; sys_log(0, "SPAM_CONFIG: duration %u score %u reload cycle %u\n", g_uiSpamBlockDuration, g_uiSpamBlockScore, g_uiSpamReloadCycle); extern void LoadSpamDB(); LoadSpamDB(); } signal_timer_enable(30); return 1; } void destroy() { sys_log(0, " Canceling ReloadSpamEvent..."); CancelReloadSpamEvent(); sys_log(0, " regen_free()..."); regen_free(); sys_log(0, " Closing sockets..."); socket_close(tcp_socket); #ifndef __UDP_BLOCK__ socket_close(udp_socket); #endif socket_close(p2p_socket); sys_log(0, " fdwatch_delete()..."); fdwatch_delete(main_fdw); sys_log(0, " event_destroy()..."); event_destroy(); sys_log(0, " CTextFileLoader::DestroySystem()..."); CTextFileLoader::DestroySystem(); sys_log(0, " thecore_destroy()..."); thecore_destroy(); } int idle() { static struct timeval pta = { 0, 0 }; static int process_time_count = 0; struct timeval now; if (pta.tv_sec == 0) gettimeofday(&pta, (struct timezone *) 0); int passed_pulses; if (!(passed_pulses = thecore_idle())) return 0; assert(passed_pulses > 0); DWORD t; while (passed_pulses--) { heartbeat(thecore_heart, ++thecore_heart->pulse); // To reduce the possibility of abort() in checkpointing thecore_tick(); } t = get_dword_time(); CHARACTER_MANAGER::instance().Update(thecore_heart->pulse); db_clientdesc->Update(t); s_dwProfiler[PROF_CHR_UPDATE] += (get_dword_time() - t); t = get_dword_time(); if (!io_loop(main_fdw)) return 0; s_dwProfiler[PROF_IO] += (get_dword_time() - t); log_rotate(); gettimeofday(&now, (struct timezone *) 0); ++process_time_count; if (now.tv_sec - pta.tv_sec > 0) { pt_log("[%3d] event %5d/%-5d idle %-4ld event %-4ld heartbeat %-4ld I/O %-4ld chrUpate %-4ld | WRITE: %-7d | PULSE: %d", process_time_count, num_events_called, event_count(), thecore_profiler[PF_IDLE], s_dwProfiler[PROF_EVENT], s_dwProfiler[PROF_HEARTBEAT], s_dwProfiler[PROF_IO], s_dwProfiler[PROF_CHR_UPDATE], current_bytes_written, thecore_pulse()); num_events_called = 0; current_bytes_written = 0; process_time_count = 0; gettimeofday(&pta, (struct timezone *) 0); memset(&thecore_profiler[0], 0, sizeof(thecore_profiler)); memset(&s_dwProfiler[0], 0, sizeof(s_dwProfiler)); } #ifdef _USE_SERVER_KEY_ if (Metin2Server_IsInvalid() && 0 == (thecore_random() % 7146)) { return 0; // shutdown } #endif #ifdef __WIN32__ if (_kbhit()) { int c = _getch(); switch (c) { case 0x1b: // Esc return 0; // shutdown break; default: break; } } #endif return 1; } int io_loop(LPFDWATCH fdw) { LPDESC d; int num_events, event_idx; DESC_MANAGER::instance().DestroyClosed(); // PHASE_CLOSE? ???? ????. DESC_MANAGER::instance().TryConnect(); if ((num_events = fdwatch(fdw, 0)) < 0) return 0; for (event_idx = 0; event_idx < num_events; ++event_idx) { d = (LPDESC) fdwatch_get_client_data(fdw, event_idx); if (!d) { if (FDW_READ == fdwatch_check_event(fdw, tcp_socket, event_idx)) { DESC_MANAGER::instance().AcceptDesc(fdw, tcp_socket); fdwatch_clear_event(fdw, tcp_socket, event_idx); } else if (FDW_READ == fdwatch_check_event(fdw, p2p_socket, event_idx)) { DESC_MANAGER::instance().AcceptP2PDesc(fdw, p2p_socket); fdwatch_clear_event(fdw, p2p_socket, event_idx); } /* else if (FDW_READ == fdwatch_check_event(fdw, udp_socket, event_idx)) { char buf[256]; struct sockaddr_in cliaddr; socklen_t socklen = sizeof(cliaddr); int iBytesRead; if ((iBytesRead = socket_udp_read(udp_socket, buf, 256, (struct sockaddr *) &cliaddr, &socklen)) > 0) { static CInputUDP s_inputUDP; s_inputUDP.SetSockAddr(cliaddr); int iBytesProceed; s_inputUDP.Process(NULL, buf, iBytesRead, iBytesProceed); } fdwatch_clear_event(fdw, udp_socket, event_idx); } */ continue; } int iRet = fdwatch_check_event(fdw, d->GetSocket(), event_idx); switch (iRet) { case FDW_READ: if (db_clientdesc == d) { int size = d->ProcessInput(); if (size) sys_log(1, "DB_BYTES_READ: %d", size); if (size < 0) { d->SetPhase(PHASE_CLOSE); } } else if (d->ProcessInput() < 0) { d->SetPhase(PHASE_CLOSE); } break; case FDW_WRITE: if (db_clientdesc == d) { int buf_size = buffer_size(d->GetOutputBuffer()); int sock_buf_size = fdwatch_get_buffer_size(fdw, d->GetSocket()); int ret = d->ProcessOutput(); if (ret < 0) { d->SetPhase(PHASE_CLOSE); } if (buf_size) sys_log(1, "DB_BYTES_WRITE: size %d sock_buf %d ret %d", buf_size, sock_buf_size, ret); } else if (d->ProcessOutput() < 0) { d->SetPhase(PHASE_CLOSE); } else if (g_TeenDesc==d) { int buf_size = buffer_size(d->GetOutputBuffer()); int sock_buf_size = fdwatch_get_buffer_size(fdw, d->GetSocket()); int ret = d->ProcessOutput(); if (ret < 0) { d->SetPhase(PHASE_CLOSE); } if (buf_size) sys_log(0, "TEEN::Send(size %d sock_buf %d ret %d)", buf_size, sock_buf_size, ret); } break; case FDW_EOF: { d->SetPhase(PHASE_CLOSE); } break; default: sys_err("fdwatch_check_event returned unknown %d", iRet); d->SetPhase(PHASE_CLOSE); break; } } } return 1; }Merci encore à vous.
Lien vers le commentaire
Partager sur d’autres sites
Meilleurs contributeurs dans cette question
5
2
2
1
Jours populaires
le 24 mai
12
le 25 mai
1
Meilleurs contributeurs dans cette question
CHAPPiE 5 messages
antok 2 messages
MacDonarty 2 messages
Saw 1 message
Jours populaires
le 24 mai 2017
12 messages
le 25 mai 2017
1 message
12 réponses à cette question
Messages recommandés