NazoX Posted February 15, 2022 Report Share Posted February 15, 2022 Buenas, como sabréis llevo un tiempo sin actividad, dado por varios motivos familiares, personales, etc, y bueno me he animado después de un tiempo a volver a Metin, se que la guía esta existe por todas partes, pero está mal, o faltan cosas, o explicado a medias etc, yo lo tengo adaptado con 4 Piedras, pero he hecho la guía para que podáis usar 6 piedras, con esta guía orientativa podéis usar 6 piedras, 4, 12 o las que queráis, e imagino que sirve para poner solo 1 o 2 piedras si lo hacemos a la inversa, en fin, empecemos. 1.Vamos a nuestro source y nos dirigimos a editar el archivo "item_length.h", una vez abierto buscamos: Quote ITEM_SOCKET_MAX_NUM = 3, 1.1 Ahora remplazamos por la cantidad de piedras que queráis (guía para 6 piedras) Quote ITEM_SOCKET_MAX_NUM = 6, 2.Ahora Editamos el archivo "Constants.cpp", y buscamos lo siguiente: Quote 3, // WEAPON_SWORD, 3, // WEAPON_DAGGER, 3, // WEAPON_BOW, 3, // WEAPON_TWO_HANDED, 3, // WEAPON_BELL, 3, // WEAPON_FAN, 3, // WEAPON_CLAW 0, // WEAPON_ARROW, 0, // WEAPON_MOUNT_SPEAR #ifdef ENABLE_WOLFMAN_CHARACTER 3, // WEAPON_CLAW #endif 2.1 Ahora lo remplazamos por lo siguiente: Quote 6, // WEAPON_SWORD, 6, // WEAPON_DAGGER, 6, // WEAPON_BOW, 6, // WEAPON_TWO_HANDED, 6, // WEAPON_BELL, 6, // WEAPON_FAN, 6, // WEAPON_CLAW 0, // WEAPON_ARROW, 0, // WEAPON_MOUNT_SPEAR #ifdef ENABLE_WOLFMAN_CHARACTER 6, // WEAPON_CLAW #endif 2.2 Ahora buscamos: Quote 3, // ARMOR_BODY, 2.3 Y remplazamos por: Quote 6, // ARMOR_BODY, #Nota: Si no tienes wolfman solo borra la línea o coméntala con // 3.Ahora nos vamos al source DB, mas concretamente al archivo "Cache.cpp" y buscamos: Quote if (isSocket) { iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", socket0, socket1, socket2"); iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen, ", %lu, %lu, %lu", p->alSockets[0], p->alSockets[1], p->alSockets[2]); iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen, ", socket0=%lu, socket1=%lu, socket2=%lu", p->alSockets[0], p->alSockets[1], p->alSockets[2]); } #Nota: Puede ser un poco diferente al vuestro, si no encontráis nada buscar "socket0, socket1" o "socket0 , socket1" 3.1 Remplazamos por: Quote if (isSocket) { iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", socket0, socket1, socket2, socket3, socket4, socket5"); iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen, ", %lu, %lu, %lu, %lu, %lu, %lu", p->alSockets[0], p->alSockets[1], p->alSockets[2], p->alSockets[3], p->alSockets[4], p->alSockets[5]); iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen, ", socket0=%lu, socket1=%lu, socket2=%lu, socket3=%lu, socket4=%lu, socket5=%lu", p->alSockets[0], p->alSockets[1], p->alSockets[2], p->alSockets[3], p->alSockets[4], p->alSockets[5]); } #Nota2: Si no queremos remplazar nada porque tenemos otro sistema, simplemente podéis añadir a continuación de "socket2" los demás, es decir socket2, socket3, socket4, socket5"); ([email protected] no esta mal ni falta un socket6) 4.Ahora vamos al archivo "ClientManagerPlayer.cpp" y buscamos: Quote str_to_number(item.alSockets[2], row[cur++]); 4.1 A continuación de este, añadiremos lo siguiente: Quote str_to_number(item.alSockets[3], row[cur++]); str_to_number(item.alSockets[4], row[cur++]); str_to_number(item.alSockets[5], row[cur++]); 4.2 Ahora buscamos x2: Quote "SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " #Nota: esto se realiza 2 veces, si no encontramos nada, probar a buscar "Select id" y lo veréis enseguida. 4.3 Ahora remplazamos por: Quote "SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,socket3,socket4,socket5,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " #Nota2: Como antes, si tenéis algún sistema y no queréis remplazar solo añadir "socket3,socket4,socket5" después del "socket2," 4.4 Buscamos el siguiente y repetimos el proceso. 5.Ahora nos vamos al Source Cliente ->GameLib->ItemData.h y buscamos: Quote ITEM_SOCKET_MAX_NUM = 3, 5.1 Remplazamos por: Quote Item_SOCKET_MAX_NUM = 6, 6.Ahora vamos a UserInterface->PythonPlayerModule.cpp y buscamos la función: Quote PyObject * chatGetLinkFromHyperlink(PyObject * poSelf, PyObject * poArgs) 6.1 Remplazamos por: Quote PyObject * chatGetLinkFromHyperlink(PyObject * poSelf, PyObject * poArgs) { char * szHyperlink; if (!PyTuple_GetString(poArgs, 0, &szHyperlink)) return Py_BuildException(); std::string stHyperlink(szHyperlink); std::vector<std::string> results; split_string(stHyperlink, ":", results, false); // item:vnum:flag:socket0:socket1:socket2:socket3:socket4:socket5 if (0 == results[0].compare("item")) { if (results.size() < 9) return Py_BuildValue("s", ""); CItemData * pItemData = NULL; if (CItemManager::Instance().GetItemDataPointer(htoi(results[1].c_str()), &pItemData)) { char buf[1024] = { 0 }; char itemlink[256]; int len; bool isAttr = false; len = snprintf(itemlink, sizeof(itemlink), "item:%x:%x:%x:%x:%x:%x:%x:%x", htoi(results[1].c_str()), htoi(results[2].c_str()), htoi(results[3].c_str()), htoi(results[4].c_str()), htoi(results[5].c_str()), htoi(results[6].c_str()), htoi(results[7].c_str()), htoi(results[8].c_str())); if (results.size() >= 11) { for (int i = 9; i < results.size(); i += 2) { len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%d", htoi(results.c_str()), atoi(results[i+1].c_str())); isAttr = true; } } if (isAttr) //"item:¹øÈ£:Ç÷¡±×:¼ÒÄÏ0:¼ÒÄÏ1:¼ÒÄÏ2" snprintf(buf, sizeof(buf), "|cffffc700|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); else snprintf(buf, sizeof(buf), "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); return Py_BuildValue("s", buf); } } return Py_BuildValue("s", ""); } 7.Ahora abrimos el archivo "PythonChatModule.cpp" y buscamos: Quote PyObject * playerGetItemLink(PyObject * poSelf, PyObject * poArgs) 7.1 Remplazamos la función por: Quote PyObject * playerGetItemLink(PyObject * poSelf, PyObject * poArgs) { TItemPos Cell; switch (PyTuple_Size(poArgs)) { case 1: if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) return Py_BuildException(); break; case 2: if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) return Py_BuildException(); break; default: return Py_BuildException(); } const TItemData * pPlayerItem = CPythonPlayer::Instance().GetItemData(Cell); CItemData * pItemData = NULL; char buf[1024]; if (pPlayerItem && CItemManager::Instance().GetItemDataPointer(pPlayerItem->vnum, &pItemData)) { char itemlink[256]; int len; bool isAttr = false; len = snprintf(itemlink, sizeof(itemlink), "item:%x:%x:%x:%x:%x:%x:%x:%x", //6 Piedras pPlayerItem->vnum, pPlayerItem->flags, pPlayerItem->alSockets[0], //1 Piedras pPlayerItem->alSockets[1], //2 Piedras pPlayerItem->alSockets[2], //3 Piedras pPlayerItem->alSockets[3], //4 Piedras pPlayerItem->alSockets[4], //5 Piedras pPlayerItem->alSockets[5]); //6 Piedras for (int i = 0; i < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++i) if (pPlayerItem->aAttr.bType != 0) { len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%d", pPlayerItem->aAttr.bType, pPlayerItem->aAttr.sValue); isAttr = true; } if( GetDefaultCodePage() == CP_ARABIC ) { if (isAttr) //"item:¹øÈ£:Ç÷¡±×:¼ÒÄÏ0:¼ÒÄÏ1:¼ÒÄÏ2" snprintf(buf, sizeof(buf), " |h|r[%s]|cffffc700|H%s|h", pItemData->GetName(), itemlink); else snprintf(buf, sizeof(buf), " |h|r[%s]|cfff1e6c0|H%s|h", pItemData->GetName(), itemlink); } else { if (isAttr) //"item:¹øÈ£:Ç÷¡±×:¼ÒÄÏ0:¼ÒÄÏ1:¼ÒÄÏ2" snprintf(buf, sizeof(buf), "|cffffc700|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); else snprintf(buf, sizeof(buf), "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); } } else buf[0] = '0'; return Py_BuildValue("s", buf); } 8.Compilamos binario/source game & db 9.Ahora tenemos que editar nuestro dump_proto, asi que lo abrimos y editamos el archivo "dump_proto.cpp" y buscamos: Quote enum EItemMisc { ITEM_NAME_MAX_LEN = 24, ITEM_VALUES_MAX_NUM = 6, ITEM_SMALL_DESCR_MAX_LEN = 256, ITEM_LIMIT_MAX_NUM = 2, ITEM_APPLY_MAX_NUM = 3, ITEM_SOCKET_MAX_NUM = 3, ITEM_MAX_COUNT = 200, ITEM_ATTRIBUTE_MAX_NUM = 7, ITEM_ATTRIBUTE_MAX_LEVEL = 5, ITEM_AWARD_WHY_MAX_LEN = 50, 9.1 Remplazamos por : Quote enum EItemMisc { ITEM_NAME_MAX_LEN = 24, ITEM_VALUES_MAX_NUM = 6, ITEM_SMALL_DESCR_MAX_LEN = 256, ITEM_LIMIT_MAX_NUM = 2, ITEM_APPLY_MAX_NUM = 3, ITEM_SOCKET_MAX_NUM = 6, //6 Piedras ITEM_MAX_COUNT = 200, ITEM_ATTRIBUTE_MAX_NUM = 7, ITEM_ATTRIBUTE_MAX_LEVEL = 5, ITEM_AWARD_WHY_MAX_LEN = 50, 10.Nos vamos a nuestro cliente, descompilamos el root y editamos el archivo "uiToolTip.py" y buscamos: Quote def SetHyperlinkItem(self, tokens): 10.1 Remplazamos la función por: Quote def SetHyperlinkItem(self, tokens): minTokenCount = 3 + player.METIN_SOCKET_MAX_NUM maxTokenCount = minTokenCount + 2 * player.ATTRIBUTE_SLOT_MAX_NUM if tokens and len(tokens) >= minTokenCount and len(tokens) <= maxTokenCount: head, vnum, flag = tokens[:3] itemVnum = int(vnum, 16) metinSlot = [int(metin, 16) for metin in tokens[3:9]] rests = tokens[9:] if rests: attrSlot = [] rests.reverse() while rests: key = int(rests.pop(), 16) if rests: val = int(rests.pop()) attrSlot.append((key, val)) attrSlot += [(0, 0)] * (player.ATTRIBUTE_SLOT_MAX_NUM - len(attrSlot)) else: attrSlot = [(0, 0)] * player.ATTRIBUTE_SLOT_MAX_NUM self.ClearToolTip() self.AddItemData(itemVnum, metinSlot, attrSlot) ItemToolTip.OnUpdate(self) #Nota: en caso que no podamos modificarlo por otro sistema o el motivo que sea, debemos editar esta 2 partes: Quote metinSlot = [int(metin, 16) for metin in tokens[3:5]] rests = tokens[6:] por: Quote metinSlot = [int(metin, 16) for metin in tokens[3:9]] rests = tokens[9:] #Update 1.1 11.Vamos a nuestro Source DB y abrimos el archivo ClientManager.cpp y buscamos: Quote void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg) en esta función un poco más abajo añadimos lo siguiente (junto a las demás): Quote "socket3, socket4, socket5, socket6," 11.2.Ahora buscamos otra vez: Quote void CClientManager::QUERY_ITEM_SAVE(CPeer * pkPeer, const char * c_pData) Y un poco más abajo añadimos junto a las demás lo siguiente: Quote "socket3, socket4, socket5, socket6," 11.3.Un poco más abajo veremos lo siguiente: Quote "VALUES(%u, %u, %d, %d, %u, %u, %ld, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", Pues lo remplazamos por lo siguiente (si no quieres remplazar solo añade %ld, %ld, %ld, %ld): Quote "VALUES(%u, %u, %d, %d, %u, %u, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", 11.4.Y un poco más abajo veremos: Quote p->alSockets[0], p->alSockets[1], p->alSockets[2], Para terminar añadimos: Quote p->alSockets[3], p->alSockets[4], p->alSockets[5], p->alSockets[6], 12.Vamos a nuestro source Binario y abrimos el archivo GameType.h y buscamos: Quote ITEM_SOCKET_SLOT_MAX_NUM = 3, Remplazamos por: Quote ITEM_SOCKET_SLOT_MAX_NUM = 7, 13.Una vez hayamos remplazado el nuevo Game, DB, .exe, compilado el root y compilado dump_proto, dumpeamos los locales, es decir, ponemos nuestros item_proto.txt e item_names.txt en el nuevo dump_proto y generamos los archivos para el locale, compilamos locale, hacemos reboot y a jugar. Imagen propia: Varios puntos a destacar: 1.Tienes que adaptarlo a tu Offline Shop ya que tendrás los sockets básicos Socket0 1 y 2, tendrás que añadir más en función de los que tengas. 2.No se cuantas piedras son el máximo que puedes añadir, 6 es seguro, pero 7,8,9,10 o + quizás te ocasionen bugs. 3.Si tienes otros sistemas que utilizen casillas con sockets, como Offline Shop, almacén especial, etc tendrás que adaptarlo o tendrás problemas, 4.A disfrutar y un saludo. ♥ TesT ♥ and morstamayo 2 Quote Link to comment Share on other sites More sharing options...
NazoX Posted May 1, 2022 Author Report Share Posted May 1, 2022 #Tema actualizado faltaban algunas partes que se me olvido añadir. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.