Jump to content

PACI

Miembro
  • Contador contenido

    501
  • Ingreso

  • Última visita

  • Días ganados

    58

Todo lo publicado por PACI

  1. Pero para qué estás tocando el source si ni sabes de dónde viene ni para qué sirve ese archivo? Además, eso te dice la ruta... es del client.
  2. No hay nada de eso para 40k por que existe el source.
  3. Simplemente no lo puedes hacer. Y no es solamente al cambiar un armadura, con subirte o bajarte del caballo tambien se quita.
  4. self.image = ui.ImageBox()self.image.SetParent(self)self.image.LoadImage("ruta")self.image.SetPosition(wndMgr.GetScreenWidth() - x, y)self.image.SetSize(220, 100)Supongo que seria algo así en el... uisystemoption.py si no me equivoco. No se donde exactamente, pero creo que alguien mas experto en esto te podra dar una respuesta mejor.
  5. PACI

    [Quest] Anti-exp

    Y donde está el fallo en eso? Se supone que no deberías ganar experiencia lol
  6. Tu nunca puedes sacar el AddonType desde el cliente.. O eso creo.
  7. BlackYuko's map converter
  8. Eso es la parte del cliente, pero tendrás que conectar el socket con el item de algun modo a parte de la visualización en el cliente.
  9. PACI

    Chestbox

    Porque el bucle no empieza en 1, si no en 2. Si no se sumase 2 al table.getn, el ultimo valor del item, y el ultimo valor de la cantidad, nunca serian leídos. ej:
  10. PACI

    Chestbox

    Hay varios fallos, y no es necesario hacer dos tablas cuando puedes usar una sola. Además, la función pc.give_item2, en el caso que hayan demasiados items en el inventario, los dropea con el nombre del personaje. quest cofres begin state start begin when 20030.use or 20031.use or 20032.use or 20033.use begin local vnum = item.vnum-20029 local data = { -- nivel, id, cantidad {1, 19, 1, 20, 1, 21, 1}, {10, 19, 1, 20, 1, 21, 1}, {20, 19, 1, 20, 1, 21, 1}, {30, 19, 1, 20, 1, 21, 1} } if pc.level < data[vnum][1] then syschat("Lo siento no tienes suficiente nivel requieres nivel "..data[vnum][1]) return end for i = 2, table.getn(data)+2, 2 do pc.give_item2(data[vnum][i], data[vnum][i+1]) end end endend
  11. Nombre: Jin Varrel en un lado, PACI o PACIFICADOR en otro Y quiero que uses, si es posible, esta imagen:
  12. Seems really nice, as always. Keep going
  13. Una quest que tenga el simbolo # para comentar algo, nunca puede funcionar. Yo hablo de las quests que están en este post.
  14. Mientras, cualquiera que vaya a copiar y pegar esas quests en su servidor, ninguna funcionará. A la primera le falta un end, y todas tienen #, cuando debería ser --.
  15. Hola. Hay gente que aún usa (tanto en cliente, como en servidor) cosas viejas, os traigo esta guia para que podáis "actualizar" vuestro cliente, y ya de paso vuestros cores para una versión más estable, y menos.. digamos peligrosa, aunque no es la palabra correcta. Desde hace ya mucho tiempo, tenemos disponible los binarios cuya revisión es la 34xxx o superior, aunque, desde que han salido, veo aún mucha gente de la comunidad hispana de metin2 usando los binarios viejos, o porque no saben hacerlo, o porque no quieren arriesgarse. Yo personalmente os recomiendo, ante todo, que actualicéis todo lo vuestro. Qué hay que cambiar para usar un binário >= 34k y <= 36k ? Los cambios para usar un binario entre 34k y 36k son muy simples, y no muy dificiles de hacer. Lo primero es cambiar vuestro game y db, os recomiendo la revisión 34083 y 33820 (game y db, respectivamente) para evitar errores de packets, y también para usar un game mucho mejor que del 2089M para abajo. Al cambiar la versión de la db para la 33820, las tablas item_proto y mob_proto dejan de ser utilizadas, aunque podeis usar esta librería de iMer para volver a utilizar las tablas en vez de archivos *.txt: http://www.elitepvpers.com/forum/metin2-pserver-guides-strategies/2733324-lib-db-protos-aus-der-datenbank-no-txt.html La parte del cliente es muy sencilla, solo tenéis que extraer vuestro cliente entero, y, donde el *.xml buscamos todos los type="2" y los reemplazamos por type="1". Si usais EterNexus, que es un extractor que no crea el *.xml, solo tenéis que extraer todo el cliente, y volver a compilarlo. En el uitooltip.py del root, deberéis cambiar esto: item.APPLY_DEF_GRADEitem.APPLY_ATT_GRADE Por: item.APPLY_DEF_GRADE_BONUSitem.APPLY_ATT_GRADE_BONUS Con la salida de las revisiones 40k y con la salida del source, la mayoría de la gente dejó ya de usar las versiones anteriores a esta para compilar una propria modificandolo a nuestro gusto, como yo y muchos otros, o usar el famoso bin 28k con el game 40250. Qué hay que cambiar para usar un game r40k ? Además de la db, game, y la adición de los *.txt (item_proto.txt, item_names.txt, mob_proto.txt, mob_names.txt), debereís hacer bastantes cambios a nível de cliente. Lo primero es cambiar el nombre de vuestro locale.py para localeinfo.py. En los demás archivos de root, debereis cambiar todos los import que se hagan al locale y todas las cosas que llamen ese archivo. Ejemplo: import locale -> import localeInfolocale. -> localeInfo. NO CONFUNDIR CON uiScriptLocale!! Después de esto hay que cambiar todos los archivos de la carpeta lib y la python22.dll/python27.dll (depende del tipo de binario que tengáis) Y eso es todo, por lo menos lo que yo hice para usar las cosas del source. Saludos y suerte.
  16. No es locale, sino local. Además, los comentarios en lua se hacen con -- y no con #, como en python. El símbolo # a partir de lua 5.1 funciona como la funcion table.getn, y esta, deja de existir. Y de bucles te falta el repeat. local var, i = 0, 80repeat print(var) var = var+1until var == i
  17. --[[needed functions: npc.get_vid() -> http://www.elitepvpers.com/forum/metin2-pserver-guides-strategies/2177716-release-new-game-function-npc-get_vid.html]]quest pvplevelup begin state start begin when kill begin -- 1 if not npc.is_pc() and pc.level >= 150 then -- killing mobs pc.give_exp2(-pc.get_exp()) end -- 5 local canContinue = true local mapdict = {idx1, idx2, idx3, idx4, idx5, idx6} -- levelup map indexes for _, v in ipairs(mapdict) do if pc.get_map_index() == v then canContinue = false break end end if pc.level >= 170 or canContinue == false then return end if npc.is_pc() then -- killing other players -- 4 local oppvid = pc.select(npc.get_vid()) local opplvl, oppid = 0, 0 if oppvid == 0 then return end opplvl, oppid = pc.level, pc.get_player_id() pc.select(oppvid) if opplvl < 90 or get_time() < pc.getqf("delay") then return end -- 2 local expvalue = tonumber(pc.getqf("killed_id") ~= oppid and 200000000 or 200000000/pc.getqf("killcount")+1) pc.setqf("killed_id", oppid) pc.setqf("killcount", tonumber(pc.getqf("killcount") == 2 and 0 or pc.getqf("killcount")+1)) pc.setqf("delay", get_time()+60*5) pc.give_exp2(expvalue) end end endend
  18. Hola. Como sabéis, ahora que el source es publico, ya nadie, o casi nadie, hará, ni posteará, más diffs para editar vuestros cores. Este es uno de los motivos por los cuales hago escribo esta guia, el otro es para dar a la comunidad hispana un poco más de conocimiento, aunque no sea mucho. Que se necesita para hacer diffs? Hay quién diga que necesitas saber ASM (assembly), C, y esas cosas. Aunque, yo no sé ninguno de los 2, y creaba diffs. Lo que más necesitamos es un brain.exe, como se suele decir, paciencia, y el IDA Pro y un conversor de valores decimales a hexadecimales, y viceversa. Antes de ponernos a toquetear en el IDA, debemos, antes de nada, saber una cosa. Qué es un diff? Un diff (difference file) es un archivo que contiene, de una manera simplificada, una (o varias) linea(s) que altera(n) un (o más) bytes de un archivo. La sintaxis es: offset: byte antiguo byte nuevo. La creación de un diff no es propriamente un problema, ya que el IDA, dependiendo de lo que hayamos modificado, lo crea solo. Y a través de un diff no puedes saber lo que cambia. Después de saber que és un diff, y para que sirve, tenemos que saber qué es lo que queremos cambiar, y donde se localiza, yo, para eso, usaba el Pseudocode de un game core o db core para buscar lo que queria cambiar, obviamente para esto necesitamos el brain.exe, porque tenemos que entender la sintaxis del codigo que hay por ahí. Os dejaré en adjuntos, todos los pseudocodes de todos los game core y db core que tengo Vale, ahora qué hago? Yo, para empezar, cogeré el pseudocode del game r40250 y cambiaré... por ejemplo, el nível de diferencia que se necesita para invitar a alguién en un grupo. Como empezamos? Hay que saber un poquito de inglés, porque las variables no están escritas en español. Lo que sabemos es que grupo se puede decir party en inglés. Una vez sepamos eso, empezaremos buscando party en nuestro editor de texto (yo uso Notepad++ para esto, vosotros podéis usar algun otro), lo segundo es saber, cuando sucede la acción, o sea, cuando sale el mensajito ese en el chat diciendo que la diferencia de nível es X. Sabemos también que eso pasa cuando invitamos a alguién, invitar en inglés es invite. Entonces ya sabemos que tenemos que buscar algo como PartyInvite. Cuando encontremos algo de este tipo: extern char CHARACTER__PartyInvite_CHARACTER______FUNCTION__[12]; // weak Entonces lo que hacemos es buscar esa función. Ojo, apenas buscamos por CHARACTER__PartyInvite. Y por fin, encontraremos la función CHARACTER__PartyInvite: int __fastcall CHARACTER__PartyInvite(int a1, int a2, int a3, int a4){ int v4; // eax@4 int v5; // edx@4 int v6; // ecx@4 int v7; // ebx@6 int v8; // eax@6 int v9; // eax@7 int result; // eax@8 int v11; // eax@10 int v12; // eax@15 int v13; // eax@22 int v14; // eax@23 int v15; // edx@23 int v16; // ecx@23 int v17; // edi@23 int v18; // eax@23 int v19; // edx@25 int v20; // ecx@25 int v21; // [sp+0h] [bp-48h]@3 int v22; // [sp+0h] [bp-48h]@6 int v23; // [sp+20h] [bp-28h]@23 int v24; // [sp+24h] [bp-24h]@23 _BYTE v25[5]; // [sp+2Bh] [bp-1Dh]@29 int v26; // [sp+30h] [bp-18h]@23 int v27; // [sp+34h] [bp-14h]@22 int v28; // [sp+38h] [bp-10h]@1 v28 = *(_DWORD *)_stack_chk_guard__FBSD_1_0; if ( *(_DWORD *)(a3 + 9328) && CParty__GetLeaderPID(a1, a2, *(_DWORD *)(a3 + 9328)) != *(_DWORD *)(a3 + 256) ) { v21 = (int)&unk_848D8B8;LABEL_4: v4 = locale_find(v21); CHARACTER__ChatPacket(a3, 1, (const char *)v4); } else { if ( *(_BYTE *)(a4 + 9104) & 2 ) { v8 = CHARACTER__GetName(a4); v22 = (int)&unk_848D8E8; v7 = v8;LABEL_7: v9 = locale_find(v22); CHARACTER__ChatPacket(a3, 1, (const char *)v9, v7); } else { v11 = CHARACTER__IsPartyJoinableCondition(a3, a4); if ( (unsigned int)v11 <= 0xA ) { switch ( v11 ) { default: goto LABEL_11; case 10: v21 = (int)&unk_848D868; goto LABEL_4; case 8: v21 = (int)&unk_848D4C0; goto LABEL_4; case 7: v12 = CHARACTER__GetName(a4); v22 = (int)"<ÆÄƼ> ÀÌ¹Ì %s´ÔÀº ÆÄƼ¿¡ ¼ÓÇØ ÀÖ½À´Ï´Ù."; v7 = v12; goto LABEL_7; case 6: v21 = (int)&unk_848D480; goto LABEL_4; case 5: v21 = (int)&unk_848D440; goto LABEL_4; case 4: v21 = (int)&unk_848D404; goto LABEL_4; case 3: v21 = (int)&unk_848D3D0; goto LABEL_4; case 2: v21 = (int)&unk_848D39C; goto LABEL_4; case 1: v21 = (int)&unk_848D368; goto LABEL_4; case 0: v27 = *(_DWORD *)(a4 + 256); v13 = std___Rb_tree_unsigned_int_std__pair_unsigned_int__const_boost__intrusive_ptr_event___std___Select1st_std__pair_unsigned_int__const_boost__intrusive_ptr_event____std__less_unsigned_int__std__allocator_std__pair_unsigned_int__const_boost__intrusive_ptr_event______find( a3 + 9340, (int)&v27); v5 = a3 + 9344; if ( a3 + 9344 == v13 ) { v14 = AllocEventInfo_TPartyJoinEventInfo_(); *(_DWORD *)(v14 + 4) = *(_DWORD *)(a4 + 256); *(_DWORD *)(v14 + 8) = *(_DWORD *)(a3 + 256); event_create_ex(&v26, (int)party_invite_event, v14, 10 * passes_per_sec); v17 = v26; v18 = *(_DWORD *)(a4 + 256); v24 = v26; v23 = v18; if ( v26 ) intrusive_ptr_add_ref(v16, v15, v26); std___Rb_tree_unsigned_int_std__pair_unsigned_int__const_boost__intrusive_ptr_event___std___Select1st_std__pair_unsigned_int__const_boost__intrusive_ptr_event____std__less_unsigned_int__std__allocator_std__pair_unsigned_int__const_boost__intrusive_ptr_event_______M_insert_unique( a3 + 9340, (int)&v23); if ( v24 ) intrusive_ptr_release(v20, v19, v24); if ( v17 ) intrusive_ptr_release(v20, v19, v17); v25[0] = 77; *(_DWORD *)&v25[1] = *(_DWORD *)(a3 + 260); DESC__Packet(*(_DWORD *)(a4 + 44), (int)v25, 5); } break; } } else {LABEL_11: sys_err((int)"PartyInvite", 4558, "Do not process party join error(%d)", v11); } } } result = *(_DWORD *)_stack_chk_guard__FBSD_1_0 ^ v28; if ( *(_DWORD *)_stack_chk_guard__FBSD_1_0 != v28 ) __stack_chk_fail(v6, v5); return result;} Ahora a partir de aquí, hay que saber leer. Vayamos por partes: LABEL_4: v4 = locale_find(v21); CHARACTER__ChatPacket(a3, 1, (const char *)v4); LABEL_7: v9 = locale_find(v22); CHARACTER__ChatPacket(a3, 1, (const char *)v9, v7); LABEL_4 y LABEL_7 tienen un locale_find y un ChatPacket, lo que significa que buscará en el locale_string.txt un texto que estará dentro del locale_find y luego lo mostrará en el Chat. Pasemos directamente al switch: v11 = CHARACTER__IsPartyJoinableCondition(a3, a4); if ( (unsigned int)v11 <= 0xA ) { switch ( v11 ) { default: goto LABEL_11; case 10: v21 = (int)&unk_848D868; goto LABEL_4; case 8: v21 = (int)&unk_848D4C0; goto LABEL_4; case 7: v12 = CHARACTER__GetName(a4); v22 = (int)"<ÆÄƼ> ÀÌ¹Ì %s´ÔÀº ÆÄƼ¿¡ ¼ÓÇØ ÀÖ½À´Ï´Ù."; v7 = v12; goto LABEL_7; case 6: v21 = (int)&unk_848D480; goto LABEL_4; case 5: v21 = (int)&unk_848D440; goto LABEL_4; case 4: v21 = (int)&unk_848D404; goto LABEL_4; case 3: v21 = (int)&unk_848D3D0; goto LABEL_4; case 2: v21 = (int)&unk_848D39C; goto LABEL_4; case 1: v21 = (int)&unk_848D368; goto LABEL_4; case 0: v27 = *(_DWORD *)(a4 + 256); v13 = std___Rb_tree_unsigned_int_std__pair_unsigned_int__const_boost__intrusive_ptr_event___std___Select1st_std__pair_unsigned_int__const_boost__intrusive_ptr_event____std__less_unsigned_int__std__allocator_std__pair_unsigned_int__const_boost__intrusive_ptr_event______find( a3 + 9340, (int)&v27); v5 = a3 + 9344; if ( a3 + 9344 == v13 ) { v14 = AllocEventInfo_TPartyJoinEventInfo_(); *(_DWORD *)(v14 + 4) = *(_DWORD *)(a4 + 256); *(_DWORD *)(v14 + 8) = *(_DWORD *)(a3 + 256); event_create_ex(&v26, (int)party_invite_event, v14, 10 * passes_per_sec); v17 = v26; v18 = *(_DWORD *)(a4 + 256); v24 = v26; v23 = v18; if ( v26 ) intrusive_ptr_add_ref(v16, v15, v26); std___Rb_tree_unsigned_int_std__pair_unsigned_int__const_boost__intrusive_ptr_event___std___Select1st_std__pair_unsigned_int__const_boost__intrusive_ptr_event____std__less_unsigned_int__std__allocator_std__pair_unsigned_int__const_boost__intrusive_ptr_event_______M_insert_unique( a3 + 9340, (int)&v23); if ( v24 ) intrusive_ptr_release(v20, v19, v24); if ( v17 ) intrusive_ptr_release(v20, v19, v17); v25[0] = 77; *(_DWORD *)&v25[1] = *(_DWORD *)(a3 + 260); DESC__Packet(*(_DWORD *)(a4 + 44), (int)v25, 5); } break; } } else {LABEL_11: sys_err((int)"PartyInvite", 4558, "Do not process party join error(%d)", v11); } Como veremos, la variable v11 está obteniendo el valor de una otra función, llamada CHARACTER__IsPartyJoinableCondition. Entonces, lo que el servidor hará es testear ese valor desde la función switch. switch ( v11 ) { default: goto LABEL_11; Si esa variable es false dependiendo de los valores encontrados en los case, entonces irá hasta el LABEL_11, que es un error en syserr: LABEL_11: sys_err((int)"PartyInvite", 4558, "Do not process party join error(%d)", v11); Si esa condición es verdadera, hará una serie de cosas. Entonces ya sabemos que, lo que sale en el chat dependerá: - Del valor de la variable v11, o sea, el valor que la función CHARACTER__IsPartyJoinableCondition obtiene. Ahora que sabemos esto, vayamos directos a esa función. int __cdecl CHARACTER__IsPartyJoinableCondition(int a1, int a2){ int v2; // edx@1 int result; // eax@2 v2 = a2; if ( *(_BYTE *)(a1 + 9797) == *(_BYTE *)(a2 + 9797) ) { if ( *(_DWORD *)_stack_chk_guard__FBSD_1_0 == *(_DWORD *)_stack_chk_guard__FBSD_1_0 ) return CHARACTER__IsPartyJoinableMutableCondition(a1, a2, a1, a2);LABEL_6: __stack_chk_fail(a1, v2); } v2 = *(_DWORD *)_stack_chk_guard__FBSD_1_0 ^ *(_DWORD *)_stack_chk_guard__FBSD_1_0; result = 10; if ( *(_DWORD *)_stack_chk_guard__FBSD_1_0 != *(_DWORD *)_stack_chk_guard__FBSD_1_0 ) goto LABEL_6; return result;} De aqui no podemos sacar grandes conclusiones, pero, sabemos una cosa: if ( *(_DWORD *)_stack_chk_guard__FBSD_1_0 == *(_DWORD *)_stack_chk_guard__FBSD_1_0 ) return CHARACTER__IsPartyJoinableMutableCondition(a1, a2, a1, a2); Esta funcion hará return al valor de una otra función. Debemos entonces, movermos hasta esa función, CHARACTER__IsPartyJoinableMutableCondition. int __fastcall CHARACTER__IsPartyJoinableMutableCondition(int a1, int a2, int a3, int a4){ int v4; // edx@1 char v5; // al@4 __int64 v6; // qax@5 int result; // eax@7 int v8; // eax@10 int v9; // [sp+1Ch] [bp-Ch]@1 v4 = 1; v9 = *(_DWORD *)_stack_chk_guard__FBSD_1_0; if ( *(_BYTE *)(singleton_CPartyManager___ms_singleton + 76) ) { LOBYTE(v4) = 2; if ( !*(_DWORD *)(a3 + 9364) ) { LOBYTE(v4) = 3; if ( !*(_BYTE *)(a4 + 4) ) { v5 = LC_IsCanada(a1); a1 = 15; if ( !v5 ) a1 = (unsigned __int8)LC_IsBrazil(15) < 1u ? 30 : 10; v6 = *(_BYTE *)(a3 + 1298) - *(_BYTE *)(a4 + 1298); LODWORD(v6) = (HIDWORD(v6) ^ v6) - HIDWORD(v6); v4 = 4; if ( a1 >= (_DWORD)v6 ) { LOBYTE(v4) = 7; if ( !*(_DWORD *)(a4 + 9328) ) { if ( !*(_DWORD *)(a3 + 9328) || (v8 = CParty__GetMemberCount(a1, v4, *(_DWORD *)(a3 + 9328)), v4 = 8, v8 != 8) ) v4 = 0; } } } } } result = v4; if ( *(_DWORD *)_stack_chk_guard__FBSD_1_0 != v9 ) __stack_chk_fail(a1, *(_DWORD *)_stack_chk_guard__FBSD_1_0 ^ v9); return result;} La primera cosa en lo que nos fijaremos es en esto: v5 = LC_IsCanada(a1); a1 = 15; if ( !v5 ) a1 = (unsigned __int8)LC_IsBrazil(15) < 1u ? 30 : 10; La variable v5 será igual a un boolean (true o false), a1 es un integer (un valor entre 0 a 2 millones). Lo que la función hace, es verificar si la variable v5 es false, si así es, el valor de la variable a1 cambia, dependiendo del locale, ya que si este es un locale/brazil el a1 será 10. a1 = (unsigned __int8)LC_IsBrazil(15) < 1u ? 30 : 10; Esto es lo que se llama, un short if-statement: a1 = boolean ? valor si es true : valor si es false; Como el nivel de diferencia en los servidores de europa es 15, podemos concluir que la variable a1 define el nivel de diferencia y es el valor que queremos cambiar. Toqueteando en el IDA Después de saber que valor tenemos que cambiar, y donde está, abrimos el IDA: Y le damos al primer botón (New - Disassemble a new file), seleccionamos nuestro archivo, en mi caso el game r40250, y nos aparecerá algo de este tipo: Nosotros, sin tocar en nada, le damos al OK. Y esperamos hasta que cargue las funciones. Cuando nos salga algo así: Significa que las funciones ya están cargadas. Ahora le hacemos click en la ventana Function name y escribimos: CHARACTER::IsPartyJoinableMutableCondition y le damos un doble click. Nosotros simplemente bajamos hasta aqui: Si le damos al botón de tabulación, nos llevará al pseudocode de esa función y, además, nos dejará en la localización actual, por ejemplo: call _Z11LC_IsCanadav ; LC_IsCanada(void)mov ecx, 0Fhtest al, aljz short loc_806E8B0 Si hacemos click en el mov y hacemos un jump to pseudocode nos llevará hasta: a1 = 15; Yo, como no sé cambiar los valores de los short if-statements, haré NOP (No Operation, que simplemente hace que en esa parte no haga nada). Entonces, nos moveremos al Hex View y podremos ver que la parte que está seleccionada, es la parte que hemos seleccionado en el IDA View. Nos vamos a la ventana donde está el LC_IsCanada: .text:0806E83A jnz short loc_806E878.text:0806E83C call _Z11LC_IsCanadav ; LC_IsCanada(void).text:0806E841 mov ecx, 0Fh.text:0806E846 test al, al.text:0806E848 jz short loc_806E8B0 El short jump if not zero (jnz) si le damos click y vamos al pseudo, veremos que está demasiado arriba del if-statement. El call al LC sabemos que es una variable El mov es la variable que queremos cambiar. El test es el if-statement. El jump if zero (jz) basicamente es lo que va después de la condición. Entonces lo que tenemos que hacer, es NOP al jz y al test. Como? Facil, seleccionamos lo que queremos cambiar: Nos vamos al Hex View le damos al F2, y cambiamos los 2 valores que salen seleccionados por 90. Ya que el No Operation (NOP) equivale a 90. Volvemos a darle al F2 para guardar los cambios. Y luego, hacemos lo mismo con el jz. Que hemos echo entonces? Basicamente, lo que hicimos hasta ahora, es dejar el nivel de diferencia entre jugadores para que se inviten sea de 15, ya que el if define todo lo demás, dependiendo del locale. Si queremos cambiar el 15 por otro, facil. Vamos hasta: mov ecx, 0Fh Luego al Hex View, entonces abrimos el conversor de valores decimales a hexadecimales, y viceversa, ponemos 15 donde el 1, y le damos click a to hexadecimal, que nos saldra un f, o sea 15 en hexadecimal equivale a 0F. Buscaremos eso en el Hex View, le damos al F2. Volvemos al conversor, y convertimos el valor que queremos poner a cambio de 15. Yo por ejemplo, pondré 5 que es 05. Le daré al F2 otra vez para guardar los cambios. Entonces si vuelvo al pseudo me saldrá: v5 = LC_IsCanada(a1, v4); a1 = 5; En vez de: v5 = LC_IsCanada(a1, v4); a1 = 15; Eso es porque hemos cambiado el 15 por 5 en el Hex View. Por fin, como creamos la diff después de cambiar lo que queramos? Y mi diff me saldrá así: This difference file has been created by IDA Progame_r4025000026842: 0F 05 // Esto es el cambio de la variable a1, de 15 a 5// Estos NOP es de la condición que hemos "eliminado"00026846: 84 9000026847: C0 9000026848: 74 9000026849: 66 90 Y por último os dejo aqui los pseudocode que tengo: https://mega.co.nz/#!ZMYjgAwa!NzEZ-jMtKeqWGMvqjE4fRQHwhJYoZmR5ptOGZLsaCag
  19. Hola.Mientras toqueteaba la source me fijé en la función switch de C++, entonces decidi hacerla en lua porque es bastante útil.La función no se usa exactamente como en C++, aunque lo que hace sea parecido.Vale, todos hemos hecho quests y/o funciones super grandes, con bastantes if desnecesarios. Lo que esta funcione hace es:Verificar si var es igual a algun valor de la tabla values. Si la condición es true, hará return al valor correspondiente de la tabla output.Si es false, hará return default. En C++: int var = 1; // Declaramos la variableswitch(var) // Empezamos la verificación de la variable{ case 2: // Si es 2, hará return a "var es 2" std::cout << "var es 2" << endl; break; case 3: // Si es 2, hará return a "var es 2" std::cout << "var es 3" << endl; break; default: // Si el valor de la variable no corresponde a ninguno de los antecedentes, hará return a "var es 1" std::cout << "var es 1" << endl; break;}-> var es 1 Ahora en lua: print(switch(2, {3, 4, 5}, {"es 3","es 4","es 5"}, "no es ninguno de los anteriores, si no 2"))-> no es ninguno de los anteriores, si no 2 Pues entonces, ahí os dejo la función, para quién quiera usarla, y ya de paso, mirais como hacerla para que podrais hacer más cosas. function switch(var, values, output, default) if type(values) ~= 'table' or type(output) ~= 'table' then return false end for _, __ in ipairs(output) do default = var == values[_] and __ or default break end return defaultend Más tarde, si tengo tiempo, haré una guia de como crear diffs. Saludos.
  20. Quita el mysql_query de mijago y pon los que te he dado en el source
  21. Al efectuar un registro, sea donde sea, obligatoriamente, lo sepas o no, estás de acuerdo con las reglas y sanciones del foro.
×
×
  • Crear nuevo...