Search the Community

Showing results for tags 'tutoriel / partage'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Register & Login
    • Register
    • Login
  • Espace Communautaire
    • Funky Emulation
    • Présentations
    • Services
    • Discussions Générales
    • Bureau de la Communauté
    • Espace Premium
  • Emulation & Co
    • Rewrite a Release / Tutorial
    • Suggest a Release / Tutorial
    • The Ideas Box
  • Emulation de jeux
    • RaiderZ
    • Aura Kingdom
    • Metin2
    • Dofus
    • World of Warcraft
    • Minecraft
    • Aion
    • Habbo
    • Voir plus...
  • Espace Divers
  • Internationnal Forum
  • PassionDev's Forum
  • M2Project - Metin2's M2SF
  • M2Project - Metin2's Aide / Questions / Support
  • M2Project - Metin2's Tutoriels & Partages
  • M2Project - Metin2's Suggestions
  • M2Project - Metin2's Report de Bugs

Product Groups

  • VIP
  • Points

Calendars

  • Community Calendar
  • Évènements

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Nationality


Sexe


Discord


Skype


Biographie


Site


Nombre

 
or  

Found 779 results

  1. Hello, Aujourd'hui je vous partage l'émulateur sur lequel je travaille de temps à autre quand j'ai du temps libre et de la motivation. J'ai commencé le développement en septembre 2013... ça date ! Je n'ai jamais eu beaucoup de temps à consacré au développement de l'émulateur du coup il n'est pas très avancé. Ce qui m'intéressait principalement dans ce projet c'est toute la partie "reverse engineering", comprendre comment le jeu fonctionne, développer des outils, etc. L'émulateur est développé en C++ avec la librairie Qt et le client supporté est le client officiel version 1.54.0. Sources: [Hidden Content] Je ferais un tutoriel à l'occaz' sur l'installation de l'ému Cordialement, Sgt --- Download
  2. Bonjour Funky! Je vous partage aujourd'hui un petit CMS avec 3 couleurs changeable que j'ai fais en 10 minutes, il ne comporte qu'un système d'inscription et de classement. Pour la configuration de la base de données, c'est dans config/db.php, pas besoin de vous montrez comment configurer ça j'espère Téléchargement: Clique ici A+ --- Download
  3. Bonjour, Aujourd'hui, je vais vous apprendre à créer votre rétro habbo avec PlusEmu, phpmyadmin et XAMP au passage Pour cela, vous allez avoir besoin de : XAMPP, pour pouvoir gérer la partit web et la base de donnés Lien : [Hidden Content] Le CMS: ICI C'est le site WEB (le CMS) que l'on va utiliser pour le serveur Habbo. Il nous permettra d'accéder à l'hôtel ainsi que de gérer la maintenance du serveur (Membres, appartements, etc ...) Les fichiers Habbo (Emulateur + Base de données + SWF): [Hidden Content] Vous aurez aussi besoin de l'émulateur avec sa base de donnée ! Lien : ICI Une fois ceci, fait, nous pouvons commencer. Rendez vous dans le dossier web de XAMPP (htdocs) déplacez-y tous les fichiers contenue dans l'archive du site : Démarrez ensuite XAMPP, installer Apache et Mysql en appuyant, puis démarrez les (appuyez sur les boutons en rouge pour les installer et en bleu pour les démarrer), une fois fait, vous devriez avoir ceci : Il se peut que Apache utilise le même port que skype, pour ça changez le dans les paramètres de WAMP. Rendez maintenant sur phpmyadmin : [Hidden Content] Appuyez sur "nouvelle base de données" : Nommez là : funkyEmu , puis appuyez sur "créer" : Ensuite, faites "importer" : Faites "parcourir", puis sélectionner le habbo.sql se trouvant dans l'archive de l'émulateur : Si le fichier ne veut pas s'upload, c'est qu'il est trop gros pour phpmyadmin, allez dans xampp\php\php.ini et modifier cette ligne : Ensuite, uploadez votre habbo.sql, cela peut prendre un peu de temps. Une fois fait, vous devriez avoir quelques tables d'ajouté(et d'autres, mais bon tout ne tient pas dans un screen) : Allez ensuite dans votre dossier : htdocs\includes\settings.inc.php Verfiez que les informations sont bien remplis comme ça, ou changez le nom de la base de données (les // sont là pour vous aidez) si vous n'avez pas mis "FunkyEMU". Enregistrez, puis rendez-vous sur : [Hidden Content] Sélectionnez ensuite "Butterfly", puis faites "Valider l'installation" Une fois fait, cliquez sur "Supprimer fichier d'installation". Vous allez ensuite vous créez un compte sur votre site. Allez ensuite ici : [Hidden Content] Allez dans votre base de donnée, puis la table "users" : Changez ensuite le "1" de "rank" en "10" Rendez vous ensuite sur votre site, relancez la page, et un bouton est apparue : Cliquez dessus, puis allez dans "configuration" Vous aurez ceci : Configurez les comme ceci : Variables : [Hidden Content]game/gamedata/external_variables.txt Texts : [Hidden Content]game/gamedata/external_flash_texts.txt Furnidata : [Hidden Content]game/gamedata/furnidata.xml Productdata : [Hidden Content]game/gamedata/productdata.txt Banner : Ne pas y toucher Base : [Hidden Content]game/gordon/PRODUCTION-201601012205-226667486/ Habbo SWF : [Hidden Content]game/gordon/PRODUCTION-201601012205-226667486/Habbo.swf Ce qui donne : Ensuite, il va falloir faire un petit changement dans votre panneau de configuration, allez dans : Faites parametres suplémentaire, puis : Changez le symbole décimal par un "." Faites "Appliquer", et le tour est joué ! Ensuite, aller dans l'émulateur : Emulateur PlusEmu\bin\Debug\config.ini Vous metterez ceci : Code : ## MySQL Configuration db.hostname=127.0.0.1 db.port=3306 db.username=root db.password= db.name=FunkyEmu Changer le si vous n'avez pas mis "FunkyEmu" en nom de base de données. Enregistrez, puis lancer l'émulateur grâce à : Plus Emulator.exe qui se trouve dans le meme dossier que le config.ini Vous aurez normalement ceci : Vous pouvez donc vous connectez sur votre rétro habbo ! Pour être staff, il vous suffit de vous mettre au "rank" 8 de la même façons que vous vous êtes mis "rank" 10 toute à l'heure. je sais que le tutoriel à déjà été fait mais apparemment Navicat créer des erreurs, je ne sais pas je n'ai pas essayez mais au moins, voici de quoi rendre tout le monde heureux. Bon jeu ! Cordialement. --- Download
  4. Bonjour ! Voyant que beaucoup d'entre vous (ou presque ) cherche à avoir les anciennes ailes de l'officiel pour leur serveur (celle ci dessous), je les partages. Je parle bien entendu des ailes où les ailes bontarien ont leur auréole ! C'est vrai que l'auréole des anges ça fais déjà plus ange . Téléchargement : Aile Démon Ange Version 1.18 Cordialement, --- Download
  5. Bonjour Je vous fais un cours tutoriel sur l'extraction des SWF de Dofus l'officiel, ce tutoriel va surtout servir à compléter le tutoriel que je vais réaliser prochainement qui s'intitulera "Tutoriel SWF, Adapter les SWF de Dofus l'officiel pour 1.29" et donc avant de réaliser un tel tutoriel il faut bien que je vous apprenne comment extraire les fichiers D2P de Dofus l'officiel pour les adapter ensuite sur 1.29 donc pour votre serveur ! Je précise que le tutoriel est entièrement de moi. À l'heure où j'écris ces lignes je le commence tout juste, j'autorise le partage partout je suis POUR essayer de faire avancer la communauté et ne rien garder dans mon coin surtout que je quitte l'émulation Dofus ce sont en quelque sorte mes derniers cadeaux ! On va commencer ce mini-tutoriel ! Étape 1 : Télécharger le décompilateur D2P Ici, puis une fois téléchargé je vous invite à extraire le contenue du décompilateur sur votre bureau avec Winrar pour s'y retrouver plus facilement. C'est quoi un décompilateur ? un décompilateur sert à convertir un format dans un autre, par exemple avec les SWF de Dofus l'officiel a comme format de base D2P comme je vous le disais juste avant, grâce au décompilateur on va convertir les fichiers D2P en format SWL et ensuite en SWF ! Ah mais c'est quoi un format , un format et une extension de fichier, par exemple regardez une image et regardez la fin, en général c'est mon_image.png le .png est le format, il y a bien sûr énormément d'extensions mais c'est pas le but de ce tutoriel de vous les apprendre ! Et pourquoi aussi on convertit le fichier D2P en SWL puis en SWF ? Il y a trop de questions à se poser mais c'est sûrement la meilleur solution. Étape 2 : Rendez-vous dans votre dossier Dofus 2 (dofus l'officiel), et si vous ne l'avez pas, installez le Dofus officiel. Étape 3 : Une fois dans le dossier de Dofus 2 rendez-vous à ce chemin on va prendre pour exemple un D2P bien précis : C:\Program Files (x86)\Dofus2\app\content\gfx\sprites\bones0.d2p Étape 4 : Copiez/collez bones0.d2p sur votre bureau. Étape 5 : Rendez-vous sur votre décompilateur et ouvrez : TenkUnpacker.exe Étape 6 : Cliquez sur Parcourir et trouvez le fichier bones0.d2p qui est normalement sur votre bureau si vous m'avez écouté, cliquez sur Ouvrir et pour finir Extraire ! Maintenant si vous regardez dans votre dossier du décompilateur un dossier appelé "data" s'est créé. C'est très intéressant car il contient tous les fichiers extraits du fichier D2P en format SWL vous suivez toujours ? Étape 7 : Donc on a ce fameux dossier avec pleins de fichiers au format SWL, on ne les touche surtout pas, et maintenant ont va simplement ouvrir le logiciel TenkSwl.exe qui va enfin convertir tout seul les fichiers SWL en SWF ! Étape 8 : Il n'y a pas d'étape 8 si vous avez suivi le tutoriel, maintenant il vous reste plus qu'à vous rendre dans le dossier de votre décompilateur et de regarder le deuxième dossier qui s'est créé ! Appelé "data2" et tous les fichiers SWF se trouvent tout simplement dedans. Le tutoriel est terminé, vous avez extrait les fichiers de Dofus l'officiel en format D2P en SWF ! Une question ? Je suis la. Un merci je vous en remercie, un message sur le sujet et encore mieux. [Tutoriel SWF] Adapter les fichiers SWF de Dofus l'officiel pour Dofus 1.29 : À venir
  6. Régler bonnus dommages: Salut tout le monde ! je partage un tutoriel pour débug les bonnus de dommages. Pourquoi ce tuto ? Car certains serveurs ne prennent pas en compte les bonus de dégâts infligés. PS : Ce tutoriel vous servira également à savoir comment décompiler / recompiler des sources avec Eclipse ! Requis: - Eclipse (Editeur Java) - Sources de l'émulateur - Un cerveau 1. Commencez par ouvrir eclipse.exe 2. Vous cliquez sur "File" => "New" => "Java Project" 3. Mettez un nom de projet (N'importe, ce n'est pas important) 4. Après avoir entré un nom, faites "Entrée" de votre clavier. Le bouton "Next" va s'activer. Cliquez dessus. 5. Vous arrivez dans une nouvelles interface, avec plusieurs onglets. Cliquez sur librairies. 6. Encore une autre interface, avec plusieurs boutons. Cliquez sur ADD External Jars. Un menu va s'ouvrir pour charger les fichiers. 7. Les fichiers à charger sont dans le dossier sources de l'émulateur => libs. Vous sélectionnez tout les fichiers en même temps et vous cliquez sur "Ouvrir" 8. Votre projet est créé. Maintenant, faites comme dans les images suivante. 9. Cliquez sur la petite flèche à gauche du projet : 10. Vous voyez le dossier "src" à l'intérieur du projet ? Il faudra y déplacer à l'intérer 4 dossiers qui se situent dans les sources de l'émulateur. (En les déplaçant eclipse vous demandera une confirmation. cliquez simplement sur "ok" sans rien toucher.) 11. Voilà, vous avez décompilé vos sources ! A présent cliquez sur la flèche à gauche de "src" => "common". Double-cliquez sur "Constants.java" 12. Maintenant faites "CTRL + F" et recherchez cette ligne "public static final int STATS_ADD_DOMA" 13. Vous arrivez à la ligne recherchée et si cette ligne affiche "public static final int STATS_ADD_DOMA = 112; remplacez "112" par "121" : 13. Maintenant enregistrez en cliquant sur la petite disquette en-dessous du bouton "Edit". 14. Maintenant cliquez sur "File" => "Run as" => "Java application". C'est pour vérifier s'il n'y pas d'erreur. 15. Maintenant recliquez sur "File" => "Export" => Runnable JAR file => "Next" => "Launch configuration" Sélectionnez le nom de votre projet. Et pour "Export destination" faites "Browse" => DossierDeVotreEmu => et si vous avez ancestra.jar dans le dossier, renommez le fichier à exporter en "ancestra.jar" faites "Finish". Faites toujours "Ok", et si vous avez renommé comme il faut, eclipse vous dira que le fichier existe déjà et si vous voulez le remplacer. Faites "oui". 16. Voilà les sources sont recompilées. Il ne reste plus qu'à lancer votre serveur et de profiter à fond le jeu !! P.S : Merci de respecter mon travail. Pour toutes questions mon skype est disponible sur mon profil. Cordialement, Xyuka alias YellowLean.
  7. Bonjour, C'est la première fois que j'écris dans cette catégorie, j’espère donc ne pas faire de grosse erreur, et ne rien oublier ! 1. Présentation du cheat : Les cheats s'utilisent tous de la même façon : Par injection. Ce sont donc des dll qui s'injectent. Cette archive contient : -Injecteur 32 bits -Injecteur 64 bits -InviDropper -PickUp-Bot -SendAttackToTarget -Spam-Bot -Switch-Bot -Tools einstellen -Upp-Tool De quoi bien vous amusez. 2. Comment l'utiliser ? Vous allez donc ouvrir l'injecteur qui correspond à votre version (si vous ne connaissez pas votre version, tutoriel à la fin de celui si !), (votre antivirus peut ne pas l'aimer, mais pas de panique !). Une fois ouvert : -Appuyez sur Browse dll et rendez vous sur les dll que je vous ai fournis. -Vérifiez que la case "Deactivate" n'est pas cocher, sinon votre dll ne serait pas injecter. -Sélectionnez ensuite votre processus selon votre client. -Pour finir appuyez sur le bouton "Inject", et voilà ! J'espere que ça vous plaira ! Téléchargement : ici Lien virustotal : ici Cordialement. --- Download
  8. Citation de Azendar. [glow=red]Lien remplacé et fonctionnel, merci Ebrius.[/glow] ---------------------------------------------------------------------- Je vous partage le célèbre crack.exe de Ygg pour éviter de mettre la licence. Je ne me souviens plus qui a fait ce magnifique crack, m'enfin, je souhaite vous le partager quand même. crack.exe à mettre dans votre dossier d'Ygg. *Modification* Lien : clique ici (MegaU) VirusScan : clique ici (VirusTotal) Cordialement, Spyrow. --- Download
  9. Tutoriel Vemµ I : Téléchargements Il vous faudra les logiciels ci-dessous : Vemµ 0.2.2.0 : Ici II : Installation : Créer 3 bases de données sous Navicat : vemu_accounts vemu_characters vemu_others Puis importez les fichiers .sql(Execute SQL File) qui se trouvent dans le dossier SQL -> Base Exemple : vemu_accounts.sql dans la base de données vemu_accounts Ensuite, vous aurez des fichiers comme : vers_2_0_1 . Exécutez les patch qu'il y a à l'intérieur dans l'ordre des versions. III : Configuration : Dans votre dossier vemu vous trouverez 2 fichiers : engine.txt et realm.txt Ouvrez-les avec le bloc notes puis configurez engine.txt : SYSTEM_PORT = 4041 --> Port system USELESS_PORT = 481 GAME_ID = 1 --> ID du serveur ( De base : 1= Jiva ; 2= Rushu ) GAME_PORT = 5556 --> Port de jeux SQL_IP = localhost --> Laissez LocalHost si votre BDD se trouve sur votre ordinateur SQL_USER = root --> Nom d'utilisateur SQL_PASS = --> Mot de passe utilisateur SQL_ACCOUNTS = vemu_accounts SQL_CHARACTERS = vemu_characters SQL_OTHERS = vemu_others MSG_COLOR = #CC0000 --> Couleur du message de Bienvenue MSG_WELCOME = Bienvenue sur Vemu --> Message de Bienvenue MSG_ONCONNECT = false --> True pour activer ( Le joueurs **** vient de se connecter ) START_LEVEL = 160 --> Level de départ START_KAMAS = 10000000 --> Kamas de départ START_STATS = 0 --> Stats de départ ( 101 pour être parchotté partout ) START_MAP = 10279 --> Map de départ START_CELL = 284 --> Case de départ START_DIR = 3 --> Direction de départ ENABLE_AURA = true --> Activer les aura ENABLE_NIGHT = true --> Activer le passage jour<->nuit RATES_PVP = 1 --> Rate PVP ( Player vs Player ) RATES_PVM = 0 --> Rate PVM ( Player vs Monster ) ANTISPAM_COMMERCE = 30 --> Nombre de secondes entre 2 messages en /b ANTISPAM_RECRUITMENT = 30 --> Nombre de secondes entre 2 messages en /r CENSURED_WORDS = .save SHOW_INFOS = True SHOW_NOTICES = True SHOW_WARNINGS = True POINTS_NAME = Points realm.txt : LOGIN_VERSION = 1.29.1 LOGIN_PORT = 468 --> Port de connection SQL_IP = localhost --> Laissez LocalHost si votre BDD se trouve sur votre ordinateur SQL_USER = root --> Nom d'utilisateur SQL_PASS = --> Mot de passe utilisateur SQL_ACCOUNTS = vemu_accounts SQL_OTHERS = vemu_others SHOW_INFOS = false SHOW_NOTICES = false SHOW_WARNINGS = false MAX_PLAYER = 500 --> Nombre de joueurs maximum Voila le plus dur est fait! Maintenant allez dans la table vemu_others puis servers_list Supprimez les 2 lignes puis créez-en une nouvelle comme ceci : 1 | 127.0.0.1 | 5556 | 4041 IV : Configurer un 2ème serveur : Allez dans votre dossier vemu , créez une nouveau dossier puis coller dedans : - Engine.txt - MySql.Data.dll - Vemu - GameServeur.exe Puis configurez à nouveau le engine.txt Il vous suffit de changer Le SYSTEM_PORT (4042 par exemple) Le USELESS_PORT (482 par exemple) Le GAME_ID (2 par exemple) Le GAME_PORT (5557 par exemple) Puis de configurer le reste à votre guise Ensuite rajoutez une ligne à votre BDD : 1 | 127.0.0.1 | 5556 | 4041 2 | 127.0.0.1 | 5557 | 4042 Et lancez le Realm puis les 2 games servers . Bonne Lecture --- Download
  10. Bonjour, Je viens vous partager un CMS développer en Laravel 5.1 par Synthx sous un design réaliser par Nicow. Fonctionnalité : Pages classiques (CGU, Règlement, Staff, News, etc...) Gestion de compte Ladder Mises à jours Achat de points (Starpass) Mode VIP (désactivable) Loterie Vote par IP Confirmation du vote avec vérification de la valeur OUT Boutique avec stock Téléchargement : GitHub --- Download
  11. Coucou, Je viens vous montrer comment ajouter un format d'image supplémentaire lisible par votre lanceur. Dans le projet ScriptLib, ouvrez le dossier Resource.cpp et chercher: m_resManager.RegisterResourceNewFunctionPointer("bmp", NewImage); Ajouter en bas le format que vous voulez ajoutez ( donc pour moi png ): m_resManager.RegisterResourceNewFunctionPointer("png", NewImage);
  12. Bonjour, J'ai décidé de refaire ce tutoriel Aujourd'hui je vais vous expliquer comment ajouté l'option "détruire" lorsque vous voulez jeter un item. Ca va être assez long, mais facile si vous suivez bien le tutoriel. Commençons ______________________________________________________________________ PRÉREQUIS ______________________________________________________________________ 1.Des source Serveur 2.Des sources Client 3.Un client ______________________________________________________________________ 1.SOURCE SERVEUR ______________________________________________________________________ Ouvrez votre "packet.h" et recherchez: HEADER_CG_ITEM_DROP2 = 20, Ajoutez ceci juste en dessous: HEADER_CG_ITEM_DESTROY = 21, Recherchez maintenant: typedef struct command_item_drop2 { BYTE header; TItemPos Cell; DWORD gold; BYTE count; } TPacketCGItemDrop2; Ajoutez ceci juste en dessous: typedef struct command_item_destroy { BYTE header; TItemPos Cell; } TPacketCGItemDestroy; Ouvrez maintenant le fichier packet_info.cpp et recherchez: Set(HEADER_CG_ITEM_DROP2, sizeof(TPacketCGItemDrop2), "ItemDrop2", true); Ajoutez ceci juste en dessous: Set(HEADER_CG_ITEM_DESTROY, sizeof(TPacketCGItemDestroy), "ItemDestroy", true); Ouvrez maintenant le fichier input_main.cpp et recherchez la fonction: void CInputMain::ItemDrop2(LPCHARACTER ch, const char * data) Ajoutez cette fonction juste après: void CInputMain::ItemDestroy(LPCHARACTER ch, const char * data) { struct command_item_destroy * pinfo = (struct command_item_destroy *) data; if (ch) ch->DestroyItem(pinfo->Cell); } Cherchez maintenant ceci: case HEADER_CG_ITEM_DROP2: if (!ch->IsObserverMode()) ItemDrop2(ch, c_pData); break; Et ajoutez: case HEADER_CG_ITEM_DESTROY: if (!ch->IsObserverMode()) ItemDestroy(ch, c_pData); break; Ouvrez maintenant le fichier char_item.cpp et recherchez la fonction: bool CHARACTER::DropItem(TItemPos Cell, BYTE bCount) Ajoutez cette fonction juste au-dessus: bool CHARACTER::DestroyItem(TItemPos Cell) { LPITEM item = NULL; if (!CanHandleItem()) { if (NULL != DragonSoul_RefineWindow_GetOpener()) ChatPacket(CHAT_TYPE_INFO, LC_TEXT("°*È*âÀ» ¿¬ »óÅ¿¡¼*´Â ¾ÆÀÌÅÛÀ» ¿Å±æ ¼ö ¾ø½À´Ï´Ù.")); return false; } if (IsDead()) return false; if (!IsValidItemPosition(Cell) || !(item = GetItem(Cell))) return false; if (item->IsExchanging()) return false; if (true == item->isLocked()) return false; if (quest::CQuestManager::instance().GetPCForce(GetPlayerID())->IsRunning() == true) return false; if (item->GetCount() <= 0) return false; SyncQuickslot(QUICKSLOT_TYPE_ITEM, Cell.cell, 255); ITEM_MANAGER::instance().RemoveItem(item); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("L'item %s est desormais detruit."), item->GetName()); return true; } Ouvrez maintenant le fichier char.h et recherchez: bool DropItem(TItemPos Cell, BYTE bCount=0); Ajoutez ceci juste au-dessus: bool DestroyItem(TItemPos Cell); Ouvrez maintenant le fichier input.h et recherchez: void ItemDrop2(LPCHARACTER ch, const char * data); Ajoutez ceci juste en dessous: void ItemDestroy(LPCHARACTER ch, const char * data); ______________________________________________________________________ 2. SOURCE CLIENT ______________________________________________________________________ Ouvrez le fichier packet.h et recherchez: HEADER_CG_ITEM_DROP2 = 20, Ajoutez ceci juste en dessous: HEADER_CG_ITEM_DESTROY = 21, Recherchez maintenant: typedef struct command_item_drop2 { BYTE header; TItemPos pos; DWORD gold; BYTE count; } TPacketCGItemDrop2; Ajoutez ceci juste en dessous: typedef struct command_item_destroy { BYTE header; TItemPos pos; }TPacketCGItemDestroy; Ouvrez maintenant le fichier PythonNetworkStreamPhaseGameItem.cpp et recherchez la fonction: bool CPythonNetworkStream::SendItemDropPacketNew(TItemPos pos, DWORD elk, DWORD count) Ajoutez cette fonction juste en dessous: bool CPythonNetworkStream::SendItemDestroyPacket(TItemPos pos) { if (!__CanActMainInstance()) return true; TPacketCGItemDestroy itemDestroyPacket; itemDestroyPacket.header = HEADER_CG_ITEM_DESTROY; itemDestroyPacket.pos = pos; if (!Send(sizeof(itemDestroyPacket), &itemDestroyPacket)) { Tracen("SendItemDestroyPacket Error"); return false; } return SendSequence(); } Ouvrez maintenant le fichier PythonNetworkStreamModule.cpp et recherchez la fonction: PyObject* netSendItemDropPacket(PyObject* poSelf, PyObject* poArgs) Ajoutez cette fonction juste en dessous: PyObject* netSendItemDestroyPacket(PyObject* poSelf, PyObject* poArgs) { TItemPos Cell; if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) return Py_BuildException(); CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance(); rkNetStream.SendItemDestroyPacket(Cell); return Py_BuildNone(); } Recherchez maintenant: { "SendItemDropPacketNew", netSendItemDropPacketNew, METH_VARARGS }, Ajoutez ceci juste après: { "SendItemDestroyPacket", netSendItemDestroyPacket, METH_VARARGS }, Ouvrez maintenant le fichier PythonNetworkStream.h et recherchez la fonction: bool SendItemDropPacketNew(TItemPos pos, DWORD elk, DWORD count); Ajoutez ceci juste après: bool SendItemDestroyPacket(TItemPos pos); ______________________________________________________________________ 3. PYTHON CLIENT ______________________________________________________________________ Ouvrez le fichier uicommon.py du pack root et recherchez la class: class QuestionDialog(ui.ScriptWindow): Juste après celle class, ajoutez la class suivante: class QuestionDialogItem(ui.ScriptWindow): def __init__(self): ui.ScriptWindow.__init__(self) self.__CreateDialog() def __del__(self): ui.ScriptWindow.__del__(self) def __CreateDialog(self): pyScrLoader = ui.PythonScriptLoader() pyScrLoader.LoadScriptFile(self, "uiscript/questiondialogitem.py") self.board = self.GetChild("board") self.textLine = self.GetChild("message") self.acceptButton = self.GetChild("accept") self.destroyButton = self.GetChild("destroy") self.cancelButton = self.GetChild("cancel") def Open(self): self.SetCenterPosition() self.SetTop() self.Show() def Close(self): self.Hide() def SetWidth(self, width): height = self.GetHeight() self.SetSize(width, height) self.board.SetSize(width, height) self.SetCenterPosition() self.UpdateRect() def SAFE_SetAcceptEvent(self, event): self.acceptButton.SAFE_SetEvent(event) def SAFE_SetCancelEvent(self, event): self.cancelButton.SAFE_SetEvent(event) def SetAcceptEvent(self, event): self.acceptButton.SetEvent(event) def SetDestroyEvent(self, event): self.destroyButton.SetEvent(event) def SetCancelEvent(self, event): self.cancelButton.SetEvent(event) def SetText(self, text): self.textLine.SetText(text) def SetAcceptText(self, text): self.acceptButton.SetText(text) def SetCancelText(self, text): self.cancelButton.SetText(text) def OnPressEscapeKey(self): self.Close() return True Ouvrez maintenant le fichier game.py et cherchez la def suivante: def __DropItem(self, attachedType, attachedItemIndex, attachedItemSlotPos, attachedItemCount): Recherchez ce bout de code dans la fonction (2x): itemDropQuestionDialog = uiCommon.QuestionDialog() Remplacez par: itemDropQuestionDialog = uiCommon.QuestionDialogItem() Toujours dans la même fonction, recherchez: itemDropQuestionDialog.SetAcceptEvent(lambda arg=True: self.RequestDropItem(arg)) Ajoutez ceci juste après: itemDropQuestionDialog.SetDestroyEvent(lambda arg=True: self.RequestDestroyItem(arg)) Recherchez maintenant la fonction: def RequestDropItem(self, answer): Ajoutez cette fonction juste après: def RequestDestroyItem(self, answer): if not self.itemDropQuestionDialog: return if answer: dropType = self.itemDropQuestionDialog.dropType dropNumber = self.itemDropQuestionDialog.dropNumber if player.SLOT_TYPE_INVENTORY == dropType: if dropNumber == player.ITEM_MONEY: return else: self.__SendDestroyItemPacket(dropNumber) self.itemDropQuestionDialog.Close() self.itemDropQuestionDialog = None constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) Recherchez ensuite la fonction: def __SendDropItemPacket(self, itemVNum, itemCount, itemInvenType = player.INVENTORY): Et ajoutez celle-ci juste après: def __SendDestroyItemPacket(self, itemVNum, itemInvenType = player.INVENTORY): if uiPrivateShopBuilder.IsBuildingPrivateShop(): chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.DROP_ITEM_FAILURE_PRIVATE_SHOP) return net.SendItemDestroyPacket(itemVNum) Ouvrez maintenant le fichier locale_interface.txt et ajoutez ceci: DESTROY Destroy Placez le fichier questiondialogitem.py dans votre pack uiscript ! LIEN FE Screen du système: Voilà c'est fini ! Source du totoriel : .Avenue™ de Metin2Dev Traduction: moi Cordialement, #Saw.
  13. Bonjour à tous ! Un petit message d'introduction et on commence ! Tout d'abord merci à @Nicky31 pour son tutoriel qui représente une très grande partie de ce poste ! Je me permets de le reprendre pour corriger/apporter des éléments qui bloquaient pas mal de monde. Durée approximative : 10 à 30 en fonction de votre qualification. L'avantage d'Ancestra Remake 54 est le multi-serveurs (Il peut gérer plusieurs serveurs). Commençons ! 1 - Pré-Requis Disposer d'Ancestra Remake 54 Disposer d'une IP de connexion (Hamachi, No-Ip, dédié ...), à vous de voir ce que vous préférez. Hamachi : Simule un réseau local. No-Ip : Redirige sur votre IP accessible ici quand votre opérateur ne vous permet pas de la garder fixe. Dédié : Sur un autre PC constamment allumé fait maison ou loué en ligne. Hébergeur conseillé : Kimsufi / soyoustart. Disposer de WampServer (gratuit) et de Navicat (crack ou payé) sauf si vous savez vous débrouiller avec PhpMyAdmin Disposer de Dofus 1.29 (Certaines personnes ont des problèmes lors du lancement du client Dofus lorsqu'ils n'installent pas Dofus 1.29 dans Program Files (x86) ). 2 - Installer les base de données En premier lieu, l'émulateur a besoin, pour fonctionner, de deux bases de données. Je vais expliquer la procédure via Navicat, si vous utilisez PhpMyAdmin je pense que vous saurez vous débrouiller tout seul. Si ce n'est pas déjà fait, commencez par installer Wamp & Navicat. Lancez Wamp puis Navicat en attendant que Wamp passe au vert dans votre barre des tâches. Si Wamp ne passe pas vert (vous pouvez passer cette étape si c'est le cas), le problème vient probablement d'une interférence avec skype. Dans skype: Outils -> Options -> Avancées -> Connexion -> Décocher "Utiliser les ports 80 et 443 comme alternative". Redémarrez Skype & Wamp [*]Ouvrez Navicat, cliquez sur Connection -> MySQL [*]Mettez seulement localhost à Connection Name et un mot de passe de votre choix à Password (non obligatoire mais bon). Ne touchez pas à ce qui est déjà rempli, faites Ok [*]Double cliquez sur localhost normalement apparu dans la colonne de gauche de Navicat. (Afin d'ouvrir la connexion) [*]Click droit sur localhost (votre connexion), puis clickez sur New Database [*]Ecrivez ancestra_realm dans Enter database name puis clickez sur OK. [*]Répétez la même opération pour une bdd du nom de ancestra_game [*]Comme pour la connexion, double clickez sur vos deux bases de données afin de les "ouvrir" (cela s'affichera en vert) [*]On va maintenant importer des données dans nos deux bdd à partir de fichiers .sql: Click droit sur ancestra_realm, puis Execute Batch File et ciblez AncestraR_Realm.sql contenu dans le dossier AR54/BDD, puis faites Start [*]Répétez la même opération pour remplir ancestra_game à partir du fichier AncestraR_Game.sql, toujours situé dans le même dossier. Vous voilà maintenant avec vos deux bases de données crées, remplies, prêtes mais ... non à jours J'vous jure, j'vous ai pas fait faire de la *****, juste que les développeurs d'AR ont dû rectifier des choses sur les bases de données, et au lieu de mettre à jour les deux gros patchs qu'on vient d'exécuter, ont mis chaque rectification dans un fichier .sql à part. Tous ces fichiers .sql, vous pouvez les trouver dans le sous dossier BDD/Patchs. Attention ! Vous ne devez pas les exécuter n'importe comment. Vous pouvez observer que le nom de chaque fichier suit cette logique: AncestraR_Realm/Game - Patch revN°Patch - Infos sur contenu.sql Realm/Game correspond à la bdd sur laquelle doit être appliqué le patch. N°Patch correspond au numéro du patch (ils sont tous numérotés) Infos sur contenu correspond à quelques infos sur le contenu du patch. Vous devez exécuter tous ces patchs en faisant attention à le faire sur la bonne base de données, et dans l'ordre croissant des numéros. Exemple pour la db game: AncestraR_Game - Patch rev2 - Pets.sql en premier AncestraR_Game - Patch rev3 - Defenders of resources.sql en deuxième ... PS : Ne vous inquiétez pas "Patch rev5" affiche un message d'erreur dans les logs mais ce n'est pas grave. Au boulot ! Une fois ceci fait, vous aurez vos deux bases de données enfin prêtes et complètes. Nous pourrons alors passer à la configuration de l'émulateur en lui même 2(bis) - Survol du fonctionnement d'un Emulateur La particularité d'AR54 qui m'a poussé à faire un tuto sur son installation (alors qu'il y a déjà des tutos pour d'autres versions d'AR), c'est que la différence de fonctionnement entre cette version et celles antérieures complique sa configuration. Voilà comment fonctionne normalement un émulateur, dissocié en deux parties realm et game : Le client se connecte sur la partie realm. Il choisit son serveur, et le realm lui renvoi l'ip et le port du game gérant le serveur demandé. Le client coupe alors la connexion avec le realm pour se connecter au game Le game gère tout le reste du jeux. Il doit néanmoins communiquer avec le realm pour avoir certaine données. Dans les versions précédentes, le multi-serveur n'était pas géré: on ne pouvait alors avoir qu'un serveur, et il n'était plus utile d'avoir cette organisation avec une application realm et une autre pour chaque serveur. Les développeurs ont donc fusionné ces deux applications en une seule. De cette façon, le client restait tout le temps connecté sur la même application (pas tout à fait en réalité, mais on entrerait dans les détails techniques). Au niveau de la configuration; on n'avait qu'une config pour une application, avec une ip & un port à renseigner pour l'unique application. Avec le multi-serveur, les développeurs ont du dissocier le realm et le game : Un seul realm (serveur de connexion), et un game par serveur. Il faut donc à présent une config par appli' (deux pour un seul serveur), et des ips & ports en plus. En résumé, il nous faut: L'ip du realm et son port de connexion (celui sur lequel le client se connecte) L'ip de chaque serveur & leur port de connexion (donnés par le realm au client). Pour ne pas compliquer les choses, nous allons gérer qu'un serveur Le port de communication utilisé entre le realm et les games. L'identifiant de chaque game ; c'est avec celui-ci que le realm s'assure qu'il à affaire aux games attendus. (Sinon n'importe quel personne tierce pourrait connecter son propre game modifié) 3 - Configurer Ancestra Remake 54 La partie précédente n'était pas vraiment prévue, mais j'ai trouvé intéressant de parler du fonctionnement de l'émulateur, ça peut aider certains à comprendre certains éléments. Bon, la première étape est de faire connaître au realm notre game. Et une table de notre db realm est prévue pour cela. Une table ??? Kézako !? Voilà une nouvelle notion pour nous, jeunes padawans que nous sommes. Une table n'est rien d'autre qu'une partie d'une base de données, regroupant donc un certains nombre d'informations à propos d'une chose précise, informations organisées comme un tableau. D'où le nom table, qui en anglais signifie tableau. 1 - Base de Données Rendez vous dans ancestra_realm Double clickez sur la table gameservers Une fenêtre s'ouvre alors. Voilà que s'affiche le contenu de notre table. L'unique ligne affichée devrait être celle-ci : Colonnes en italiques id | ServerIP | ServerPort | State | ServerBDD | ServerDBName | ServerUser | ServerPassword | key 1 | 127.0.0.1 | 5555 | 0 | 127.0.0.1 | ancestra_game | root | | server1 L'id correspond à l'id du serveur. Vous pouvez trouver tous les fichiers d’emblème des serveurs dans Dofus/clips/artworks/servers. Leur nom correspond à leur id. Pour ma part je m'en fou un peu donc je laisse 1. IP de la machine qui aura le game. Donc votre ip hamachi/no-ip/dédié ou 127.0.0.1 si vous voulez tester en localhost. On laisse aussi 5555 au ServerPort, c'est ce port ainsi que la serverIP que le realm enverra au client pour qu'il se connecte au game. State, c'est l'état du serveur: 0 pour hors ligne, 1 en ligne, 2 sauvegarde. On laisse 0, le realm s'occupe de le mettre à 1 quand il reçoit la connexion du game. ServerBDD ; l'ip de notre db game. S'il est sur la même machine que le game vous pouvez laisser 127.0.0.1, sinon mettez son ip. ServerDbName ; le nom de la db game correspondante, on laisse ancestra_game (sauf si vous l'avez appelé autrement) ServerUser ; le nom d'utilisateur de la connexion à la db. Si vous ne l'avez pas changé depuis l'installation, c'est toujours root ServerPassword ; le mot de passe de la connexion à la db. Si vous n'en avez pas mit, il y en a pas. key ; c'est la clé qui identifie le game & qu'il devra donner au realm. Je décide de la laisser telle quelle, gardez la en mémoire si vous la changez. 2 - Configuration du realm A présent, direction AR54/Realm/Realm_Config.txt : REALM_PORT : Port de connexion à mettre dans la config.xml, on va prendre 444 REALM_COM_PORT : Port de communication entre le realm & les game. On prend 489 Je vous laisse configurer les identifiants de votre db realm. Dans le cas ou vous avez fait le tutoriel à la lettre ; vous êtes censé mettre : REALM_DB_HOST = 127.0.0.1 REALM_DB_USER = root REALM_DB_PASSWORD = REALM_DB_NAME = ancestra_realm Warning Si vous n'avez pas mis de mot de passe (password) ; n'oubliez pas de laisser un espace après le "=" sinon le serveur ne se lancera pas. 3 - Configuration du game Direction AR54/Game/Game_Config.txt: REALM_IP : l'ip hamachi/no-ip/dédié de la machine hébergeant le realm. Configurez l'accès à la db realm. Comme pour la partie db, mettez 127.0.0.1 si la db est sur la même machine que le game. HOST_IP : Ip hamachi/no-ip/dédié de la machine hébergeant le game. AUTH_KEY : La clé que vous avez indiqué dans la colonne key de la db GAME_PORT: Le port de connexion du game, que vous avez indiqué dans la colonne ServerPort (5555 dans ce tutoriel) COM_PORT : Port de communication entre le game & le realm. Il doit être identique à celui que nous avons mis dans la config realm, soit 489 PLAYER_LMIT : Ne pas laisser -1, il provoque un bug à la connexion au serveur (Merci à @Défense pour l'infos). Mettez donc une autre limite de joueurs, comme 100. Configurez l'accès à la db game de la même façon que pour la realm. Dans le cas ou vous avez fait le tutoriel à la lettre ; vous êtes censé mettre : #Configuration de la base de donnée du serveur de connexion REALM_DB_HOST = 127.0.0.1 REALM_DB_USER = root REALM_DB_PASS = REALM_DB_NAME = ancestra_realm # Configuration de la base de donnée DB_HOST = 127.0.0.1 DB_USER = root DB_PASS = DB_NAME = ancestra_game 4 - Configuration des .bat pour démarrer le realm et le game Ouvrez avec un éditeur de .txt les fichiers "startRealm.bat" du dossier "realm" et "game". Vous devez à présent renseigner la localisation de votre "java.exe". Dans mon cas : @echo off title Ancestra Remake rev 54 :loop "C:\Program Files\Java\jre1.8.0_191\bin\java.exe" -jar -Xmx1024m -Xms1024m Ancestra.jar goto loop PAUSE Petite astuce pour avoir votre chemin rapidement : - Cherchez votre java.exe qui devrait se trouver dans "Programmes". - Créez un raccourci sur le bureau - Clique droit sur le raccourci puis "propriété" - Copier le contenu de "Cible :" La partie "-Xmx1024m -Xms1024m" correspond à la ram que vous allouez à votre serveur. Ici 1024m donc 1G de ram. Normalement, vous avez à présent Ancestra Remake bien installé et configuré. Il ne reste plus qu'à indiquer au client Dofus l'ip et le port de connexion du realm. 5 - Configuration du client DOFUS Ne vous inquiétez pas, c'est beaucoup plus simple que pour l'émulateur. Direction Dofus/config.xml, remplacez tout le contenu par ceci : <config> <delay value="500"/> <rdelay value="3000"/> <rcount value="10"/> <conf name="En ligne"> <connserver ip="Adresse ip du serveur" name="Nom de votre serveur" port="Port du realm"/> <dataserver url="data/" type="local" priority="3" /> <dataserver url="[Hidden Content]" priority="1" /> <dataserver url="[Hidden Content]" priority="0" /> </conf> <conf name="En ligne (TEST)" type="test"> <dataserver url="data/" type="local" priority="3" /> <dataserver url="[Hidden Content]" priority="1" /> <dataserver url="[Hidden Content]" priority="0" /> </conf> <cacheasbitmap> <cache element="ExternalContainer/InteractionCell" value="false" /> <cache element="ExternalContainer/Ground" value="false" /> <cache element="ExternalContainer/Object1" value="false" /> <cache element="ExternalContainer/Object2" value="false" /> <cache element="ExternalContainer/Zone" value="false" /> <cache element="ExternalContainer/Select" value="false" /> <cache element="ExternalContainer/Grid" value="false" /> <cache element="ExternalContainer/Pointer" value="false" /> <cache element="GAPI/UI" value="false" /> <cache element="GAPI/UITop" value="false" /> <cache element="GAPI/Popup" value="false" /> <cache element="GAPI/UIUltimate" value="false" /> <cache element="GAPI/Cursor" value="false" /> <cache element="mapHandler/BACKGROUND" value="false" /> <cache element="mapHandler/Cell/Ground" value="false" /> <cache element="mapHandler/Cell/Object1" value="false" /> <cache element="mapHandler/Cell/Object2" value="false" /> <cache element="mapHandler/Cell/ObjectExternal" value="false" /> <cache element="Zone/Zone" value="true" /> <cache element="Zone/Pointers" value="true" /> </cacheasbitmap> </config> Remplacez de la ligne suivante par ce qui est demandé. <connserver ip="Adresse ip du serveur" name="Nom de votre serveur" port="Port du realm"> Exemple : <connserver ip="127.0.0.1" name="Serveur tuto" port="444"/> Si vous avez bien suivi ce tutoriel, vous devriez normalement mettre 444 pour le port du realm. Le nom du serveur ne dépend de rien de ce qu'on à fait avant. A présent que tout est en place, il ne reste qu'à lancer l'émulateur : En premier le Realm en lançant AR54/Realm/startRealm.bat puis le Game en lançant AR54/Game/startRealm.bat. (Vous pouvez renommer celui la en startGame.bat) Et voilà, distribuez la config.xml à vos joueurs, et votre serveur est en place ! Si vous avez des difficultés malgré le tutoriel je vous laisse les 3 configs que nous avons vu réglé pour faire tourner votre serveur en réseau local. Je conseille tout de même d'essayer un minimum pour ne pas être décourager pour la suite ! Game_Config.txt Realm_Config.txt config.xml Je me ferai une joie de répondre à vos questions et d'avoir des suggestions pour améliorer le contenu. Encore une fois, le tutoriel n'est pas de moi, j'ai seulement corrigé quelques parties causants des problèmes à beaucoup et apporter des précisions en accord avec @Calypso. Bonne chance à tous ! --- Download
  14. Bonjour, Bonsoir Les Funkiest, je vous partage un système qui va vous permettre de stocker vos items Up, Pierre, Manuel dans différents inventaires. Niveau requis : Intermédiaire Temps estimé : 30 minutes Pré-requis: - Sources Client - Sources Serveur - Client Tout se trouve dans le dossier, tout est expliquer la dedans. Download Aperçu : [Hidden Content] Sources : Turkmmo Pour continuer: Vous trouverez de nombreux partages et tutoriels sur Funky-Émulation dans la section Metin2. La FAQ pourra répondre à la plupart de vos questions. Une catégorie support est disponible. Si vous avez un problème ou une question, n'hésitez pas à poster une demande !
  15. Bonjour, Granny 2.9.12 Granny 2.11.8 Granny 2.8.41 Cordialement, History. --- Download
  16. Yep, Vous connaissez sans doutes les fameuses file 2013, avec les tools qui permettent de générer le côté client grâce au côté serveur. Mais malheureusement, certains n'arrivent plus à dump ces protos car ils sont beaucoup trop récents ... Bah ici, c'est la même chose ! Il suffit de mettre l'exe dans un dossier avec l'item proto et l'item name txt (ou mob), de les faire glisser sur le exe le tour est joué ! De plus, il prend en compte les nouveaux mob proto donc les nouvelles colonnes ! Téléchargement: [Hidden Content] --- Download
  17. Bonjour à tous, ce tutoriel a pour but de recenser et de détailler les bonus présents sur Metin2. Tous les implanteurs en ont une. C'est indispensable. Mais avec les files 2013, 13 nouveaux bonus sont apparus. De plus, l'affichage de ces bonus a été modifié avec l'apparition des fichier item_proto.txt, où connaître le n° du bonus n'est plus suffisant ! Il est donc grand temps de dépoussiérer cette vieille liste et de comprendre, enfin, à quoi tout correspond. À savoir : La mise en place suit ce schéma : APPLY_MAX_HP : Points de vie maximum +X 1 : numéro du bonus correspond au numéro que vous trouverez dans item_proto.xml (client), item_proto.sql, item.sql (base de données) APPLY_MAX_HP : nom du bonus correspond au nom que vous trouverez dans le fichier item_proto.txt (pour les files 2013+) (inutile pour les files 2012-) Points de vie maximum +X : traduction approximative du bonus (X étant la puissance du bonus) Certains bonus peuvent varier selon si on regarde du point de vue du joueur ou du point de vue du monstre Le tutoriel est long, les informations nombreuses, il est possible que des erreurs soient présentes, si tel est le cas, n'hésitez pas La liste : (complète pour les files 2014) : (si la team FE a altéré des bonus sur les files 2016, merci de le signaler, sinon les informations restent inchangées) (certains bonus ne sont pas détaillés car ils sont connus par tout le monde) Et voilà ! Ce fut laborieux mais vous avez tout ! À vous de jouer ! À rajouter : nom bonus 82, 83, 84 lien vers un tuto qui modifier les limites sur les sources (VD, VA... etc) lien vers un tuto sur la table skill_proto (notamment pour les bonus FIRE/ELEC/WIND) lien vers un tuto sur la table/fichier mob_proto (notamment pour les bonus contre les races de monstres ou l'immunité contre la réflection) plus de détails pour les nouveaux bonus la mise en page est lourde, si quelqu'un a une meilleure idée pour présenter ça... (screen d'un tableau ?)
  18. Bonjour, Bonsoir Je vous partage un système de magasin Hors Ligne qui est debug par rapport à celui qui est déjà partagé sur FE pars History/Liberty. Niveau requis : Intermédiaire Temps estimé : 30 minutes Pré-requis: - Sources Serveur - Sources Client - Client Download Un aperçu du système ( Je ne suis pas la personne qui à fait la vidéo ) : PS : Je n'ai pas testé le Partage de History/Liberty mais on ma dit qu'il ne fonctionnait pas si je me trompe merci de faire signe. Sources : Turkmmo Pour continuer: Vous trouverez de nombreux partages et tutoriels sur Funky-Émulation dans la section Metin2. La FAQ pourra répondre à la plupart de vos questions. Une catégorie support est disponible. Si vous avez un problème ou une question, n'hésitez pas à poster une demande !
  19. Salut à tous ! Je vous partage aujourd'hui une exclusivité de emulation-bay crée par Agronaque alias Rayz. Un petit bijoux attirant vos joueurs à voter ! Description : La quête Vote4BeTheBest.quest vous servira à faire voter vos joueurs pour votre serveur. En guise de récompense, ils gagneront un bonus simple dans une branche particulière (maxhp, def, attaque, magie) Version 1.0 Version 1.1 Vous vous loguez et vous recevez une lettre directement nommée "Votez et gagnez un bonus". Il vous suffit de cliquer dessus afin de voter dans le vote1, 2 ou 3 et ainsi gagner un petit bonus pour améliorer votre personnage. Si vous êtes GM, vous aurez droit au panel de configuration des adresses topsite et à une page internet Google simple. Vidéo :
  20. Bonjour, J'ai remarqué que beaucoup n'arrivaient plus à avoir la version v1.3 du repacker de Moustikk du à un problème de mises à jour... Bien à vous, --- Download
  21. Bonjour, aujourd'hui je vous partage le logiciel Flash Decompiller Trillix 5.3.1370. Ce programme sert à ouvrir les fichiers en .swf Vous pouvez vous en servir pour changer l'image du chargement de votre rétro par exemple ! Liens mega : ici Scan : ici Tutoriel : Il est déjà intégré dans l'archive, mais je l'explique quand même ici avec quelques screens ! Vous allez installer le programme qui se trouve dans Setup en prenant soins de décocher la case pour le lancer à la fin ! Je vous détaille l'installation même si je pense que vous savez faire... Sélectionnez votre langue puis, puis faite "OK" Faites suivants : Faites ensuite l'installation standard, c'est très important ! Après, faite attention à ne pas cocher cette case : SURTOUT PAS Allez ensuite dans sur votre bureau : Faites CLIQUES DROIT sur "Flash Decompiler Trillix.exe" (un menu déroulant s'affichera), et cliquez sur "Ouvrir l'emplacement du fichier". maintenant, vous avez les deux dossier "Program Files (x86)\Eltima Software\Flash Decompiler Trillix" & "Flash Decompiler Trillix 5.3.1370 cracked" Dans le dossier "Flash Decompiler Trillix 5.3.1370 cracked", glissez le programme "FlashDecompiler.exe" dans le dossier "Program Files (x86)\Eltima Software\Flash Decompiler Trillix" Et voilà c'est cracker. Bon jeu à vous Cordialement. --- Download
  22. Salut à tous, voici une petite API pour les votes sur RPG paradize. En gros elle fait : Récupère le captcha de la page de vote. Envoi le formulaire de vote. Regarde si le vote a été accepté et retourne true ou false. Donc au final plus besoin de faire une redirection vers RPG Paradize, et seul les bon votes seront comptés, et tout ça, très simplement ! RpgApi.php : ICI Exemple : ICI L'utilisation d'un tel système est relativement lourd, il est donc préférable de ne pas trop charger la page de vote. --- Download
  23. Bonjour à tous, Je viens encore une fois aujourd'hui vous faire part d'un plus gros travail que le client, cela concerne le translate.lua Ce fichier n'est pas encore complètement traduit mais j'y travaille. [Hidden Content] Enjoy --- Download
  24. Bonjour à tous, Ayant reçu et vu plusieurs demandes d'aide sur l'installation d'une machine virtuelle permettant de compiler tout en lançant les files ainsi que des personnes qui souhaitaient des liens autres que MEGA pour le VDI actuelle. J'ai décidé de me lancer dans la création d'une nouvelle machine virtuelle sous la version 9.2 32bit de FreeBSD, je vais vous expliquer ci-dessous les raisons pour lesquelles j'ai choisi cette version ainsi que les fonctionnalités de la VM. Sommaire : Pourquoi avoir choisi cette version de FreeBSD? Quelles sont les fonctionnalités de cette VM? Listing des packages installées sur la VM. Choses à savoir Donc commençons Pourquoi avoir choisi cette version de FreeBSD? Ça va être assez simple, la version 9.2 de FreeBSD reste la plus compatible avec les files Metin2, la version 9.3 fait aussi l'affaire mais il s'avère qu'elle pose quelques problèmes au niveau des fetch (permettant de télécharger via un lien), donc j'ai préféré ne pas la choisir. Ensuite, les versions beaucoup plus supérieures, à la 10 et au-dessus, la version de gcc (compilateur du game/db) n'est plus installée par défaut, ce qui veut dire que la version 4.2 n'est plus accessible d'installation via les ports/pkg (à ma connaissance). De ce fait vous ne pourrez donc pas compiler avec une version supérieure de gcc au dessus de la "4.2". Autrement, vous ne pourrez pas compiler les sources sans faire des modifications au niveau des libs/makefile et une dizaine de fichier serveur. Vous pouvez toujours installer une version supérieure de gcc et supprimer celle installée par défaut, vous êtes libre de faire ce que vous voulez. Quelles sont les fonctionnalités de cette VM? Alors, cette machine virtuelle a été créée dans le but d'être la plus compréhensible possible afin de pouvoir être utilisée par tout type de personnes, quel que soit leur niveau dans ce domaine. Tout d'abord, l'heure sera mise à jour automatiquement par le réseau informatique FreeBSD, le protocole utilisé pour permettre ceci est "ntpd", il peut être désactivé par le biais du ficher rc.conf du répertoire etc. Par la suite, MySQL a été optimisé de sorte à ce qu'il se mette en cache automatiquement, permettant ainsi l'ouverture rapide de votre serveur et d'éviter au maximum les connexions refused. La machine virtuelle a été défragmenté et compactée de sorte à être beaucoup plus rapide et légère par les services proposés par "VMware". Les packages ont étés installés par l'utilitaire "pkg" et il vous permet donc de les supprimer afin d'augmenter leurs versions ou les rétrograder. Par exemple pour mettre mysql56 au lieu de la 55 vous tapez juste "pkg remove mysql55-server" et une fois la désinstallation finie vous tapez "pkg install mysql56-server". Listing des packages installés sur la VM Chose à savoir Les files installées sur cette machine virtuelle sont les 2016, les files ont été éteintes, quêtes rechargées et les logs nettoyés pour éviter une surcharge inutile du VDI. Pour les sources, ceux-ci sont compilables, je me suis permis de régler le TIME BOMB pour que les files puissent se lancer sans soucis et pour que vous puissiez lancer les files directement, le MakeFile a été modifié de sorte à ce que vous puissiez obtenir un game et un db strippé ainsi que la version originale optimisée. Cependant, les sources ont été archivées au format .tar.gz pour éviter par la même occasion une surcharge du VDI au niveau de la taille, il se situe dans /usr/src/ vous aurez juste à entrer la commande "cd /usr/src && tar -zxvf mainline.tar.gz". Si vous ne savez pas compiler vous pouvez suivre le tutoriel de Calypso. Liste des modifications apportés sur les files Pour toute demande d'aide, veuillez poster dans la section appropriée qui est celle-ci. Cette machine virtuelle pourra être mis à jour à la demande des membres. La machine virtuelle a été upload au format .VDI pour ceux utilisant virtualbox ainsi qu'au format .VMDK pour ceux qui comme moi utilise VMware. Ils possèdent une taille de 9GO6 non compressés et une taille de 2GO compressé. Amusez-vous bien ! Le client/source client etc seront disponible en téléchargement directement sur le sujet des Files 2016 après approbation de @Calypso @ASIKOO @Mei Liens VDI : Cliquez ici pour télécharger Mirror (1) Liens VMDK : Cliquez ici pour télécharger Mirror (1) Liens Files Mirrorace: MEGA Liens Sources Mirrorace: MEGA: Le mot de passe MYSQL/SSH est : funky-emu Voilà, j'espère que celles-ci vous auront aider. La vie ou la mort, faîtes votre choix. Cordialement, --- Download #Saw.
  25. Bonjour à tous, je vous partage donc un partage d'epvps pour ne plus avoir besoin de txt et reprendre donc l'ancien systeme via mysql. Pour ce faire on se rend donc dans ClientManagerBoot.cpp qui se trouve donc dans mainline/srcs/server/db/src. Ensuite il vous faudra remplacer bool CClientManager::InitializeItemTable() { //================== ÇÔ¼ö ¼³¸à ==================// //1. ¿ä¾à : 'item_proto.txt', 'item_proto_test.txt', 'item_names.txt' ÆÄÀÃÀ» ÀðÃ, // (TItemTable), ¿ÀºêçƮ¸¦ »ý¼ºÇÑ´Ù. //2. ¼ø¼ // 1) 'item_names.txt' ÆÄÀÃÀ» ÀÃ¾î¼ (a)[localMap](vnum:name) ¸ÊÀ» ¸¸µç´Ù. // 2) 'item_proto_text.txt'ÆÄÀðú (a)[localMap] ¸ÊÀ¸·Î // (b)[test_map_itemTableByVnum](vnum:TItemTable) ¸ÊÀ» »ý¼ºÇÑ´Ù. // 3) 'item_proto.txt' ÆÄÀðú (a)[localMap] ¸ÊÀ¸·Î // (!)[item_table], À» ¸¸µç´Ù. // <Âü°Ã> // °¢ row µé Ãß, // (b)[test_map_itemTableByVnum],(!)[mob_table] ¸ðµÎ¿¡ ÀÖ´Â row´Â // (b)[test_map_itemTableByVnum]ÀÇ °ÃÀ» »ç¿ëÇÑ´Ù. // 4) (b)[test_map_itemTableByVnum]ÀÇ rowÃß, (!)[item_table]¿¡ ¾ø´Â °ÃÀ» Ãß°¡ÇÑ´Ù. //3. Å×½ºÆ® // 1)'item_proto.txt' 亸°¡ item_table¿¡ Àß µé¾î°¬´ÂÃö. -> ¿Ã·á // 2)'item_names.txt' 亸°¡ item_table¿¡ Àß µé¾î°¬´ÂÃö. // 3)'item_proto_test.txt' ¿¡¼ [°ãÄ¡´Â] 亸°¡ item_table ¿¡ Àß µé¾î°¬´ÂÃö. // 4)'item_proto_test.txt' ¿¡¼ [»õ·Î¿î] 亸°¡ item_table ¿¡ Àß µé¾î°¬´ÂÃö. // 5) (ÃÖþ) °ÔÀÓ Ŭ¶óÀ̾ðÆ®¿¡¼ æ´ë·Î ÀÛµ¿ ÇôÂÃö. //_______________________________________________// //=================================================================================// // 1) 'item_names.txt' ÆÄÀÃÀ» ÀÃ¾î¼ (a)[localMap](vnum:name) ¸ÊÀ» ¸¸µç´Ù. //=================================================================================// bool isNameFile = true; map localMap; cCsvTable nameData; if(!nameData.Load("item_names.txt",'\t')) { fprintf(stderr, "item_names.txt was loaded successfully.\n"); isNameFile = false; } else { nameData.Next(); while(nameData.Next()) { localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1); } } //_________________________________________________________________// //=================================================================// // 2) 'item_proto_text.txt'ÆÄÀðú (a)[localMap] ¸ÊÀ¸·Î // (b)[test_map_itemTableByVnum](vnum:TItemTable) ¸ÊÀ» »ý¼ºÇÑ´Ù. //=================================================================// map test_map_itemTableByVnum; //1. ÆÄÀà Àþî¿À±â. cCsvTable test_data; if(!test_data.Load("item_proto_test.txt",'\t')) { fprintf(stderr, "item_proto_test.txt was loaded successfully.\n"); //return false; } else { test_data.Next(); //¼³¸à ·Î¿ì ³Ñ¾î°¡±â. //2. Å×½ºÆ® ¾ÆÀÌÅÛ Å×ÀÌºà »ý¼º. TItemTable * test_item_table = NULL; int test_itemTableSize = test_data.m_File.GetRowCount()-1; test_item_table = new TItemTable[test_itemTableSize]; memset(test_item_table, 0, sizeof(TItemTable) * test_itemTableSize); //3. Å×½ºÆ® ¾ÆÀÌÅÛ Å×À̺ÿ¡ °ªÀ» ³Ö°Ã, ¸Ê¿¡±îÃö ³Ö±â. while(test_data.Next()) { if (!Set_Proto_Item_Table(test_item_table, test_data, localMap)) { fprintf(stderr, "¾ÆÀÌÅÛ Ç÷ÎÅä Å×ÀÌºà ¼ÂÆà ½ÇÆÃ.\n"); } test_map_itemTableByVnum.insert(std::map::value_type(test_item_table->dwVnum, test_item_table)); test_item_table++; } } //______________________________________________________________________// //========================================================================// // 3) 'item_proto.txt' ÆÄÀðú (a)[localMap] ¸ÊÀ¸·Î // (!)[item_table], À» ¸¸µç´Ù. // <Âü°Ã> // °¢ row µé Ãß, // (b)[test_map_itemTableByVnum],(!)[mob_table] ¸ðµÎ¿¡ ÀÖ´Â row´Â // (b)[test_map_itemTableByVnum]ÀÇ °ÃÀ» »ç¿ëÇÑ´Ù. //========================================================================// //vnumµéÀ» ÀúÀåÇÒ ¼Â. »õ·Î¿î Å×½ºÆ® ¾ÆÀÌÅÛÀ» ÆǺ°ÇÒ¶§ »ç¿ëµÈ´Ù. set vnumSet; //ÆÄÀà Àþî¿À±â. cCsvTable data; if(!data.Load("item_proto.txt",'\t')) { fprintf(stderr, "item_proto.txt was loaded successfully.\n"); return false; } data.Next(); //¸Ç ÀÃ٠æ¿Ü (¾ÆÀÌÅÛ Ä®·³À» ¼³¸ÃÇô ºÎºÃ) if (!m_vec_itemTable.empty()) { sys_log(0, "RELOAD: item_proto"); m_vec_itemTable.clear(); m_map_itemTableByVnum.clear(); } //===== ¾ÆÀÌÅÛ Å×ÀÌºà »ý¼º =====// //»õ·Î Ãß°¡µÇ´Â °¹¼ö¸¦ ÆľÇÇÑ´Ù. int addNumber = 0; while(data.Next()) { int vnum = atoi(data.AsStringByIndex(0)); std::map::iterator it_map_itemTable; it_map_itemTable = test_map_itemTableByVnum.find(vnum); if(it_map_itemTable != test_map_itemTableByVnum.end()) { addNumber++; } } //data¸¦ ´Ù½Ã ùÃÙ·Î ¿Å±ä´Ù.(´Ù½Ã Àþî¿Â´Ù; data.Destroy(); if(!data.Load("item_proto.txt",'\t')) { fprintf(stderr, "item_proto.txt was loaded successfully.\n"); return false; } data.Next(); //¸Ç ÀÃ٠æ¿Ü (¾ÆÀÌÅÛ Ä®·³À» ¼³¸ÃÇô ºÎºÃ) m_vec_itemTable.resize(data.m_File.GetRowCount() - 1 + addNumber); memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size()); int testValue = m_vec_itemTable.size(); TItemTable * item_table = &m_vec_itemTable[0]; while (data.Next()) { int col = 0; std::map::iterator it_map_itemTable; it_map_itemTable = test_map_itemTableByVnum.find(atoi(data.AsStringByIndex(col))); if(it_map_itemTable == test_map_itemTableByVnum.end()) { //°¢ Ä®·³ µ¥ÀÌÅà ÀúÀå if (!Set_Proto_Item_Table(item_table, data, localMap)) { fprintf(stderr, "¾ÆÀÌÅÛ Ç÷ÎÅä Å×ÀÌºà ¼ÂÆà ½ÇÆÃ.\n"); } } else { //$$$$$$$$$$$$$$$$$$$$$$$ Å×½ºÆ® ¾ÆÀÌÅÛ Ã¤º¸°¡ ÀÖ´Ù! TItemTable *tempTable = it_map_itemTable->second; item_table->dwVnum = tempTable->dwVnum; strlcpy(item_table->szName, tempTable->szName, sizeof(item_table->szName)); strlcpy(item_table->szLocaleName, tempTable->szLocaleName, sizeof(item_table->szLocaleName)); item_table->bType = tempTable->bType; item_table->bSubType = tempTable->bSubType; item_table->bSize = tempTable->bSize; item_table->dwAntiFlags = tempTable->dwAntiFlags; item_table->dwFlags = tempTable->dwFlags; item_table->dwWearFlags = tempTable->dwWearFlags; item_table->dwImmuneFlag = tempTable->dwImmuneFlag; item_table->dwGold = tempTable->dwGold; item_table->dwShopBuyPrice = tempTable->dwShopBuyPrice; item_table->dwRefinedVnum =tempTable->dwRefinedVnum; item_table->wRefineSet =tempTable->wRefineSet; item_table->bAlterToMagicItemPct = tempTable->bAlterToMagicItemPct; item_table->cLimitRealTimeFirstUseIndex = -1; item_table->cLimitTimerBasedOnWearIndex = -1; int i; for (i = 0; i < ITEM_LIMIT_MAX_NUM; ++i) { item_table->aLimits.bType = tempTable->aLimits.bType; item_table->aLimits.lValue = tempTable->aLimits.lValue; if (LIMIT_REAL_TIME_START_FIRST_USE == item_table->aLimits.bType) item_table->cLimitRealTimeFirstUseIndex = (char)i; if (LIMIT_TIMER_BASED_ON_WEAR == item_table->aLimits.bType) item_table->cLimitTimerBasedOnWearIndex = (char)i; } for (i = 0; i < ITEM_APPLY_MAX_NUM; ++i) { item_table->aApplies.bType = tempTable->aApplies.bType; item_table->aApplies.lValue = tempTable->aApplies.lValue; } for (i = 0; i < ITEM_VALUES_MAX_NUM; ++i) item_table->alValues = tempTable->alValues; item_table->bGainSocketPct = tempTable->bGainSocketPct; item_table->sAddonType = tempTable->sAddonType; item_table->bWeight = tempTable->bWeight; } vnumSet.insert(item_table->dwVnum); m_map_itemTableByVnum.insert(std::map::value_type(item_table->dwVnum, item_table)); ++item_table; } //_______________________________________________________________________// //========================================================================// // 4) (b)[test_map_itemTableByVnum]ÀÇ rowÃß, (!)[item_table]¿¡ ¾ø´Â °ÃÀ» Ãß°¡ÇÑ´Ù. //========================================================================// test_data.Destroy(); if(!test_data.Load("item_proto_test.txt",'\t')) { fprintf(stderr, "item_proto_test.txt was loaded successfully.\n"); //return false; } else { test_data.Next(); //¼³¸à ·Î¿ì ³Ñ¾î°¡±â. while (test_data.Next()) //Å×½ºÆ® µ¥ÀÌÅà °¢°¢À» ÈȾ°¡¸ç,»õ·Î¿î °ÃÀ» Ãß°¡ÇÑ´Ù. { //Ãߺ¹µÇ´Â ºÎºÃÀ̸é ³Ñ¾î°£´Ù. set::iterator itVnum; itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0))); if (itVnum != vnumSet.end()) { continue; } if (!Set_Proto_Item_Table(item_table, test_data, localMap)) { fprintf(stderr, "¾ÆÀÌÅÛ Ç÷ÎÅä Å×ÀÌºà ¼ÂÆà ½ÇÆÃ.\n"); } m_map_itemTableByVnum.insert(std::map::value_type(item_table->dwVnum, item_table)); item_table++; } } // QUEST_ITEM_PROTO_DISABLE // InitializeQuestItemTable(); // END_OF_QUEST_ITEM_PROTO_DISABLE m_map_itemTableByVnum.clear(); itertype(m_vec_itemTable) it = m_vec_itemTable.begin(); while (it != m_vec_itemTable.end()) { TItemTable * item_table = &(*(it++)); sys_log(1, "ITEM: #%-5lu %-24s %-24s VAL: %ld %ld %ld %ld %ld %ld WEAR %lu ANTI %lu IMMUNE %lu REFINE %lu REFINE_SET %u MAGIC_PCT %u", item_table->dwVnum, item_table->szName, item_table->szLocaleName, item_table->alValues[0], item_table->alValues[1], item_table->alValues[2], item_table->alValues[3], item_table->alValues[4], item_table->alValues[5], item_table->dwWearFlags, item_table->dwAntiFlags, item_table->dwImmuneFlag, item_table->dwRefinedVnum, item_table->wRefineSet, item_table->bAlterToMagicItemPct); m_map_itemTableByVnum.insert(std::map::value_type(item_table->dwVnum, item_table)); } sort(m_vec_itemTable.begin(), m_vec_itemTable.end(), FCompareVnum()); return true; } par bool CClientManager::InitializeItemTable() { char query[2048]; fprintf(stderr,"Loading item_proto from MySQL"); snprintf(query, sizeof(query), "SELECT vnum,name,%s,type,subtype,weight,size,antiflag,flag,wearflag,immuneflag+0,gold,shop_buy_price,refined_vnum," "refine_set,magic_pct,limittype0,limitvalue0,limittype1,limitvalue1,applytype0,applyvalue0," "applytype1,applyvalue1,applytype2,applyvalue2,value0,value1,value2,value3,value4,value5,socket_pct,addon_type FROM item_proto%s ORDER BY vnum", g_stLocaleNameColumn.c_str(), GetTablePostfix()); std::auto_ptr pkMsg(CDBManager::instance().DirectQuery(query)); SQLResult * pRes = pkMsg->Get(); if (!pRes->uiNumRows) return false; int addNumber = pRes->uiNumRows; if (!m_vec_itemTable.empty()) { sys_log(0, "RELOAD: item_proto"); m_vec_itemTable.clear(); m_map_itemTableByVnum.clear(); } m_vec_itemTable.resize(addNumber-1); memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size()); TItemTable * item_table = &m_vec_itemTable[0]; MYSQL_ROW data; //return true; set vnumSet; while ((data = mysql_fetch_row(pRes->pSQLResult))) { str_to_number(item_table->dwVnum, data[0]); strlcpy(item_table->szName,data[1] , sizeof(item_table->szName)); strlcpy(item_table->szLocaleName, data[2], sizeof(item_table->szLocaleName)); str_to_number(item_table->bType, data[3]); str_to_number(item_table->bSubType, data[4]); str_to_number(item_table->bWeight, data[5]); str_to_number(item_table->bSize, data[6]); str_to_number(item_table->dwAntiFlags, data[7]); str_to_number(item_table->dwFlags, data[8]); str_to_number(item_table->dwWearFlags, data[9]); str_to_number(item_table->dwImmuneFlag, data[10]); str_to_number(item_table->dwGold, data[11]); str_to_number(item_table->dwShopBuyPrice, data[12]); str_to_number(item_table->dwRefinedVnum, data[13]); str_to_number(item_table->wRefineSet, data[14]); str_to_number(item_table->bAlterToMagicItemPct, data[15]); item_table->cLimitRealTimeFirstUseIndex = -1; item_table->cLimitTimerBasedOnWearIndex = -1; str_to_number(item_table->aLimits[0].bType, data[16]); str_to_number(item_table->aLimits[0].lValue, data[17]); if (LIMIT_REAL_TIME_START_FIRST_USE == item_table->aLimits[0].bType) item_table->cLimitRealTimeFirstUseIndex = (char)0; if (LIMIT_TIMER_BASED_ON_WEAR == item_table->aLimits[0].bType) item_table->cLimitTimerBasedOnWearIndex = (char)0; str_to_number(item_table->aLimits[1].bType, data[18]); str_to_number(item_table->aLimits[1].lValue, data[19]); if (LIMIT_REAL_TIME_START_FIRST_USE == item_table->aLimits[1].bType) item_table->cLimitRealTimeFirstUseIndex = (char)1; if (LIMIT_TIMER_BASED_ON_WEAR == item_table->aLimits[1].bType) item_table->cLimitTimerBasedOnWearIndex = (char)1; str_to_number(item_table->aApplies[0].bType, data[20]); str_to_number(item_table->aApplies[0].lValue, data[21]); str_to_number(item_table->aApplies[1].bType, data[22]); str_to_number(item_table->aApplies[1].lValue, data[23]); str_to_number(item_table->aApplies[2].bType, data[24]); str_to_number(item_table->aApplies[2].lValue, data[25]); str_to_number(item_table->alValues[0], data[26]); str_to_number(item_table->alValues[1], data[27]); str_to_number(item_table->alValues[2], data[28]); str_to_number(item_table->alValues[3], data[29]); str_to_number(item_table->alValues[4], data[30]); str_to_number(item_table->alValues[5], data[31]); str_to_number(item_table->bGainSocketPct, data[32]); str_to_number(item_table->sAddonType, data[33]); vnumSet.insert(item_table->dwVnum); m_map_itemTableByVnum.insert(std::map::value_type(item_table->dwVnum, item_table)); sys_log(0, "ITEM: #%-5lu %-24s %-24s VAL: %d %ld %d %d %d %d WEAR %d ANTI %d IMMUNE %d REFINE %lu REFINE_SET %u MAGIC_PCT %u", item_table->dwVnum, item_table->szName, item_table->szLocaleName, item_table->alValues[0], item_table->alValues[1], item_table->alValues[2], item_table->alValues[3], item_table->alValues[4], item_table->alValues[5], item_table->dwWearFlags, item_table->dwAntiFlags, item_table->dwImmuneFlag, item_table->dwRefinedVnum, item_table->wRefineSet, item_table->bAlterToMagicItemPct); item_table++; } fprintf(stderr," Complete! %d Items loaded.\r\n",addNumber); return true; } et bool CClientManager::InitializeMobTable() { //================== ÇÔ¼ö ¼³¸í ==================// //1. ¿ä¾à : 'mob_proto.txt', 'mob_proto_test.txt', 'mob_names.txt' ÆÄÀÏÀ» Àаí, // (!)[mob_table] Å×ÀÌºí ¿ÀºêÁ§Æ®¸¦ »ý¼ºÇÑ´Ù. (ŸÀÔ : TMobTable) //2. ¼ø¼­ // 1) 'mob_names.txt' ÆÄÀÏÀ» Àо (a)[localMap](vnum:name) ¸ÊÀ» ¸¸µç´Ù. // 2) 'mob_proto_test.txt'ÆÄÀÏ°ú (a)[localMap] ¸ÊÀ¸·Î // (b)[test_map_mobTableByVnum](vnum:TMobTable) ¸ÊÀ» »ý¼ºÇÑ´Ù. // 3) 'mob_proto.txt' ÆÄÀÏ°ú (a)[localMap] ¸ÊÀ¸·Î // (!)[mob_table] Å×À̺íÀ» ¸¸µç´Ù. // <Âü°í> // °¢ row µé Áß, // (b)[test_map_mobTableByVnum],(!)[mob_table] ¸ðµÎ¿¡ ÀÖ´Â row´Â // (b)[test_map_mobTableByVnum]ÀÇ °ÍÀ» »ç¿ëÇÑ´Ù. // 4) (b)[test_map_mobTableByVnum]ÀÇ rowÁß, (!)[mob_table]¿¡ ¾ø´Â °ÍÀ» Ãß°¡ÇÑ´Ù. //3. Å×½ºÆ® // 1)'mob_proto.txt' Á¤º¸°¡ mob_table¿¡ Àß µé¾î°¬´ÂÁö. -> ¿Ï·á // 2)'mob_names.txt' Á¤º¸°¡ mob_table¿¡ Àß µé¾î°¬´ÂÁö. // 3)'mob_proto_test.txt' ¿¡¼­ [°ãÄ¡´Â] Á¤º¸°¡ mob_table ¿¡ Àß µé¾î°¬´ÂÁö. // 4)'mob_proto_test.txt' ¿¡¼­ [»õ·Î¿î] Á¤º¸°¡ mob_table ¿¡ Àß µé¾î°¬´ÂÁö. // 5) (ÃÖÁ¾) °ÔÀÓ Å¬¶óÀ̾ðÆ®¿¡¼­ Á¦´ë·Î ÀÛµ¿ ÇÏ´ÂÁö. //_______________________________________________// //===============================================// // 1) 'mob_names.txt' ÆÄÀÏÀ» Àо (a)[localMap] ¸ÊÀ» ¸¸µç´Ù. //<(a)localMap ¸Ê »ý¼º> map localMap; bool isNameFile = true; //<ÆÄÀÏ Àбâ> cCsvTable nameData; if(!nameData.Load("mob_names.txt",'\t')) { fprintf(stderr, "mob_names.txt ÆÄÀÏÀ» Àоî¿ÀÁö ¸øÇß½À´Ï´Ù\n"); isNameFile = false; } else { nameData.Next(); //¼³¸írow »ý·«. while(nameData.Next()) { localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1); } } //________________________________________________// //===============================================// // 2) 'mob_proto_test.txt'ÆÄÀÏ°ú (a)localMap ¸ÊÀ¸·Î // (b)[test_map_mobTableByVnum](vnum:TMobTable) ¸ÊÀ» »ý¼ºÇÑ´Ù. //0. set vnumSet; //Å×½ºÆ®¿ë ÆÄÀÏ µ¥ÀÌÅÍÁß, ½Å±Ô¿©ºÎ È®Àο¡ »ç¿ë. //1. ÆÄÀÏ Àоî¿À±â bool isTestFile = true; cCsvTable test_data; if(!test_data.Load("mob_proto_test.txt",'\t')) { fprintf(stderr, "Å×½ºÆ® ÆÄÀÏÀÌ ¾ø½À´Ï´Ù. ±×´ë·Î ÁøÇàÇÕ´Ï´Ù.\n"); isTestFile = false; } //2. (c)[test_map_mobTableByVnum](vnum:TMobTable) ¸Ê »ý¼º. map test_map_mobTableByVnum; if (isTestFile) { test_data.Next(); //¼³¸í ·Î¿ì ³Ñ¾î°¡±â. //¤¡. Å×½ºÆ® ¸ó½ºÅÍ Å×ÀÌºí »ý¼º. TMobTable * test_mob_table = NULL; int test_MobTableSize = test_data.m_File.GetRowCount()-1; test_mob_table = new TMobTable[test_MobTableSize]; memset(test_mob_table, 0, sizeof(TMobTable) * test_MobTableSize); //¤¤. Å×½ºÆ® ¸ó½ºÅÍ Å×ÀÌºí¿¡ °ªÀ» ³Ö°í, ¸Ê¿¡±îÁö ³Ö±â. while(test_data.Next()) { if (!Set_Proto_Mob_Table(test_mob_table, test_data, localMap)) { fprintf(stderr, "¸÷ ÇÁ·ÎÅä Å×ÀÌºí ¼ÂÆà ½ÇÆÐ.\n"); } test_map_mobTableByVnum.insert(std::map::value_type(test_mob_table->dwVnum, test_mob_table)); ++test_mob_table; } } // 3) 'mob_proto.txt' ÆÄÀÏ°ú (a)[localMap] ¸ÊÀ¸·Î // (!)[mob_table] Å×À̺íÀ» ¸¸µç´Ù. // <Âü°í> // °¢ row µé Áß, // (b)[test_map_mobTableByVnum],(!)[mob_table] ¸ðµÎ¿¡ ÀÖ´Â row´Â // (b)[test_map_mobTableByVnum]ÀÇ °ÍÀ» »ç¿ëÇÑ´Ù. //1. ÆÄÀÏ Àбâ. cCsvTable data; if(!data.Load("mob_proto.txt",'\t')) { fprintf(stderr, "mob_proto.txt ÆÄÀÏÀ» Àоî¿ÀÁö ¸øÇß½À´Ï´Ù\n"); return false; } data.Next(); //¼³¸í row ³Ñ¾î°¡±â //2. (!)[mob_table] »ý¼ºÇϱâ //2.1 »õ·Î Ãß°¡µÇ´Â °¹¼ö¸¦ ÆÄ¾Ç int addNumber = 0; while(data.Next()) { int vnum = atoi(data.AsStringByIndex(0)); std::map::iterator it_map_mobTable; it_map_mobTable = test_map_mobTableByVnum.find(vnum); if(it_map_mobTable != test_map_mobTableByVnum.end()) { addNumber++; } } //data¸¦ ´Ù½Ã ùÁÙ·Î ¿Å±ä´Ù.(´Ù½Ã Àоî¿Â´Ù; data.Destroy(); if(!data.Load("mob_proto.txt",'\t')) { fprintf(stderr, "mob_proto.txt ÆÄÀÏÀ» Àоî¿ÀÁö ¸øÇß½À´Ï´Ù\n"); return false; } data.Next(); //¸Ç À­ÁÙ Á¦¿Ü (¾ÆÀÌÅÛ Ä®·³À» ¼³¸íÇÏ´Â ºÎºÐ) //2.2 Å©±â¿¡ ¸Â°Ô mob_table »ý¼º if (!m_vec_mobTable.empty()) { sys_log(0, "RELOAD: mob_proto"); m_vec_mobTable.clear(); } m_vec_mobTable.resize(data.m_File.GetRowCount()-1 + addNumber); memset(&m_vec_mobTable[0], 0, sizeof(TMobTable) * m_vec_mobTable.size()); TMobTable * mob_table = &m_vec_mobTable[0]; //2.3 µ¥ÀÌÅÍ Ã¤¿ì±â while (data.Next()) { int col = 0; //(b)[test_map_mobTableByVnum]¿¡ °°Àº row°¡ ÀÖ´ÂÁö Á¶»ç. bool isSameRow = true; std::map::iterator it_map_mobTable; it_map_mobTable = test_map_mobTableByVnum.find(atoi(data.AsStringByIndex(col))); if(it_map_mobTable == test_map_mobTableByVnum.end()) { isSameRow = false; } //°°Àº row °¡ ÀÖÀ¸¸é (b)¿¡¼­ Àоî¿Â´Ù. if(isSameRow) { TMobTable *tempTable = it_map_mobTable->second; mob_table->dwVnum = tempTable->dwVnum; strlcpy(mob_table->szName, tempTable->szName, sizeof(tempTable->szName)); strlcpy(mob_table->szLocaleName, tempTable->szLocaleName, sizeof(tempTable->szName)); mob_table->bRank = tempTable->bRank; mob_table->bType = tempTable->bType; mob_table->bBattleType = tempTable->bBattleType; mob_table->bLevel = tempTable->bLevel; mob_table->bSize = tempTable->bSize; mob_table->dwAIFlag = tempTable->dwAIFlag; mob_table->dwRaceFlag = tempTable->dwRaceFlag; mob_table->dwImmuneFlag = tempTable->dwImmuneFlag; mob_table->bEmpire = tempTable->bEmpire; strlcpy(mob_table->szFolder, tempTable->szFolder, sizeof(tempTable->szName)); mob_table->bOnClickType = tempTable->bOnClickType; mob_table->bStr = tempTable->bStr; mob_table->bDex = tempTable->bDex; mob_table->bCon = tempTable->bCon; mob_table->bInt = tempTable->bInt; mob_table->dwDamageRange[0] = tempTable->dwDamageRange[0]; mob_table->dwDamageRange[1] = tempTable->dwDamageRange[1]; mob_table->dwMaxHP = tempTable->dwMaxHP; mob_table->bRegenCycle = tempTable->bRegenCycle; mob_table->bRegenPercent = tempTable->bRegenPercent; mob_table->dwGoldMin = tempTable->dwGoldMin; mob_table->dwGoldMax = tempTable->dwGoldMax; mob_table->dwExp = tempTable->dwExp; mob_table->wDef = tempTable->wDef; mob_table->sAttackSpeed = tempTable->sAttackSpeed; mob_table->sMovingSpeed = tempTable->sMovingSpeed; mob_table->bAggresiveHPPct = tempTable->bAggresiveHPPct; mob_table->wAggressiveSight = tempTable->wAggressiveSight; mob_table->wAttackRange = tempTable->wAttackRange; mob_table->dwDropItemVnum = tempTable->dwDropItemVnum; mob_table->dwResurrectionVnum = tempTable->dwResurrectionVnum; for (int i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i) mob_table->cEnchants[i] = tempTable->cEnchants[i]; for (int i = 0; i < MOB_RESISTS_MAX_NUM; ++i) mob_table->cResists[i] = tempTable->cResists[i]; mob_table->fDamMultiply = tempTable->fDamMultiply; mob_table->dwSummonVnum = tempTable->dwSummonVnum; mob_table->dwDrainSP = tempTable->dwDrainSP; mob_table->dwPolymorphItemVnum = tempTable->dwPolymorphItemVnum; mob_table->Skills[0].bLevel = tempTable->Skills[0].bLevel; mob_table->Skills[0].dwVnum = tempTable->Skills[0].dwVnum; mob_table->Skills[1].bLevel = tempTable->Skills[1].bLevel; mob_table->Skills[1].dwVnum = tempTable->Skills[1].dwVnum; mob_table->Skills[2].bLevel = tempTable->Skills[2].bLevel; mob_table->Skills[2].dwVnum = tempTable->Skills[2].dwVnum; mob_table->Skills[3].bLevel = tempTable->Skills[3].bLevel; mob_table->Skills[3].dwVnum = tempTable->Skills[3].dwVnum; mob_table->Skills[4].bLevel = tempTable->Skills[4].bLevel; mob_table->Skills[4].dwVnum = tempTable->Skills[4].dwVnum; mob_table->bBerserkPoint = tempTable->bBerserkPoint; mob_table->bStoneSkinPoint = tempTable->bStoneSkinPoint; mob_table->bGodSpeedPoint = tempTable->bGodSpeedPoint; mob_table->bDeathBlowPoint = tempTable->bDeathBlowPoint; mob_table->bRevivePoint = tempTable->bRevivePoint; } else { if (!Set_Proto_Mob_Table(mob_table, data, localMap)) { fprintf(stderr, "¸÷ ÇÁ·ÎÅä Å×ÀÌºí ¼ÂÆà ½ÇÆÐ.\n"); } } //¼Â¿¡ vnum Ãß°¡ vnumSet.insert(mob_table->dwVnum); sys_log(1, "MOB #%-5d %-24s %-24s level: %-3u rank: %u empire: %d", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire); ++mob_table; } //_____________________________________________________// // 4) (b)[test_map_mobTableByVnum]ÀÇ rowÁß, (!)[mob_table]¿¡ ¾ø´Â °ÍÀ» Ãß°¡ÇÑ´Ù. //ÆÄÀÏ ´Ù½Ã Àоî¿À±â. test_data.Destroy(); isTestFile = true; test_data; if(!test_data.Load("mob_proto_test.txt",'\t')) { fprintf(stderr, "Å×½ºÆ® ÆÄÀÏÀÌ ¾ø½À´Ï´Ù. ±×´ë·Î ÁøÇàÇÕ´Ï´Ù.\n"); isTestFile = false; } if(isTestFile) { test_data.Next(); //¼³¸í ·Î¿ì ³Ñ¾î°¡±â. while (test_data.Next()) //Å×½ºÆ® µ¥ÀÌÅÍ °¢°¢À» ÈȾ°¡¸ç,»õ·Î¿î °ÍÀ» Ãß°¡ÇÑ´Ù. { //Áߺ¹µÇ´Â ºÎºÐÀÌ¸é ³Ñ¾î°£´Ù. set::iterator itVnum; itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0))); if (itVnum != vnumSet.end()) { continue; } if (!Set_Proto_Mob_Table(mob_table, test_data, localMap)) { fprintf(stderr, "¸÷ ÇÁ·ÎÅä Å×ÀÌºí ¼ÂÆà ½ÇÆÐ.\n"); } sys_log(0, "MOB #%-5d %-24s %-24s level: %-3u rank: %u empire: %d", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire); ++mob_table; } } sort(m_vec_mobTable.begin(), m_vec_mobTable.end(), FCompareVnum()); return true; } par bool CClientManager::InitializeMobTable() { char query[2048]; fprintf(stderr,"Loading mob_proto from MySQL "); snprintf(query, sizeof(query), "SELECT vnum,name,%s,rank,type,battle_type,level,size,ai_flag,mount_capacity,setRaceFlag,setImmuneFlag," "empire,folder,on_click,st,dx,ht,iq,damage_min,damage_max,max_hp,regen_cycle,regen_percent,gold_min," "gold_max,exp,def,attack_speed,move_speed,aggressive_hp_pct,aggressive_sight,attack_range,drop_item," "resurrection_vnum,enchant_curse,enchant_slow,enchant_poison,enchant_stun,enchant_critical,enchant_penetrate," "resist_sword,resist_twohand,resist_dagger,resist_bell,resist_fan,resist_bow,resist_fire,resist_elect," "resist_magic,resist_wind,resist_poison,dam_multiply,summon,drain_sp,mob_color,polymorph_item,skill_level0," "skill_vnum0,skill_level1,skill_vnum1,sp_berserk,sp_stoneskin,sp_godspeed,sp_deathblow,sp_revive,skill_level2," "skill_vnum2,skill_level3,skill_vnum3,skill_level4,skill_vnum4 FROM mob_proto%s" ,g_stLocaleNameColumn.c_str(), GetTablePostfix()); std::auto_ptr pkMsg(CDBManager::instance().DirectQuery(query)); SQLResult * pRes = pkMsg->Get(); if (!pRes->uiNumRows) return false; if (!m_vec_mobTable.empty()) { sys_log(0, "RELOAD: mob_proto"); m_vec_mobTable.clear(); } int size = pRes->uiNumRows; m_vec_mobTable.resize(size); memset(&m_vec_mobTable[0], 0, sizeof(TMobTable) * m_vec_mobTable.size()); TMobTable * mob_table = &m_vec_mobTable[0]; MYSQL_ROW data; //return true; set vnumSet; while ((data = mysql_fetch_row(pRes->pSQLResult))) { /* "SELECT vnum,name,locale_name,rank,type,battle_type,level,size,ai_flag,mount_capacity,setRaceFlag,setImmuneFlag," "empire,folder,on_click,st,dx,ht,iq,damage_min,damage_max,max_hp,regen_cycle,regen_percent,gold_min," "gold_max,exp,def,attack_speed,move_speed,aggressive_hp_pct,aggressive_sight,attack_range,drop_item," "resurrection_vnum,enchant_curse,enchant_slow,enchant_poison,enchant_stun,enchant_critical,enchant_penetrate," "resist_sword,resist_twohand,resist_dagger,resist_bell,resist_fan,resist_bow,resist_fire,resist_elect," "resist_magic,resist_wind,resist_poison,dam_multiply,summon,drain_sp,mob_color,polymorph_item,skill_level0," "skill_vnum0,skill_level1,skill_vnum1,sp_berserk,sp_stoneskin,sp_godspeed,sp_deathblow,sp_revive,skill_level2," "skill_vnum2,skill_level3,skill_vnum3,skill_level4,skill_vnum4 FROM mob_proto%s */ int col = 0; str_to_number(mob_table->dwVnum, data[col++]); if(mob_table->dwVnum ==0) continue; strlcpy(mob_table->szName,data[col++] , sizeof(mob_table->szName)); strlcpy(mob_table->szLocaleName, data[col++], sizeof(mob_table->szLocaleName)); str_to_number(mob_table->bRank,data[col++]); str_to_number(mob_table->bType,data[col++]); str_to_number(mob_table->bBattleType,data[col++]); str_to_number(mob_table->bLevel,data[col++]); str_to_number(mob_table->bSize,data[col++]); //AI_FLAG mob_table->dwAIFlag = get_Mob_AIFlag_Value(data[col++]); //mount_capacity; col++; //RACE_FLAG mob_table->dwRaceFlag = get_Mob_RaceFlag_Value(data[col++]); //IMMUNE_FLAG mob_table->dwImmuneFlag = get_Mob_ImmuneFlag_Value(data[col++]); mob_table->bEmpire = atoi(data[col++]); strlcpy(mob_table->szFolder, data[col++], sizeof(mob_table->szFolder)); mob_table->bOnClickType = atoi(data[col++]); mob_table->bStr = atoi(data[col++]); mob_table->bDex = atoi(data[col++]); mob_table->bCon = atoi(data[col++]); mob_table->bInt = atoi(data[col++]); mob_table->dwDamageRange[0] = atoi(data[col++]); mob_table->dwDamageRange[1] = atoi(data[col++]); mob_table->dwMaxHP = atoi(data[col++]); mob_table->bRegenCycle = atoi(data[col++]); mob_table->bRegenPercent = atoi(data[col++]); mob_table->dwGoldMin = atoi(data[col++]); mob_table->dwGoldMax = atoi(data[col++]); mob_table->dwExp = atoi(data[col++]); mob_table->wDef = atoi(data[col++]); mob_table->sAttackSpeed = atoi(data[col++]); mob_table->sMovingSpeed = atoi(data[col++]); mob_table->bAggresiveHPPct = atoi(data[col++]); mob_table->wAggressiveSight = atoi(data[col++]); mob_table->wAttackRange = atoi(data[col++]); str_to_number(mob_table->dwDropItemVnum, data[col++]); //32 str_to_number(mob_table->dwResurrectionVnum, data[col++]); for (int i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i) str_to_number(mob_table->cEnchants[i], data[col++]); for (int i = 0; i < MOB_RESISTS_MAX_NUM; ++i) str_to_number(mob_table->cResists[i], data[col++]); str_to_number(mob_table->fDamMultiply, data[col++]); str_to_number(mob_table->dwSummonVnum, data[col++]); str_to_number(mob_table->dwDrainSP, data[col++]); //Mob_Color ++col; str_to_number(mob_table->dwPolymorphItemVnum, data[col++]); str_to_number(mob_table->Skills[0].bLevel, data[col++]); str_to_number(mob_table->Skills[0].dwVnum, data[col++]); str_to_number(mob_table->Skills[1].bLevel, data[col++]); str_to_number(mob_table->Skills[1].dwVnum, data[col++]); str_to_number(mob_table->Skills[2].bLevel, data[col++]); str_to_number(mob_table->Skills[2].dwVnum, data[col++]); str_to_number(mob_table->Skills[3].bLevel, data[col++]); str_to_number(mob_table->Skills[3].dwVnum, data[col++]); str_to_number(mob_table->Skills[4].bLevel, data[col++]); str_to_number(mob_table->Skills[4].dwVnum, data[col++]); str_to_number(mob_table->bBerserkPoint, data[col++]); str_to_number(mob_table->bStoneSkinPoint, data[col++]); str_to_number(mob_table->bGodSpeedPoint, data[col++]); str_to_number(mob_table->bDeathBlowPoint, data[col++]); str_to_number(mob_table->bRevivePoint, data[col++]); //ĽÂżˇ vnum Ăß°ˇ vnumSet.insert(mob_table->dwVnum); //fprintf(stderr, "MOB #%d %s %s level: %u rank: %u empire: %d\n", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire); sys_log(0, "MOB #%-5d %-24s %-24s level: %-3u rank: %u empire: %d", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire); ++mob_table; } fprintf(stderr," Complete! %d/%d Mobs loaded.\r\n",size,vnumSet.size()); sort(m_vec_mobTable.begin(), m_vec_mobTable.end(), FCompareVnum()); return true; } Attention dans bool CClientManager::InitializeTables() vous devrez supprimez donc MirrorMobTableIntoDB() and MirrorItemTableIntoDB() Source : EPvP