Aller au contenu

Classement


Contenu populaire

Affichage du contenu avec la meilleure réputation depuis le 16/06/2018 dans toutes les zones

  1. 7 points
    Bonsoir à tous, Suite à une récente demande d'@Abass. J'ai décidé de vous partager ce petit tweak, qui franchement ne casse pas trois pattes à un canard mais qui mine de rien est assez sympathique. Et puis, qui dit inutile dit indispensable. Qu'est-ce que ça fait au juste ? Tout simplement, dès lors qu'un objet dans un magasin vaudra 0 Yang, le jeu vous dira "Prix : Gratuit" à la place de "Prix : 0 Yangs". C'est tout ! Sans plus attendre, commençons le tutoriel, ça va être très rapide. Ouvrez le fichier "uitooltip.py" qui se situe dans root puis changez la définition "AppendPrice(self, price)" avec la mienne, qui contient la condition en plus. def AppendPrice(self, price): self.AppendSpace(5) if price == 0: self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE_FREE) else: self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE % (localeInfo.NumberToMoneyString(price)), self.GetPriceColor(price)) Enregistrez, fermez, repackez root puis rendez vous dans votre fichier locale_fr, ouvrez "locale_game.txt" et rajoutez cette ligne : TOOLTIP_BUYPRICE_FREE Prix : Gratuit En dessous de celle-ci (pour la propreté) : TOOLTIP_BUYPRICE Prix : %s Enregistrez, fermez, repackez locale_fr puis rendez-vous en jeu. Voici le résultat : Voilà, c'est tout pour ce mini-guide ! Passez une bonne journée
  2. 5 points
    Bonjour ! Je vous propose un tutoriel pour installer le système de ticket partagé par Shang, que j'ai corrigé car il contenait d'assez gros problèmes côté python, permettant des injections SQL. I - Source client : Dans le fichier Packet.h : Chercher : QUEST_INPUT_STRING_MAX_NUM = 64, Ajouter juste après : #ifdef ENABLE_TICKET_SYSTEM QUEST_INPUT_STRING_LONG_MAX_NUM = 512, #endif Chercher ensuite : typedef struct command_quest_input_string { BYTE bHeader; char szString[QUEST_INPUT_STRING_MAX_NUM+1]; } TPacketCGQuestInputString; Ajouter : #ifdef ENABLE_TICKET_SYSTEM typedef struct command_quest_input_long_string { BYTE bHeader; char szString[QUEST_INPUT_STRING_LONG_MAX_NUM]; } TPacketCGQuestInputLongString; #endif Pour en finir avec ce fichier, chercher : #ifdef __AUCTION__ HEADER_CG_AUCTION_CMD = 205, #endif Puis ajouter : #ifdef ENABLE_TICKET_SYSTEM HEADER_CG_QUEST_INPUT_LONG_STRING = 214, #endif Vérifiez qu'aucun de vos packets n'utilise le 214, sinon changez en conséquence, et vous ferez de même dans les sources serveur. Dans le fichier PythonNetworkStream.h : Chercher : bool SendQuestInputStringPacket(const char * c_szString); Ajouter : #ifdef ENABLE_TICKET_SYSTEM bool SendQuestInputStringLongPacket(const char * c_pszString); #endif Dans le fichier PythonNetworkStreamModule.cpp : Chercher : PyObject* netSendQuestInputStringPacket(PyObject* poSelf, PyObject* poArgs) { char * szString; if (!PyTuple_GetString(poArgs, 0, &szString)) return Py_BuildException(); CPythonNetworkStream& rns=CPythonNetworkStream::Instance(); rns.SendQuestInputStringPacket(szString); return Py_BuildNone(); } Ajouter : #ifdef ENABLE_TICKET_SYSTEM PyObject * netSendQuestInputLongStringPacket(PyObject * poSelf, PyObject * poArgs) { char * szString; if (!PyTuple_GetString(poArgs, 0, &szString)) return Py_BuildException(); CPythonNetworkStream & rns = CPythonNetworkStream::Instance(); rns.SendQuestInputStringLongPacket(szString); return Py_BuildNone(); } #endif Chercher ensuite : { "SendQuestInputStringPacket", netSendQuestInputStringPacket, METH_VARARGS }, Ajouter : #ifdef ENABLE_TICKET_SYSTEM { "SendQuestInputLongStringPacket", netSendQuestInputLongStringPacket, METH_VARARGS }, #endif Dans le fichier PythonNetworkSteamPhaseGame.cpp : Chercher : bool CPythonNetworkStream::SendQuestInputStringPacket(const char * c_szString) { TPacketCGQuestInputString Packet; Packet.bHeader = HEADER_CG_QUEST_INPUT_STRING; strncpy(Packet.szString, c_szString, QUEST_INPUT_STRING_MAX_NUM); if (!Send(sizeof(Packet), &Packet)) { Tracen("SendQuestInputStringPacket Error"); return false; } return SendSequence(); } Ajouter : #ifdef ENABLE_TICKET_SYSTEM bool CPythonNetworkStream::SendQuestInputStringLongPacket(const char * c_pszString) { TPacketCGQuestInputLongString Packet; Packet.bHeader = HEADER_CG_QUEST_INPUT_LONG_STRING; strncpy(Packet.szString, c_pszString, QUEST_INPUT_STRING_LONG_MAX_NUM); if (!Send(sizeof(Packet), &Packet)) { Tracen("SendQuestInputStringLongPacket Error"); return false; } return SendSequence(); } #endif Dans le fichier PythonApplicationModule.cpp : Chercher : #ifdef ENABLE_COSTUME_SYSTEM PyModule_AddIntConstant(poModule, "ENABLE_COSTUME_SYSTEM", 1); #else PyModule_AddIntConstant(poModule, "ENABLE_COSTUME_SYSTEM", 0); #endif Ajouter : #ifdef ENABLE_TICKET_SYSTEM PyModule_AddIntConstant(poModule, "ENABLE_TICKET_SYSTEM", 1); #else PyModule_AddIntConstant(poModule, "ENABLE_TICKET_SYSTEM", 0); #endif Dans le fichier Locale_inc.h : Ajouter : #define ENABLE_TICKET_SYSTEM Vous pouvez maintenant lancer la compilation de vos sources client le temps qu'on s'occupe des sources serveur ! II - Source serveur : Dans le fichier service.h : Ajouter : #define ENABLE_TICKET_SYSTEM Dans le fichier input.h : Chercher : void QuestInputString(LPCHARACTER ch, const void * pvData); Ajouter : #ifdef ENABLE_TICKET_SYSTEM void QuestInputLongString(LPCHARACTER ch, const void * c_pvData); #endif Dans le fichier input_main.cpp : Chercher : void CInputMain::QuestInputString(LPCHARACTER ch, const void* c_pData) { TPacketCGQuestInputString * p = (TPacketCGQuestInputString*) c_pData; char msg[65]; strlcpy(msg, p->msg, sizeof(msg)); sys_log(0, "QUEST InputString pid %u msg %s", ch->GetPlayerID(), msg); quest::CQuestManager::Instance().Input(ch->GetPlayerID(), msg); } Ajouter : #ifdef ENABLE_TICKET_SYSTEM void CInputMain::QuestInputLongString(LPCHARACTER ch, const void * c_pvData) { const TPacketCGQuestInputLongString * p = reinterpret_cast<const TPacketCGQuestInputLongString*>(c_pvData); sys_log(0, "QUEST InputLongString pid %u msg %s", ch->GetPlayerID(), p->szMsg); quest::CQuestManager::Instance().Input(ch->GetPlayerID(), p->szMsg); } #endif Chercher : case HEADER_CG_QUEST_INPUT_STRING: QuestInputString(ch, c_pData); break; Ajouter : #ifdef ENABLE_TICKET_SYSTEM case HEADER_CG_QUEST_INPUT_LONG_STRING: QuestInputLongString(ch, c_pData); break; #endif Dans le fichier packet.h : Chercher : typedef struct command_quest_input_string { BYTE header; char msg[64+1]; } TPacketCGQuestInputString; Ajouter : #ifdef ENABLE_TICKET_SYSTEM typedef struct command_quest_input_long_string { BYTE header; char szMsg[512]; } TPacketCGQuestInputLongString; #endif Chercher : HEADER_CG_XTRAP_ACK = 204, Ajouter : #ifdef ENABLE_TICKET_SYSTEM HEADER_CG_QUEST_INPUT_LONG_STRING = 214, #endif -->Penser à modifier le packet si vous l'avez fait dans les sources client. Dans le fichier packet_info.cpp : Chercher : Set(HEADER_CG_STATE_CHECKER, sizeof(BYTE), "ServerStateCheck", false); Ajouter : #ifdef ENABLE_TICKET_SYSTEM Set(HEADER_CG_QUEST_INPUT_LONG_STRING, sizeof(TPacketCGQuestInputLongString), "QuestInputLongString", true); #endif Dans le fichier questlua_global.cpp : Si, et seulement si vous n'avez pas mysql_direct_query, vous suivez cette étape, sinon, vous pouvez dores et déjà compiler vos sources. Chercher : void RegisterGlobalFunctionTable(lua_State* L) Ajouter au dessus : #ifdef _MSC_VER #define INFINITY (DBL_MAX+DBL_MAX) #define NAN (INFINITY-INFINITY) #endif int _mysql_direct_query(lua_State* L) { // char szQuery[1024]; if (!lua_isstring(L, 1)) return 0; // strncpy(szQuery, lua_tostring(L, 1), sizeof(szQuery)); int i=0, m=1; MYSQL_ROW row; MYSQL_FIELD * field; MYSQL_RES * result; // SQLMsg * pMsg = DBManager::instance().DirectQuery(szQuery); std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery(lua_tostring(L, 1))); if (pMsg.get()) { // ret1 (number of affected rows) lua_pushnumber(L, pMsg->Get()->uiAffectedRows); //-1 if error such as duplicate occurs (-2147483648 via lua) // if wrong syntax error occurs (4294967295 via lua) // ret2 (table of affected rows) lua_newtable(L); if ((result = pMsg->Get()->pSQLResult) && !(pMsg->Get()->uiAffectedRows == 0 || pMsg->Get()->uiAffectedRows == (uint32_t)-1)) { // LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); // ch->ChatPacket(CHAT_TYPE_INFO, "<%s> Retrieved %u fields\n", __FUNCTION__, mysql_num_fields(result)); // ch->ChatPacket(CHAT_TYPE_INFO, "<%s> Retrieved %u rows\n", __FUNCTION__, mysql_num_rows(result)); // ch->ChatPacket(CHAT_TYPE_INFO, "<%s> Affected %u rows\n", __FUNCTION__, pMsg->Get()->uiAffectedRows); // ch->ChatPacket(CHAT_TYPE_INFO, "<%s> Num %u rows\n", __FUNCTION__, pMsg->Get()->uiNumRows); while((row = mysql_fetch_row(result))) { lua_pushnumber(L, m); lua_newtable(L); while((field = mysql_fetch_field(result))) { lua_pushstring(L, field->name); if (!(field->flags & NOT_NULL_FLAG) && (row[i]==NULL)) { // lua_pushstring(L, "NULL"); lua_pushnil(L); } else if (IS_NUM(field->type)) { double val = NAN; lua_pushnumber(L, (sscanf(row[i],"%lf",&val)==1)?val:NAN); } else if (field->type == MYSQL_TYPE_BLOB) { lua_newtable(L); for (DWORD iBlob=0; iBlob < field->max_length; iBlob++) { lua_pushnumber(L, row[i][iBlob]); lua_rawseti(L, -2, iBlob+1); } } else lua_pushstring(L, row[i]); // LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); // ch->ChatPacket(CHAT_TYPE_INFO, "<%s> Retrieved %d flag %s for %s\n", __FUNCTION__, field->type, field->name, row[i]?row[i]:"NULL"); lua_rawset(L, -3); i++; } mysql_field_seek(result, 0); i=0; lua_rawset(L, -3); m++; } } } else {lua_pushnumber(L, 0); lua_newtable(L);} // delete pMsg; return 2; } Chercher ensuite : { NULL, NULL } Ajouter au dessus : { "mysql_direct_query", _mysql_direct_query }, Vous pouvez maintenant lancer la compilation de vos sources serveur, le temps qu'on s'occupe des fichiers serveur ! III - Serveur : Vous allez dans cette partie, ajouter ceci dans votre quest_functions : ticket.answer_ticket ticket.create_ticket ticket.load_answers ticket.load_permisions ticket.load_tickets ticket.add_member ticket.update_permisions ticket.delete_member ticket.has_permision ticket.add_viewer ticket.delete_viewer Ajouter dans questlib : dofile(get_locale_base_path().."/quest/ticket_lib.so") Ajouter ensuite la lib disponible en pièce jointe, la quête et le dossiers "tickets" (Pièce jointe : QUEST.rar). IV - MySQL : je vous invite pour cette partie à lancer ces queries : SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for tickets -- ---------------------------- DROP TABLE IF EXISTS `tickets`; CREATE TABLE `tickets` ( `order_id` int(11) NOT NULL AUTO_INCREMENT, `id` varchar(8) NOT NULL, `title` varchar(60) NOT NULL, `priority` varchar(150) NOT NULL, `date` datetime NOT NULL, `status` tinyint(1) NOT NULL, `creator` varchar(16) NOT NULL, `msg` varchar(500) NOT NULL, `category` int(2) NOT NULL, PRIMARY KEY (`order_id`) ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for tickets_answers -- ---------------------------- DROP TABLE IF EXISTS `tickets_answers`; CREATE TABLE `tickets_answers` ( `order_id` int(11) NOT NULL AUTO_INCREMENT, `id` varchar(8) NOT NULL, `creator` varchar(16) NOT NULL, `date` datetime NOT NULL, `msg` varchar(500) NOT NULL, PRIMARY KEY (`order_id`) ) ENGINE=MyISAM AUTO_INCREMENT=14 DEFAULT CHARSET=latin1; SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for tickets_permisions -- ---------------------------- DROP TABLE IF EXISTS `tickets_permisions`; CREATE TABLE `tickets_permisions` ( `pid` int(50) NOT NULL, `answer_permision` tinyint(1) NOT NULL, `delete_permision` tinyint(1) NOT NULL, `add_permision` tinyint(1) NOT NULL, PRIMARY KEY (`pid`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; V - Client : Dans votre locale_game.txt, ajouter : TICKET_PRIORITY_HIGH Élevée TICKET_PRIORITY_MEDIUM Normale TICKET_PRIORITY_LOW Faible TICKET_STATE_ON_HOLD En cours TICKET_STATE_CLOSED Fermé TICKET_STATE_SOLVED Résolu TICKET_ADD_NAME Nom: TICKET_ADD_TITLE Ajouter un membre TICKET_ADD_ACCEPT Accepter TICKET_SEND Envoyer TICKET_TITLE Asylum : Tickets TICKET_MY_TICKETS Mes Tickets TICKET_ADMINISTRATION Administration TICKET_SORT_BY Ordre : TICKET_ID ID TICKET_TITLE_T Titre TICKET_PRIORITY Priorité TICKET_DATE Date TICKET_STATE Etat TICKET_CREATE_NEW Créer un nouveau ticket TICKET_SEARCH Rechercher par ID: TICKET_SEARCH_BUTTON Rechercher TICKET_NAME Nom TICKET_ANSWER Répondre TICKET_DELETE Supprimer TICKET_CHANGE_PERMISIONS Modifier les permissions TICKET_ADD_MEMBER Ajouter un membre TICKET_REFRESH Actualiser TICKET_CATEGORY Categorie TICKET_CATEGORY_0 Tous Dans votre uiquest.py : Chercher : def Destroy(self): self.ClearDictionary() if self.OnCloseEvent: self.OnCloseEvent() self.OnCloseEvent = None # QUEST_INPUT if self.needInputString: if self.editLine: text = self.editLine.GetText() net.SendQuestInputStringPacket(text) # END_OF_QUEST_INPUT self.imgTitle = None self.images = None self.eventCurtain = None self.board = None Remplacer par : def Destroy(self): self.ClearDictionary() if self.OnCloseEvent: self.OnCloseEvent() self.OnCloseEvent = None # QUEST_INPUT if self.needInputString: if self.editLine: text = self.editLine.GetText() if app.ENABLE_TICKET_SYSTEM: if (len(text) > 64): net.SendQuestInputLongStringPacket(text) else: net.SendQuestInputStringPacket(text) else: net.SendQuestInputStringPacket(text) # END_OF_QUEST_INPUT self.imgTitle = None self.images = None self.eventCurtain = None self.board = None Dans le fichier interfaceModule.py : Ajouter : if app.ENABLE_TICKET_SYSTEM: import uiTicket Chercher : self.dlgShop = uiShop.ShopDialog() self.dlgShop.LoadDialog() self.dlgShop.Hide() Ajouter : if app.ENABLE_TICKET_SYSTEM: self.wndTicket = uiTicket.TicketWindow() self.wndTicket.Hide() Chercher : if self.dlgShop: self.dlgShop.Destroy() Ajouter : if app.ENABLE_TICKET_SYSTEM: if self.wndTicket: self.wndTicket.Destroy() Chercher : del self.wndItemSelect Ajouter : if app.ENABLE_TICKET_SYSTEM: del self.wndTicket Dans le fichier costinfo.py : Ajouter : if app.ENABLE_TICKET_SYSTEM: Tickets = { 'QID' : 0, 'QCMD' : '', 'MY_TICKETS' : [], 'GLOBAL_TICKETS' : [], 'ANSWERS' : {}, 'PERMISIONS' : [] } CApiSetHide = 0 Dans le fichier game.py : Chercher : "mall" : self.__InGameShop_Show, Ajouter : if app.ENABLE_TICKET_SYSTEM: "TICKETS" : self.ManagerTickets, Chercher : def OpenQuestWindow(self, skin, idx): Ajouter : if app.ENABLE_TICKET_SYSTEM: if constInfo.CApiSetHide == 1: net.SendQuestInputStringPacket(str(constInfo.SendString)) constInfo.CApiSetHide = 0 return Chercher : def __InGameShop_Show(self, url): if constInfo.IN_GAME_SHOP_ENABLE: self.interface.OpenWebWindow(url) Ajouter : if app.ENABLE_TICKET_SYSTEM: def ManagerTickets(self, cmd): cmd = cmd.split('#') if cmd[0] == 'QID': constInfo.Tickets['QID'] = int(cmd[1]) elif cmd[0] == 'INPUT': constInfo.INPUT_IGNORE = int(cmd[1]) elif cmd[0] == 'SEND': net.SendQuestInputLongStringPacket(str(constInfo.Tickets['QCMD'])) constInfo.Tickets['QCMD'] = '' elif cmd[0] == 'CLEAR_CONTENT': constInfo.Tickets['MY_TICKETS'] = [] constInfo.Tickets['GLOBAL_TICKETS'] = [] elif cmd[0] == 'CLEAR_PERMISIONS': constInfo.Tickets['PERMISIONS'] = [] elif cmd[0] == 'SET_TICKET': date = cmd[4].split('[_]') constInfo.Tickets['GLOBAL_TICKETS'].append([cmd[1], cmd[2].replace('[_]', ' '), int(cmd[3]), date[0], date[1], int(cmd[5]), cmd[6], cmd[7].replace('[_]', ' '), int(cmd[8])]) if cmd[6] == player.GetName(): constInfo.Tickets['MY_TICKETS'].append([cmd[1], cmd[2].replace('[_]', ' '), int(cmd[3]), date[0], date[1], int(cmd[5]), cmd[6], cmd[7].replace('[_]', ' '), int(cmd[8])]) elif cmd[0] == 'CREATE_ANSWER': constInfo.Tickets['ANSWERS'][cmd[1]] = [] elif cmd[0] == 'SET_ANSWER': date = cmd[3].split('[_]') constInfo.Tickets['ANSWERS'][cmd[1]].append([cmd[2], date[0], date[1], cmd[4].replace('[_]', ' ')]) elif cmd[0] == 'SET_PERMISION': constInfo.Tickets['PERMISIONS'].append([cmd[1], int(cmd[2]), int(cmd[3]), int(cmd[4])]) elif cmd[0] == 'OPEN': self.interface.wndTicket.Open(int(cmd[1])) elif cmd[0] == 'REFRESH_CONTENT': self.interface.wndTicket.RefreshPage() Dans le fichier ui.py : Ajouter la class : if app.ENABLE_TICKET_SYSTEM: class CoolButton(Window): BACKGROUND_COLOR = grp.GenerateColor(0.0, 0.0, 0.0, 1.0) DARK_COLOR = grp.GenerateColor(0.4, 0.4, 0.4, 1.0) WHITE_COLOR = grp.GenerateColor(1.0, 1.0, 1.0, 0.3) HALF_WHITE_COLOR = grp.GenerateColor(1.0, 1.0, 1.0, 0.2) def __init__(self, layer = "UI"): Window.__init__(self, layer) self.eventFunc = None self.eventArgs = None self.ButtonText = None self.ToolTipText = None self.EdgeColor = None self.isOver = FALSE self.isSelected = FALSE self.width = 0 self.height = 0 def __del__(self): Window.__del__(self) self.eventFunc = None self.eventArgs = None def SetSize(self, width, height): Window.SetSize(self, width, height) self.width = width self.height = height def SetEvent(self, func, *args): self.eventFunc = func self.eventArgs = args def SetTextColor(self, color): if not self.ButtonText: return self.ButtonText.SetPackedFontColor(color) def SetEdgeColor(self, color): self.EdgeColor = color def SetText(self, text): if not self.ButtonText: textLine = TextLine() textLine.SetParent(self) textLine.SetPosition(self.GetWidth()/2, self.GetHeight()/2) textLine.SetVerticalAlignCenter() textLine.SetHorizontalAlignCenter() textLine.SetOutline() textLine.Show() self.ButtonText = textLine self.ButtonText.SetText(text) def SetToolTipText(self, text, x=0, y = -19): if not self.ToolTipText: toolTip=createToolTipWindowDict["TEXT"]() toolTip.SetParent(self) toolTip.SetSize(0, 0) toolTip.SetHorizontalAlignCenter() toolTip.SetOutline() toolTip.Hide() toolTip.SetPosition(x + self.GetWidth()/2, y) self.ToolTipText=toolTip self.ToolTipText.SetText(text) def ShowToolTip(self): if self.ToolTipText: self.ToolTipText.Show() def HideToolTip(self): if self.ToolTipText: self.ToolTipText.Hide() def SetTextPosition(self, width): self.ButtonText.SetPosition(width, self.GetHeight()/2) self.ButtonText.SetHorizontalAlignLeft() def Enable(self): wndMgr.Enable(self.hWnd) def Disable(self): wndMgr.Disable(self.hWnd) def OnMouseLeftButtonDown(self): self.isSelected = TRUE def OnMouseLeftButtonUp(self): self.isSelected = FALSE if self.eventFunc: apply(self.eventFunc, self.eventArgs) def OnUpdate(self): if self.IsIn(): self.isOver = TRUE self.ShowToolTip() else: self.isOver = FALSE self.HideToolTip() def OnRender(self): xRender, yRender = self.GetGlobalPosition() widthRender = self.width heightRender = self.height grp.SetColor(self.BACKGROUND_COLOR) grp.RenderBar(xRender, yRender, widthRender, heightRender) if self.EdgeColor: grp.SetColor(self.EdgeColor) else: grp.SetColor(self.DARK_COLOR) grp.RenderLine(xRender, yRender, widthRender, 0) grp.RenderLine(xRender, yRender, 0, heightRender) grp.RenderLine(xRender, yRender+heightRender, widthRender, 0) grp.RenderLine(xRender+widthRender, yRender, 0, heightRender) if self.isOver: grp.SetColor(self.HALF_WHITE_COLOR) grp.RenderBar(xRender + 2, yRender + 2, self.width - 3, heightRender - 3) if self.isSelected: grp.SetColor(self.WHITE_COLOR) grp.RenderBar(xRender + 2, yRender + 2, self.width - 3, heightRender - 3) Chercher (EditLine): self.eventKillFocus = None Ajouter : if app.ENABLE_TICKET_SYSTEM: self.CanClick = None Chercher : def SetTabEvent(self, event): self.eventTab = event Ajouter : if app.ENABLE_TICKET_SYSTEM: def CanEdit(self, flag): self.CanClick = flag Chercher : def OnMouseLeftButtonDown(self): En dessous de : if FALSE == self.IsIn(): return FALSE Ajouter : if app.ENABLE_TICKET_SYSTEM: if FALSE == self.CanClick: return Déplacer ensuite les fichiers fournis dans l'archive PACK.rar où il faut, et voilà ! C'est terminé. Vous pouvez maintenant ouvrir la fenêtre en utilisant la fonction : if app.ENABLE_TICKET_SYSTEM: def OpenTicketWindow(self): import event constInfo.Tickets['QCMD'] = 'OPEN#' event.QuestButtonClick(constInfo.Tickets['QID']) return Rendu (je vous renvoie sur la chaine de l'auteur) : A ploush ! QUEST.rar PACK.rar
  3. 4 points
    Bonjour, Comme pour le système de metin visible sur la minimap, après plusieurs recherche et demande sur différents forum j'ai réussi à faire de même avec les boss. Pour commencer nous allons nous rendre dans les fichiers sources de votre client. Nous irons donc dans UserInterface et nous allons ouvrir le fichier InstanceBase.h. On cherche: NAMECOLOR_WAYPOINT, On fait une nouvelle ligne et on ajoute: NAMECOLOR_BOSS, On cherche: BOOL IsEnemy(); On ajoute en dessous: ///boss BOOL IsBoss(); Nous en avons maintenant fini avec ce fichier, toujours dans le même dossier on cherche le fichier InstanceBase.cpp. On cherche ceci: BOOL CInstanceBase::IsFlag() On copie en dessous du block tout ça: ///boss BOOL CInstanceBase::IsBoss() { if (GetRace() == 691) return TRUE; if (GetRace() == 692) return TRUE; if (GetRace() == 693) return TRUE; if (GetRace() == 791) return TRUE; if (GetRace() == 991) return TRUE; if (GetRace() == 992) return TRUE; if (GetRace() == 993) return TRUE; if (GetRace() == 1091) return TRUE; if (GetRace() == 1092) return TRUE; if (GetRace() == 1093) return TRUE; if (GetRace() == 1094) return TRUE; if (GetRace() == 1095) return TRUE; if (GetRace() == 2191) return TRUE; if (GetRace() == 1191) return TRUE; if (GetRace() == 1192) return TRUE; if (GetRace() == 1304) return TRUE; if (GetRace() == 1306) return TRUE; if (GetRace() == 1307) return TRUE; if (GetRace() == 1901) return TRUE; if (GetRace() == 1902) return TRUE; if (GetRace() == 1903) return TRUE; if (GetRace() == 2206) return TRUE; if (GetRace() == 2207) return TRUE; if (GetRace() == 2291) return TRUE; if (GetRace() == 2306) return TRUE; if (GetRace() == 2307) return TRUE; if (GetRace() == 2492) return TRUE; if (GetRace() == 2493) return TRUE; if (GetRace() == 2494) return TRUE; if (GetRace() == 2598) return TRUE; if (GetRace() == 3090) return TRUE; if (GetRace() == 3091) return TRUE; if (GetRace() == 3190) return TRUE; if (GetRace() == 3191) return TRUE; if (GetRace() == 3290) return TRUE; if (GetRace() == 3291) return TRUE; if (GetRace() == 3390) return TRUE; if (GetRace() == 3391) return TRUE; if (GetRace() == 3490) return TRUE; if (GetRace() == 3491) return TRUE; if (GetRace() == 3590) return TRUE; if (GetRace() == 3591) return TRUE; if (GetRace() == 3690) return TRUE; if (GetRace() == 3691) return TRUE; if (GetRace() == 3790) return TRUE; if (GetRace() == 3791) return TRUE; if (GetRace() == 3890) return TRUE; if (GetRace() == 3891) return TRUE; if (GetRace() == 5001) return TRUE; if (GetRace() == 5004) return TRUE; if (GetRace() == 5002) return TRUE; if (GetRace() == 5161) return TRUE; if (GetRace() == 5162) return TRUE; if (GetRace() == 5163) return TRUE; if (GetRace() == 6091) return TRUE; if (GetRace() == 6191) return TRUE; return FALSE; } /////////////// /////////////// On en a fini avec ce fichier, toujours dans le même dossier on cherche le fichier InstanceBaseEffect.cpp. Dans le fichier on cherche ceci: else if (IsEnemy()) { if (IsBoss()) return NAMECOLOR_BOSS; return NAMECOLOR_MOB; } else if (IsEnemy()) { return NAMECOLOR_MOB; } On remplace le la totalité du else if par ceci: else if (IsEnemy()) { if (IsBoss()) return NAMECOLOR_BOSS; return NAMECOLOR_MOB; } On en a fini avec ce fichier, toujours dans le même dossier on cherche le fichier PythonCharacterManagerModule.cp.p On cherche ceci à l'intérieur: PyModule_AddIntConstant(poModule, "NAMECOLOR_WAYPOINT", CInstanceBase::NAMECOLOR_WAYPOINT); On colle ceci dessous: PyModule_AddIntConstant(poModule, "NAMECOLOR_BOSS", CInstanceBase::NAMECOLOR_BOSS); On en a fini avec ce fichier, toujours dans le même dossier on cherche maintenant le fichier PythonMinimap.h. On cherche à l’intérieur ceci: TInstanceMarkPositionVector m_BossPositionVector; TInstanceMarkPositionVector m_NPCPositionVector; On ajout ceci en dessous: TInstanceMarkPositionVector m_BossPositionVector; On en a fini avec ce fichier maintenant toujours dans le même dossier on cherche le fichier PythonMinimap.cpp On cherche ceci: m_NPCPositionVector.clear(); On ajout en dessous ceci: m_BossPositionVector.clear(); On cherche maintenant le bloque des NPC: // NPC STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_NPC)); aIterator = m_NPCPositionVector.begin(); while (aIterator != m_NPCPositionVector.end()) { TMarkPosition & rPosition = *aIterator; m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); m_WhiteMark.Render(); ++aIterator; } On ajout ce bloque qui correspond à celui des BOSS: // Boss STATEMANAGER.SetRenderState(D3DRS_TEXTUREFACTOR, CInstanceBase::GetIndexedNameColor(CInstanceBase::NAMECOLOR_BOSS)); aIterator = m_BossPositionVector.begin(); while (aIterator != m_BossPositionVector.end()) { TMarkPosition & rPosition = *aIterator; m_WhiteMark.SetPosition(rPosition.m_fX, rPosition.m_fY); m_WhiteMark.Render(); ++aIterator; } On recherche ensuite ceci: else if (pkInstEach->IsEnemy()) { aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; m_MonsterPositionVector.push_back(aMarkPosition); } On ajoute en dessous ceci: else if (pkInstEach->IsBoss()) { aMarkPosition.m_fX = ( m_fWidth - (float)m_WhiteMark.GetWidth() ) / 2.0f + fDistanceFromCenterX + m_fScreenX; aMarkPosition.m_fY = ( m_fHeight - (float)m_WhiteMark.GetHeight() ) / 2.0f + fDistanceFromCenterY + m_fScreenY; m_BossPositionVector.push_back(aMarkPosition); } Vous pouvez maintenant ouvrir Visual Studio, nettoyer votre projet, et le recompiler. Nous passons maintenant à la partie python, pour cela vous allez depack les fichiers root.eix et root.epk. Une fois depack on se rend dans le dossier root et on cherche le fichier python colorInfo.py On ajoute la ligne suivante où l'on veut: CHR_NAME_RGB_BOSS = (9, 22, 255) Vous pouvez changer la couleursur ce site en entrant les différentes valeurs. On cherche ensuite le fichier suivant introloading.py (toujours dans le dossier root): On cherche dedans la ligne suivante: chrmgr.NAMECOLOR_WAYPOINT : colorInfo.CHR_NAME_RGB_WAYPOINT, Et on ajoute en dessous ceci: chrmgr.NAMECOLOR_BOSS : colorInfo.CHR_NAME_RGB_BOSS, Voilà le tutoriel est maintenant terminé merci à vous j'espère que ça vous aidera et vous apportera un petit plus. Cordialement,
  4. 3 points
    Bonjour, J'aimerais vous faire part de mon partage d'un très gros pack complet de serveur metin 2 ou j ai passer presque 6 mois a bosser dessus suite , a ma reprise de boulot dans la vie actif je n'est plus le temps de m'occuper de tout sa et je trouve sa dommage de faire dormir sa sur mon pc donc je laisse un lien de dl pour récupéré tout sa en espérant que vous ailler une bonne connexion car le dossier et très gros en espérant que vous me laisserez des bon coms et oublier pas un pouce bleu Merci. Source=moi Lien de dl=Contenu Masqué Le fichier a dl comporte : Client Lib source Files Se sont des files 2014 toute debug , tout l interface et modifier le client et en qualité hd , ce qui de l implantation dans le client tout et implanter les magasin hors ligne , le switchbot, interface inédite en jeu et plein autre surprise je vous laisse découvrir, je vous laisse un gros partage prenez en par que c'est beaucoup de boulot et que je partage tout sa avec plaisir pour ma part! 😉
  5. 2 points
    C'est un peu sale tout ça... Y'a moyen d'améliorer ce méli-mélo ^^. Trois possibilités : BOOL CInstanceBase::IsBoss() { switch(GetRace()) case 691: case 692: case 693: case 791: case 991: case 992: case 993: case 1091: case 1092: case 1093: case 1094: case 1095: case 2191: case 1191: case 1192: case 1304: case 1306: case 1307: case 1901: case 1902: case 1903: case 2206: case 2207: case 2291: case 2306: case 2307: case 2492: case 2493: case 2494: case 2598: case 3090: case 3091: case 3190: case 3191: case 3290: case 3291: case 3390: case 3391: case 3490: case 3491: case 3590: case 3591: case 3690: case 3691: case 3790: case 3791: case 3890: case 3891: case 5001: case 5004: case 5002: case 5161: case 5162: case 5163: case 6091: case 6191: return TRUE; break; // Si on ne break pas, il passe au case suivant default: return FALSE; break; } La manière plus propre, mais toujours un peu sale, ou alors une manière plus propre de faire la même chose: BOOL CInstanceBase::IsBoss() { const char maxElems = 56; int iVnums[maxElems] = { 691, 692, 693, 791, 991, 992, 993, 1091, 1092, 1093, 1094, 1095, 2191, 1191, 1192, 1304, 1306, 1307, 1901, 1902, 1903, 2206, 2207, 2291, 2306, 2307, 2492, 2493, 2494, 2598, 3090, 3091, 3190, 3191, 3290, 3291, 3390, 3391, 3490, 3491, 3590, 3591, 3690, 3691, 3790, 3791, 3890, 3891, 5001, 5004, 5002, 5161, 5162, 5163, 6091, 6191 }; for (int i=0; i < maxElems; i++) { if (GetRace() == i) return TRUE; } return FALSE; } Le problème de Metin2 c'est qu'ils sont bêtes au point d'avoir oublié de différencier les vrais boss avec de simples pierres Metin ou monstres nommés. C'est con, mais c'est pas irréalisable, je m'y étais penché un peu plus dessus... En gros l'idée c'est qu'un boss c'est un rank supérieur ou égal à 4, et qui n'est pas une pierre metin. Dans l'idéal et en troisième option, pour faire un truc vraiment plus propre il faudrait faire un truc du style: BOOL CInstanceBase::IsBoss() { const CPythonNonPlayer::TMobTable *pkTab = CPythonNonPlayer::Instance().GetTable(GetRace()); if (pkTab->bRank >= 4 && pkTab->bType == 0 && !IsStone()) return TRUE; return FALSE; } C'est beaucoup plus agréable à lire et plus simple d'utilisation ;). La condition c'est que le Type soit égal à 0 (NPC de type mob), que son rank soit supérieur ou égal à S_KNIGHT ( = 4 comme le chef orc, et 5 comme le Dragon Rouge, de rank KING), et que le mob en question ne soit pas une pierre Metin (car leur rank est égal à 5 !) Des bisous
  6. 1 point
    Salut , je vous partage emulateur symbioz 2.30 de skinz Lien : Contenu Masqué l'emulateur est codé en C# le site d'origin du partgae c DoE emulateur code par Skinz PS: Certaines parties sont a refaire: (les tools sont assez sale :3 et le fonctionnement de parser d'effet de sorts et d'item) Il est loin d'être terminé, et il y a beaucoup de travail a faire Fonctionne avec le client dofus 2.30
  7. 1 point
    Bonjour à tous, Je viens de mettre la main sur Stump 2.42, j'en profite pour le partager ici: Emulateur: Contenu Masqué Client: Contenu Masqué Les BDD sont incluses dans l'archives de l'émulateur. Have fun !
  8. 1 point
    En soit ça reste quelque chose de pas mal, bon des systèmes basiques mais je pense que ça pourrait aider plus d'un débutant avec se que tu propose. Good Luck Je suis totalement d'accord avec toi Gin sur le faire qu'ici ils veulent tout sur un plateau. La plus part ne savent pas se débrouiller seul ou même utiliser un navigateur internet pour réussir résoudre son problème. Parfois c'est dommage parce que tu vois des serveurs qui tournent mais ce n'est pas grâce à leurs "talent" si je puis dire.
  9. 1 point
    Yo, juste avant de te proposer une aide supplémentaire : tu utilises les files 2014+ sous FreeBSD (avec VirtualBox) ? Si oui, inutile car il y a un bug existant : Tu es déconnecté lors de la sélection du personnage pour les personnes externe à ton réseau...
  10. 1 point
    Salut Funky-Emu. Aujourd'hui je vais vous apprendre à installer HabboPHP et l'utiliser Pour suivre ce tutoriel, il vous faudra soit Phoneix soit Butterfly Il faudra totalement supprimer votre ancien CMS mais pas les SWF ! Téléchargement : ici Scan virus : ici On va maintenant l'installer, vous allez déplacer tout les fichiers de l'archive dans votre dossier web (ftp pour hebergeur // htdocs pour XAMP /// www pour WAMP) Un fois fait rendez vous sur : Contenu Masqué ou l'adresse de votre hébergement web. Faites "C'est partit" Allez ensuite dans votre base de donné, par exemple avec phpmydamin ça donne : -Allez dans votre base de données -Faites "importer" -sélectionner votre fichier .sql se trouvant dans pheonix : Faire ensuite "Exécuter" L'importation va durer un petit moment, c'est possible. Retournez sur votre localhost puis : Configurez comme il se doit ceci, puis, attendez phpmyadmin est finis toutes ses requêtes, puis faites : "Envoyer" puis "vérifier" Remplissez comme vous le voulez puis faites : "Envoyer" Ensuite, aller dans votre fichier web, puis supprimer le dossier "install" une fois ceci, fait allez sur Contenu Masqué Connectez-vous, et allez dans la Housepeeking (administration) : Allez dans l'onglet serveur et si vous avez suivis le tutoriel de Calypso vous devez entrer ça : (Si non, corrigez ce qu'il faut !) Adresse Emulateur : 127.0.0.1 Port Emulateur : 3000 Texts : Contenu Masquégame/gamedata/external_flash_texts.txt Variables : Contenu Masquégame/gamedata/external_variables.txt Habbo SWF : Contenu Masquégame/gordon/PRODUCTION-201602082203-712976078/Habbo.swf Ce qui devrait vous donnez ça : Une fois ceci fait, vous voilà Administrateur, cms configurer, je crois que c'est bon non ? Petit bonus, pour changer ça : Allez dans : admin\includes\footer.php admin\form\includes Voilà, après ce petit bonus, je vous laisser Bon jeu !! Cordialement.
  11. 1 point
    Bien le bonjour ! Je vous partage une ancienne et texture que j'ai pu faire, même si l'armure est déjà partagée elle est quand même présente dans le fichier de téléchargement avec sa texture originale ! Lien de téléchargement : Cliquez ici Source : Moi même Mei,
  12. 1 point
    Salut à toi ! Je vais vous expliquer comment repack et depack vos fichiers eix / epk Metin2. Qu'est ce que ces fichiers ? Ce sont tout le contenu de votre client tel que les maps, les modèles 3D, les armes, les interfaces, etc .. Ce sont tous les fichiers qui se trouvent dans le dossier pack. I. Téléchargement EterNexus: Contenu Masqué II. Depack un fichier 1. Dans le menu Plus, cliquez sur Extraire 2. Choisissez le fichier que vous voulez extraire (dans le dossier pack de votre client). Je vais ici depack le fichier root. Ensuite, cliquez sur Ouvrir. 3. Le fichier a été depack. Vous verrez un dossier appelé root dans le dossier pack de votre client. Tout le contenu du pack se trouve dans le dossier root. Si vous depackez le fichier BGM, le dossier s'appellera BGM, et etc .. II. Repack un fichier 1. Il est important de repack un fichier pour que la modification effectué dans les fichiers du pack soient prise en compte. Dans le menu Plus de EterNexus, cliquez sur Archiver. 2. Il faut sélectionner le dossier que vous voulez repack (dossier qui se trouve dans le dossier pack de votre client). Dans notre cas, nous voulons repack le dossier root, donc je sélectionne le dossier root. 3. Une fois le repack terminé, vous trouverez les fichiers repack dans le dossier où se trouve votre logiciel EterNexus. 5. Il suffit de déplacer ces deux fichiers dans le dossier pack de votre client et de remplacer les anciens. III. Fin du tutoriel Vous savez maintenant depack et repack un fichier. Si tu as besoin d'aide, n'hésite pas à aller créer un topic dans la catégorie Aide / Question / Support de la section Metin2. La communauté sera là pour vous aider. A bientôt !
  13. 1 point
    Salut tout le monde, J'ai rencontré pas mal de personnes sur forum cherchant les lib pour leur dédier. La plupart sont données par MP, ou par Skype. Donc toutes les personnes ne dispose pas forcément l'accès au téléchargement des lib. C'est pour ça qu'ici, je vais mettre en téléchargement les libs pour votre serveur ainsi que comment les installer. Petit tutoriel certes, mais qui peut être très utile pour certains Prenez bien les lib qui correspondent à votre serveur, renseignez-vous Lib 32 Bits : Contenu Masqué Lib 64 Bits : Contenu Masqué Rien n'est plus facile que d'installer les libs sur votre dédier. Donc comme je l'ai dit, il faut choisir les libs en fonction de son serveur. Si votre serveur est en 32 BITS, téléchargez les libs pour 32 BITS et si vous avez un serveur qui est en 64 BITS, téléchargez les libs pour 64 BITS. Enfin bref, je rentre trop dans lés détails ^^ Donc, connectez vous à votre WinSCP et allez dans /usr/libs/ Il suffit donc de faire glisser les libs dans ce dossier. C'est la même chose pour un 32 BITS ou un 64 BITS. On ne remplace jamais une lib ! Si cela ne fonctionne pas, il vous faudra aussi placer les libs dans le dossier /usr/lib32/. Maintenant, vous manque plus qu'à démarrer votre serveur et tout devrait fonctionner. Cordialement, Calypso
  14. 1 point
    Salut à toi ! Tu n'as jamais fait de serveur Metin2 ? Ce tutoriel est fait pour toi ! Je vais t'expliquer comment créer un serveur de A à Z ! Tu pourras ensuite le modifier à ta guise et le modifier à ton image. Lors de ce tutoriel, vous allez apprendre à créer un serveur en localhost ! C'est-à-dire un serveur rien que pour vous, vous serez le seul à pouvoir vous y connecter. Prêt ? Alors commençons ! I. Téléchargement VirtualBox - Contenu Masqué Navicat - Contenu Masqué WinSCP - Contenu Masqué Le serveur (le VDI) - Contenu Masqué Le client - Contenu Masqué II. La machine virtuelle 1. Installez VirtualBox. Il nous permettra de virtualiser le système d'exploitation FreeBSD. 2. Lancez le logiciel VirtualBox 3. Cliquez sur le bouton Nouvelle, en haut à gauche 4. Choisissez un nom pour votre machine virtuelle. Dans Type, choisissez BSD et dans Version, FreeBSD (32bit ou 64bit en fonction de votre ordinateur). Et cliquez sur Suivant 5. Allouez la mémoire vive à votre machine virtuelle en fonction de votre ordinateur. Le minimum conseillé est 1go (1024Mo). N'hésitez pas à en donner plus le temps que le curseur est dans la barre verte. Cliquez sur Suivant. 6. Cochez la case " Utiliser un fichier de disque dur virtuel existant " et choisissez le fichier VDI (.vdi) que vous avez téléchargé. Cliquez ensuite sur Créer. 7. Votre machine virtuelle est crée. Configurons la carte réseau. Clique droit sur votre VM (virtual machine) puis Configuration 8. Dans le menu Réseau, mettez " Accès par pont " dans mode d'accès réseau et dans nom, mettez votre carte réseau (carte Wifi si vous êtes en WIF ou Ethernet si vous êtes en Ethernet). Cliquez ensuite sur OK. 9. Votre machine virtuelle est maintenant créée ! III. Lancement du serveur Metin2 1. Pour lancer votre machine virtuelle, il suffit de cliquer deux fois sur votre machine. Une fenêtre s'ouvre et votre système d'exploitation démarre. Patientez. On vous demande ensuite de vous connecter à un utilisateur. 2. Dans login, entrez: root pour login et dans Password, mettez mcncc.com. Vous êtes maintenant connecté et vous avez accès à tout le système d'exploitation. Dans le terminal, tapez cd /usr/metin2 4. Vous voila dans le dossier de votre serveur metin2. Pour démarrer le serveur il suffit de taper: sh start.sh (et sh stop.sh pour l'arrêter). Entrez ensuite le nombre de channel que vous voulez ouvrir. Pour commencer, un seul suffit. 5. Votre serveur Metin2 est lancé ! Il ne vous reste plus qu'à configurer votre client ! Bien entendu, laissez votre fenêtre Virtual Box ouverte pour que votre serveur reste ouvert. IV. Se connecter In Game ! 1. Commencez par extraire le client de Client 2014.rar sur votre bureau. 2. Il faut configurer le client de sorte à ce qu'il se connecte sur l'adresse IP de votre serveur. Il existe un tutoriel pour vous apprendre à le faire: Contenu Masqué 3. Pour obtenir l'IP de votre machine, il suffit de faire la commande ifconfig sur votre machine virtuelle et de repérer l'adresse IP commençant par 192.168 (l'ip locale) 4. Dans mon cas, je vois bien 192.168.43.205 C'est celle-ci ! 5. Une fois la configuration terminée, lancez metin2client.exe qui se trouve à la racine de votre client. 6. Connectez vous avec ces identifiants. User: admin Mot de passe: test 7. Choisissez votre personnage et ça y est, vous voila sur votre premier serveur privé Metin2 ! V. Accéder aux fichiers du serveur 1. Pour accéder aux fichiers du serveur, il faut installer le logiciel WinSCP. Une fois installé, lancez le. 2. Cliquez sur nouveau site et remplissez comme l'image ci dessous 3. Vous voici connecté à WinSCP. Vous avez tout simplement un accès à votre système d'exploitation FreeBSD mais cette fois avec un explorateur de fichier, et non en ligne de commande. 4. Déplacez-vous dans l’arborescence. Cliquez sur .. pour revenir à la racine du serveur, cliquez sur le dossier usr puis metin2. Vous tombez sur: 5. Ceci sont les fichiers serveur de votre serveur Metin2 ! VI. Accéder à la base de données du serveur 1. La base de données contient toutes les données de votre serveur (comptes, joueurs, etc ..). Pour y accéder, installez Navicat et lancez-le. 2. Cliquez sur le bouton Connection puis MySQL 3. Remplissez comme l'image ci-dessous: 4. La connexion s'est créé dans le volet de gauche. Il suffit juste de cliquer 2 fois dessus pour s'y connecter. 5. Ceci est la base de donnée de votre serveur Metin2 ! VII. Fin du tutoriel C'est tout bon, vous avez tous les outils pour créer un serveur Metin2 à votre image FAQ des débutants à voir absolument: Contenu Masqué Si tu as besoin d'aide, n'hésite pas à aller créer un topic dans la catégorie Aide / Question / Support de la section Metin2. La communauté sera là pour vous aider. Bon courage, jeune apprenti !
  15. 1 point
    Bonjour à toutes et à tous ! Dans ce tutoriel (partagé originalement par Craven), je vais vous expliquer comment ajouter un bouton à la taskbar, soit ceci : Plus précisément, nous allons ajouter un bouton ici : Pour cela, dans ce tutoriel, je vais assigner à ce bouton ceci : Ne vous inquiétez pas, je vais aussi vous apprendre à l'assigner à n'importe quoi ! Pré-requis : Un éditeur python, Un dépackeur tel que EterNexus Un client, Ce fichier Python : ici Dans tous le tutoriel, n'oubliez pas de remplacer les espaces (tous les quatre espaces) par des tabulations ! Dépack Pour ce tutoriel, je vais vous demander de dépack : root locale Pack locale Rendez vous dans : locale\fr\ui\ Vous y trouverez un fichier nommé : taskbar.py Ce fichier contient les éléments et la disposition des éléments de la taskbar. Nous allons ajouter notre boutons. Inspirons-nous d'un autre bouton, par exemple : { "name" : "InventoryButton", "type" : "button", "x" : SCREEN_WIDTH - 110, "y" : 3 + Y_ADD_POSITION, "tooltip_text" : uiScriptLocale.TASKBAR_INVENTORY, "default_image" : ROOT + "TaskBar/Inventory_Button_01.sub", "over_image" : ROOT + "TaskBar/Inventory_Button_02.sub", "down_image" : ROOT + "TaskBar/Inventory_Button_03.sub", }, Ajoutez en dessous : { "name" : "BonusGui", "type" : "button", "x" : SCREEN_WIDTH - 178, "y" : 3 + Y_ADD_POSITION, "tooltip_text" : "Bonus", "default_image" : ROOT + "TaskBar/Inventory_Button_01.sub", "over_image" : ROOT + "TaskBar/Inventory_Button_02.sub", "down_image" : ROOT + "TaskBar/Inventory_Button_03.sub", }, Bien, qu'avons nous là... name = Il faut bien pouvoir désigner le bouton par quelque chose, donc on lui donne un nom ! type = Il faut bien que Python sache de quoi on parle ! Ici, un bouton. x = C'est bien beau de savoir ce que c'est, mais où on le met ? Et bien c'est pour ça qu'x est là, il place le bouton sur l'axe des abscisses. y = Il place le bouton sur l'axe des ordonnées. tooltip_text : Cela permet d'afficher une indication textuelle : default_image : Désigne la texture du bouton quand il ne se passe rien. over_image : Désigne la texture du bouton quand la souris passe dessus. down_image : La texture du boutons quand on clique dessus. Ce qui vous donne : Biens, vous pouvez déjà repacks votre locale. Attaquons le root Bien, nous attaquons maintenant le pack root. Ouvrez le fichier : Cherchez ensuite la ligne : toggleButtonDict[TaskBar.BUTTON_CHARACTER]=self.GetChild("CharacterButton") Ajoutez : toggleButtonDict[TaskBar.BUTTON_BONUSGUI]=self.GetChild("BonusGui") Changez : self.GetChild("BonusGui") Par le nom que vous aurez mis dans "name" dans l'étape ci-dessus. Ici, nous créons un bouton, qui va "s'inspirer' de BonusGui. Il va prendre ses propriétés. Bien, cherchez maintenant : BUTTON_CHAT = 4 Créons une variable, et attribuons lui le chiffre intègre 5 : BUTTON_BONUSGUI = 5 Le nom correspondant à celui-ci : toggleButtonDict[TaskBar.BUTTON_BONUSGUI]=self.GetChild("BonusGui") Bien, on en a fini avec ce fichier, on passe au suivant ! Ouvrez le fichier : Pour les clients 2013 et moins : Cherchez : self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_CHAT, ui.__mem_func__(self.ToggleChat)) Ajoutez : self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_BONUSGUI, ui.__mem_func__(self.BonusGui)) Pour les 2014 et plus : Il faut ajouter : self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_BONUSGUI, ui.__mem_func__(self.BonusGui)) En dessous de : self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_SYSTEM, ui.__mem_func__(self.ToggleSystemDialog)) TaskBar.BUTTON_BONUSGUI Qui correspond à celui rentré précédemment. Et : (self.BonusGui) Ici, c'est le "name" qu'on a vu au tout début ! Ici, on désigne la fonction qui va s'exécuter lorsqu'on va cliquer sur le bouton. Maintenant il vous suffit d'ajouter le code que vous souhaitez exécuter lorsqu'on clic sur ce bouton. Je vais donc utiliser le code pour la Bonus Gui. Mettez où vous le souhaitez, pour ma part je l'ai mis au dessus de " def __MakeParty(self):" Pour les personnes implantant la bonus gui, ajoutez ceci: def BonusGui(self): import uiBonusPage global BPisLoaded try: if BPisLoaded != 1: exec 'uiBonusPage.BonusBoardDialog().Show()' else: pass except ImportError: import dbg,app dbg.Trace('uiBonusPage.py Importing error') app.Abort() Pour les autres, vous pouvez ajouter le code que vous voulez après le def. (n'oubliez pas le (self):) Écrivez le même nom que celui que vous avez inscrit dans name. Pour ceux qui implantent un code personnalisé, vous pouvez vous arrêter là, et faire vos autres modifications. Pour ceux qui suivent ce tuto à la lettre, vous allez devoir ajouter quelques autres choses du côté de la gui bonus. Cherchez : IsQBHide = 0 Ajoutez : BPisLoaded = 0 Allez ensuite dans le fichier : Cherchez la fonction : def SetOverVisual(self, filename): Ajoutez en dessous : ##Bonus def GetText(self): if not self.ButtonText: return return self.ButtonText.GetText() def SetDownVisual(self, filename): wndMgr.SetDownVisual(self.hWnd, filename) Mettez ensuite le fichier téléchargé au début du tutoriel dans le root, et packez le tout. Et voilà, admirez votre magnifique travail !
  16. 1 point
    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.53.2. Sources: Contenu Masqué Je ferais un tutoriel à l'occaz' sur l'installation de l'ému Cordialement, Sgt
  17. 1 point
    Au niveau de votre API, quid du fonctionnement avec CloudFlare ?
  18. 1 point
  19. 1 point
    Salut tout le monde ! Ce tutoriel vous permettra de créer un serveur WoW Cataclysm en version 4.3.4 en local ou en hamachi.
  20. 1 point
    C'est vrai d'ailleurs, ça m'fait penser @AriusII t'as eu ton cadeau toi ?
  21. 1 point
    Salut ! Je les ai pas vu, donc je les partages vite fait : Contenu Masqué Je crois qu'il faut QT, mais bon, faut mieux demander à des personnes plus compétentes en C++ que moi :XX Y'a pas grand chose d'autre à écrire Ploush ploush
  22. 1 point
    Hellow. Je vien vous partager un nouveau set d'armes - Gr2 - Icon - Texture - Source : FreakGamers Lien du téléchargement : Cliquer ici LastHope - Metin2World.
  23. 1 point
    Alors, avant de parler de quoi que ce soit : De nombreux MenuAdmin existent pour AncestraR, seulement, certains sont mal organisés ou pas suffisamment complet. J'espère que celui ci pourra palier ces problèmes. Je pense qu'une petite explication des trois versions n'est pas de trop. La v1 possède deux commandes sur le menu principal : Signaler sa présence au staff et Signaler sa présence aux joueurs. Le premier lance sur le chat : /q viens de se connecter. Ainsi tout les joueurs GM1 ou plus pourront le lire. Le deuxième lance sur la console : nammounce viens de se connecter. Ainsi tout les joueurs ayant le canal vert ouvert pourront lire le message. La v2 possède la deuxième commande sur le menu principal. La première commande se trouve dans le StartUp et sera lancée automatiquement à la connexion du joueur. La v3 possède les deux commandes dans le StartUp et elles seront lancées automatiquement à la connexion du joueur. Ce MenuAdmin sera mis à jour suivant vos critiques et remarques et a chaque nouvelle commandes implantables. Menu Principal => (Version2) Lien de téléchargement : Contenu Masqué ___ Voici pour la présentation du MenuAdmin. Je suis disponible pour vos remarques/idées via les messages privé de Funky-Emu ou via [email protected] Merci de respecter mon travail.
  24. 1 point
    Salut ! Je vais voir pour le télécharger, voir les potentiels bugs, les corriger si j'en suis capable (je suis pas non plus une experte), et vous publiez un .vdi, etc. Ça à l'air d'être à la mode sur ce forum...
  25. 1 point
    Bonjour ! J'ai transformé des images de bitefight en TGA , pour que cela puisse devenir des items. Casques , Boucliers , bottes et colliers. Malheureusement dans ce jeu il n'y a pas de boucles ni de bracelets Source des images : Bitefight Wiki Lien de téléchargement :Cliquez ici Cordialement,
  26. 1 point
    Bonjour à tous ! Aujourd’hui je vais vous apprendre à mettre en place un serveur privé RaiderZ ! /!\ Ce tutoriel ne demande aucune connaissance particulière en informatique, et est accessible à tous /!\ Pré-requis : Un ordinateur ou un VPS utilisant Windows 7 ou plus PostGreSQL Driver ODBC PostgreSQL Navicat 12.0, DataGrip, ou n’importe quel programme de gestion de BDD fonctionnant avec PostgreSQL Le DevKit de RaiderZ Notepad++ /!\ Ce tutoriel est réalisé avec PostgreSQL 10.1 et Navicat 12.0.13 /!\ I) Installation de PostgreSQL Lancez le fichier d’installation, et suivez les étapes jusqu’à la création du mot de passe de l’utilisateur par défaut. Entrez le mot de passe que vous voulez (c’est celui qui sera utilisé plus tard pour configurer le serveur). Une fois l'installation finie, décochez la case Stack Builder et cliquez sur "Terminer" II) Installation de Navicat → Voir[Partage]Navicat 12.0.13 III) Configuration de PostgreSQL A) Création des BDD Pour créer les tables, allez dans votre menu démarrer, et cherchez: Lancez le programme, et validez par "Entrée" jusqu'au mot de passe: Vous vous souvenez du mot de passe que vous avez mis à l'installation? Tapez le /!\ Le mot de passe ne s'affiche pas quand vous le tapez, c'est normal ! /!\ Une fois que vous êtes connecté, vous pouvez taper la commande suivante: Puis validez par "Entrée". Faites la même chose pour les deux bases de données restantes, en validant bien par "Entrée", et en oubliant pas le ; à la fin: Vous pouvez fermer, vos tables sont créées! B) Configuration de Navicat La configuration de Navicat est assez simple, commencez par ajouter une nouvelle connexion PostgreSQL: Puis configurez le serveur comme sur le screen: Dans le champ "password", mettez votre mot de passe PostgreSQL. C) Restauration des tables C'est sans doute la partie la plus compliquée du tutoriel, accrochez vous ! Cherchez le dossier d'installation de PosgreSQL, et allez dans le dossier "bin": /!\ Si vous ne l'avez pas modifié, c'est C:\Program Files (x86)\PostgreSQL\10\bin /!\ Une fois que vous avez trouvé le dossier, ouvrez une fenêtre de commande et faites un cd pour arriver jusqu'au dossier: Vous êtes prêt à lancer les commandes ! Pour créer les tables, vous devez utiliser la commande suivante: psql : Nom du programme principal de PostgreSQL -U postgres : Nom d'utilisateur pour se connecter à la BDD -d rz_account : Nom de la base de donnée -f C:\Users\...\rz_accountdb.sql : Fichier de sauvegarde à restaurer Une fois la commande tapée, validez avec "Entrée", vous devriez avoir ceci qui s'affiche dans la fenêtre de commande: Vous connaissez la chanson: tapez votre mot de passe PostgreSQL Une fois le mot de passe validé, la restauration se fera automatiquement, et vous devriez voir ceci: Faites la même chose, mais pour la base de donnée rz_gamedb avec le fichier rz_gamedb.sql la commande devrait mettre quelques dizaines de secondes à se finir. Après ça, vous pouvez fermer la console, on en a fini avec elle ! Pour vérifier que vos tables sont bien mises, vous pouvez allez vérifier dans Navicat: IV) Configuration des files Dans chaque dossier du serveur se situe un fichier server.ini. C’est lui qui contient la configuration De chaque programme du serveur. Vous devez ouvrir chaque fichier server.ini, et remplacer à l’intérieur de cette ligne : PASSWORD = "password" password par votre mot de passe PostgreSQL. Exemple: V) Installer le driver ODBC Ouvrez le fichier d’installation des drivers ODBC, et installez le. Allez dans Panneau de Configuration → Outils d’administration → Sources de données ODBC (32 bit): /!\SI VOUS N'AVEZ PAS L’ICÔNE ODBC/!\ (Merci Saya pour l'astuce ! ) Une fois dans le menu des sources de données, rendez vous dans l’onglet Utilisateur, cliquez sur « Ajouter », et sélectionnez « PostgreSQL Unicode » dans la liste, puis cliquez à nouveau sur « Ajouter »: Configurez le driver comme suit : Cliquez ensuite sur "Tester", si ce message: s'affiche, c'est que tout est bon ! V) Relier le client au serveur Pour relier le client au serveur, ouvrez le fichier « RaiderZ Run.bat », et changez l’adresse IP par celle de votre serveur. Exemple : ./START Raiderz.exe localhost Exemple : ./START Raiderz.exe 142.89.32.16 Voilà, vous avez un serveur complet fonctionnel ! Il ne vous reste plus qu'à le lancer ! VI) Lancement du serveur Pour lancer le serveur, vous devez simplement lancer, dans n'importe quel ordre, les quatre programmes: LoginServer AppServer GameServer MasterServer VII) Quitter le serveur Pour quitter le serveur, vous avez juste à fermer le programme "MasterServer", et le reste suivra ! Pour continuer: Si le tutoriel vous a été utile, laissez un point de réputation ou un commentaire, ça fait toujours plaisir !
  27. 1 point
    Salut. Pour les files 2014+, il est inutile de depack l'item proto du client. Il te faut aller sur WinSCP (ou Filezilla, selon ce que tu utilises) puis prendre l'item_proto.txt et l'item_names.txt qui s'y trouvent. Tu peux ensuite effectuer y tes modifications et tu devras ensuite les repack en utilisant un dump proto adéquat à tes files. Egalement, penses à utiliser EterNexus plutôt que M2Repacker pour depack/repack.
  28. 1 point
  29. 1 point
    Bonjour, je t'ai contacter sur discord. Au plaisir Astro
  30. 1 point
    Bonjour, De rien, bonne journée également !
  31. 1 point
    Disclaimer : This guide is only a translation of the following tutorial made by Emulateur and then renewed by Calypso. The screenshots are still in French as for now and the tutorial may be aged but still works like charm. [.To be continued.] Hey there! You want to create a metin2 private server? You want to play with your friends? Create a community or create one just as a hobby? Then follow this guide! I will explain you how to create a private server! You will then be able to do whatever you want on it? Ain't it cool? Buuut... This tutorial will work only in localhost, implying that you will be the only one able to connect and play on it. It's some kind of a test server. Ready? Go! I. Downloads VirtualBox - Contenu Masqué Navicat - Contenu Masqué WinSCP - Contenu Masqué The server (VDI file) - Contenu Masqué The client- Contenu Masqué II. Virtual Machine 1. Install VirtualBox. You will use it as a way to emulate the Operating System called FreeBSD. (The server will run on this OS) 2. Start VirtualBox 3. Click on "New" at the bottom left of the screen. 4. Choose a name and name the Virtual Machine. Choose BSD for Type and FreeBSD (XXbits depending on your OS, most likely 64bits) in Version. Then click on Next 5. Allocate the amount of RAM of your choice to the Virtual Machine. Note that you'll be fine with 2048Mo (It might even be overkill for a server you'll only use alone). The minimum I advise you to allocate is 1Go (1024Mo). Anyway, as long as you're in the green bar you're fine. Click Next. 6. Tick the "Use and already existing virtual disk" (Or something like that, that's the last box) and select the VDI (.vdi) you just downloaded in Step 1. Then press Create. 7. Your Virtual Machine is now created. Now let's configure the Networking. Right click on your VM (Virtual Machine) then hit Configuration 8. In Network, select "Bridged" for Networking Mode and in Name, select your Networking Card. Then click OK. 9. The networking is now selected and the Virtual Machine created! Let's go to step three. III. Start your server 1. If you want to start the VM, you just have to double click on it. The Virtual Machine will start. Wait a bit. Now it asks you to connect a user. 2. In login, put: root and in Password, write mcncc.com. You are now fully connected as a super user. If you want to start the files, begin with typing cd /usr/metin2 4. Now you are in the metin2 files folder. You just have to type to start it : sh start.sh (and sh stop.sh to close it). And then the number of channel that you want to open. One channel is perfect to begin with. 5. Your Metin2 server is now working ! You just have to configure the client ! Of course, you need to leave Virtual Box open if you want your server to be openned as well. IV. Connection to the client ! 1. Extract the file Client 2014.rar on your computer, i.e your Desktop. 2. Then, you need to configure the serverinfo.py and put your ip inside. Here's a guide for it (Still in French ATM) : Contenu Masqué 3. If you want to get your VM's IP, you need to type ifconfig and notice the IP starting with 192.168 (That's a locale IP) 4. In my case, it's 192.168.43.205 That's the one we're after ! 5. Once the configuration is done, start metin2client.exe which is at the root of your client. 6. Use these already existing admin credentials : User: admin Password: test || You can change them or create a new one later on. 7. Choose your character, and voilà ! Your connected on your first Metin2 private server ! V. Gain access to the files 1. If you want to inspect or modify the files, you need to install the software "WinSCP". Once it's installed & started, do as explained below. 2. Click on "New Site" and do as the following screenshot. 3. Now you're connected to WinSCP. You can now browse through the files with a software instead than a terminal. 4. Click on .. to go at the root, then click on usr then metin2. You should be there: 5. These are the Folders & Files that your server contains ! VI. Gain access to the database 1. The database contains pretty much everything related to players, account and so on. Install Navicat and start it. 2. Click on Connect then MySQL 3. Fill it like this: Name The IP you saw before (starting with 192.168) 3306 root mcncc.com 4. On the left pannel you can see your server. In order to connect, you just have to click two times over it. 5. And this is the database of your server ! VII. End of the Tutorial Now, everything is alright, you can connect to the database, browse your files and edit your client ! You can now modifiy everything as you want FAQ - Must Read for beginners - (Still in French ATM) : Contenu Masqué If you need some help, don't hesitate and lead to Questions & Answer. The community will be there to help you. Good luck!
  32. 1 point
    Selenia - Emulateur Tera Fate Of Arun - FR 1 - Selenia, qu'est ce que c'est ? Selenia est un émulateur TERA que j'ai développé à partir d'une très grosse base d'un autre émulateur (angelis). A ce jour, il est possible de se connecter In Game. Il manque malgré cela, une très grande partie des OpCodes, il manque donc la moitié des fonctionnalité du jeu: Taper, sauter, etc ... Il est basé sur le dernier Client TERA et ne comporte pas encore les dernières nouveautés du jeu comme la nouvelle race. 2 - L'objectif ? L'objectif est de développer un émulateur (Je n'ai pas encore décidé pour l'open-source) Il pourra ainsi permettre la création de serveurs privé TERA. 3 - L'organisation du projet L'émulateur utilise Maven pour l'organisation du projet. Il utilise ainsi plusieurs librairies JAVA tel que nanohttpd ou Gson Enfin, pour finir, il utilise Hibernate qui est un framework open source. 4 - L'avancement Comme je l'ai dit plus haut, on peut se connecter In Game. Avant de pouvoir le partager sur FunkyEmulation, j'aimerais faire une revue totale de l'Auth. J'aimerais aussi corriger la plus grosse partie des bugs que j'ai pu rencontrer pour avoir un confort minimal et ainsi mettre en place des fichiers externes pour avoir une meilleure gestion des maps, des mobs, des drops, etc ... 5 - Screen
  33. 1 point
    Bonjour, Un tutoriel très simple et très rapide, on va pas se le cacher, je cherche pas très loin pour mes tutos.... Comment changer les NORM FULL BUSY ect de l'interface de connexion sur vos serveurs ! Exemples du tutoriel (et un coup de pub, mais faut pas le dire, surtout que le GA voudrait pas que je modifie ses packs, il serait pas très content ) : Depackez votre fichier root : Ouvrez "serverinfo.py". Vous devriez trouvez : STATE_NONE = '...' STATE_DICT = { 0 : 'Reboot', 1 : 'NORM', 2 : 'BUSY', 3 : 'FULL' } ça dépends de votre client. Vous pouvez donc remplacer selon vos envies, je vous explique juste un peut les choses (Il est gentil ce monsieur hein ? ) STATE_NONE = '...' // ---> Quand on ne peut pas se connecter au serveur (le client ne détecte pas le serveur) STATE_DICT = { 0 : 'Reboot', // ---> Bah comme sont nom l'indique quand le serveur est en redémarrage. 1 : 'NORM', // ---> Quand le serveur est près à recevoir les joueurs. 2 : 'BUSY', // ---> Quand le serveur comment à être pleins mais pas totalement plein. 3 : 'FULL' } // ---> Quand le serveur est complet. Une fois ceci vous pouvez donc déjà modifier mais pas ajouter de la couleurs, on va donc le faire tout de suite : exemple de code avec de la couleurs et les noms modifiés : STATE_NONE = '|cFFFF0000|hFERMEE' STATE_DICT = { 0 : '|cFFFF0000|hFERMEE', 1 : '|cff00ff00|hOUVERT', 2 : '|cffFF6800|hCHARGER', 3 : '|cffFF8300|hCOMPLET' } Pour ajouter de la couleur on ajoutes donc : |CodeCouleur|h Devant le terme que vous voulez utiliser. Je vous partage le code de certaines couleurs : cffff0000 = rouge cff00ff00 = vert cff0000ff = bleu cffffff00 = jaune cffff00ff = violet cff00ffff = cyan cff000000 = noir Pour en obtenir d'autre : tapez |cff puis le code rgb de votre couleur, par exemple ff0000 pour du rouge Pour obtenir le : | Utilisez la combinaison de touche : Alt Gr + 6 (celui avec le quel vous faites : - et non celui du pavez numérique Utiliser bien Alt Gr et non Alt ---> Si vous obtenez ♠ bah c'est que vous vous êtes et tromper de 6 et de Alt. Si mon tuto n'est pas assez précis, dites le moi Cordialement.
  34. 0 point
    Comme je te l'ai dis, ne t'attends vraiment à voir la solution arriver car personne ici ne la (sinon ça se saurait). Malheureusement
Ce classement est défini par rapport à Paris/GMT+02:00
×

Information importante

By using this site, you agree to our Conditions d’utilisation.