Crear Script LUA | FILES EMUPLAYERS MUEMULATORS

Iniciado por Victhorinox, Abr 27, 2026, 04:23 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Abr 27, 2026, 04:23 PM Ultima modificación: May 01, 2026, 04:06 PM por Victhorinox



🔥 LA BIBLIA DEL PROGRAMADOR | LUA EMUPLAYERS MUEMULATORS 🔥
Si tienes retraso mental y no puedes entender esto, apaga la PC, borra el emulador y búscate un trabajo honesto.



1. ¿QUÉ ES ESTA PORQUERÍA Y CÓMO FUNCIONA?
Este sistema utiliza el motor LUA 5.2 inyectado directo en el cliente. Su comunicación es BINARIA PURA. Olvídate del JSON lento y de los textos basura. Aquí hablamos directamente con la memoria del servidor mediante bytes, lo que lo hace indetectable, ultra rápido y libre de lag.



2. EL DICCIONARIO COMPLETO (LA BIBLIA)
Para programar aquí NO USAMOS NÚMEROS al azar porque se olvidan. Usamos los NOMBRES EXACTOS que están en estas listas. Si escribes mal una mayúscula, el motor crasheará. Copia y pega los nombres tal cual están aquí.

A. RED, PAQUETES Y ERRORES
Estas son las acciones que viajan entre tu Cliente y el GameServer.
Código (lua) [Seleccionar]
NetHeader = {
  C2S_ID = 243, C2S_SUB = 254, S2C_ID = 122, S2C_SUB = 254
}

NetAction = {
  PING_TEST = 0, SYNC_DATA = 1, REQUEST_INFO = 2, CHECK_ANTICHEAT = 3,
  BUY_VIP = 16, BUY_WCOINS = 17, EXCHANGE_COINS = 18, OPEN_JEWEL_BANK = 19,
  DEPOSIT_JEWEL = 20, WITHDRAW_JEWEL = 21, BUY_CUSTOM_ITEM = 22, SELL_CUSTOM_ITEM = 23,
  OPEN_OFFSTORE = 24, CLAIM_REWARD_CODE = 25, RESET_CHAR = 48, GRAND_RESET = 49,
  ADD_STAT_STR = 50, ADD_STAT_AGI = 51, ADD_STAT_VIT = 52, ADD_STAT_ENE = 53,
  ADD_STAT_CMD = 54, CLEAR_PK = 55, CHANGE_CLASS = 56, CHANGE_NAME = 57,
  BUY_MASTER_LEVEL = 58, REPAIR_ALL = 59, WARP_CUSTOM = 80, WARP_BOSS = 81,
  WARP_VIP = 82, JOIN_EVENT_CUSTOM = 83, CLAIM_DAILY_REWARD = 84, CLAIM_BATTLE_PASS = 85,
  REGISTER_CS = 86, LUCKY_WHEEL_SPIN = 112, LUCKY_WHEEL_CLAIM = 113, OPEN_BOX_GACHA = 114,
  PLAY_LOTTERY = 115, UI_BUTTON_CLICK = 128, UI_SLIDER_MOVE = 129, UI_SCROLL_MOVE = 130,
  UI_CHECKBOX_TOGGLE = 131, UI_TEXTBOX_SUBMIT = 132, UI_CLOSE_WINDOW = 133,
  PARTY_AUTO_ACCEPT = 144, SEARCH_PARTY = 145, GUILD_BUFF_ACTIVATE = 146,
  GUILD_WAR_CUSTOM = 147, SYNC_BOSS_HP = 160, SYNC_MOB_STATS = 161, SYNC_PLAYER_BUFF = 162,
  SYNC_PET_STATS = 163, SYNC_CURRENCY = 164, SYNC_RANKING_DATA = 165, PET_UPGRADE = 176,
  PET_EVOLVE = 177, PET_HEAL = 178, TOGGLE_ANTILAG = 179, CHANGE_CUSTOM_FOG = 180,
  PLAY_SCREEN_EFFECT = 192, PLAY_SOUND_EFFECT = 193, SPAWN_PARTICLE = 194,
  SET_ENTITY_GLOW = 195, DRAW_CUSTOM_SPRITE = 196, ADMIN_BAN_HWID = 208,
  ADMIN_BAN_CHAR = 209, ADMIN_RELOAD_LUA = 210, ADMIN_SPAWN_BOSS = 211,
  RESPONSE_SUCCESS = 224, RESPONSE_ERROR = 225, OPEN_CUSTOM_WINDOW = 226
}

NetError = {
  NONE = 0, UNKNOWN = 1, INVENTORY_FULL = 2, INSUFFICIENT_FUNDS = 3,
  LEVEL_TOO_LOW = 4, LEVEL_TOO_HIGH = 5, ITEM_NOT_FOUND = 6, MAX_RESETS_REACHED = 7,
  VIP_REQUIRED = 8, PK_NOT_ALLOWED = 9, COOLDOWN_ACTIVE = 10, OUT_OF_BOUNDS = 11
}

B. ENTIDADES, CLASES Y ESTADOS
Define razas, permisos, vida y si el tipo está online o muerto.
Código (lua) [Seleccionar]
ObjectAuthority = { TYPE_USER = 1, TYPE_GAME_MASTER = 8, TYPE_ADMINISTRATOR = 32 }
GameMasterLevel = { TYPE_MODERATOR = 5, TYPE_GAME_MASTER = 8, TYPE_ADMINISTRATOR = 32 }
ObjectConnected = { OBJECT_OFFLINE = 0, OBJECT_CONNECTED = 1, OBJECT_LOGGED = 2, OBJECT_ONLINE = 3 }
ObjectLive = { OBJECT_DEAD = 0, OBJECT_LIVE = 1 }

ObjectGuildStatus = {
  GUILD_STATUS_NONE = -1, GUILD_STATUS_MEMBER = 0, GUILD_STATUS_BATTLE_MASTER = 32,
  GUILD_STATUS_OFFICE_MASTER = 64, GUILD_STATUS_MASTER = 128
}

ObjectClass = {
  CLASS_DW = 0, CLASS_SM = 16, CLASS_GM = 24, CLASS_DK = 1, CLASS_BK = 17,
  CLASS_BM = 18, CLASS_FE = 2, CLASS_ME = 33, CLASS_HE = 34, CLASS_MG = 3,
  CLASS_DM = 49, CLASS_DL = 4, CLASS_LE = 65, CLASS_SU = 5, CLASS_BS = 81,
  CLASS_DIM = 82, CLASS_RF = 6, CLASS_FM = 97
}

ObjectType = {
  OBJECT_NONE = 0, OBJECT_USER = 1, OBJECT_MONSTER = 2,
  OBJECT_NPC = 3, OBJECT_ITEM = 5, OBJECT_BOTS = 6
}

C. COMBATE, PK Y ANIMACIONES
Define quién te mató, tu nivel de asesino, efectos visuales y animaciones del personaje.
Código (lua) [Seleccionar]
KillerType = { TYPE_MONSTER = 0, TYPE_USER = 1, TYPE_GUILD_WAR = 2, TYPE_DUEL = 3 }

ObjectPKLevel = {
  PKLEVEL_HERO_3 = 0, PKLEVEL_HERO_2 = 1, PKLEVEL_HERO_1 = 2, PKLEVEL_COMMONER = 3,
  PKLEVEL_MURDERER_1 = 4, PKLEVEL_MURDERER_2 = 5, PKLEVEL_MURDERER_3 = 6
}

ObjectEffect = {
  EFFECT_GREATER_DAMAGE = 1, EFFECT_GREATER_DEFENSE = 2, EFFECT_ELF_BUFFER = 3,
  EFFECT_MANA_SHIELD = 4, EFFECT_GREATER_CRITICAL_DAMAGE = 5, EFFECT_INFINITY_ARROW = 6,
  EFFECT_BP_RECOVERY = 7, EFFECT_GREATER_LIFE = 8, EFFECT_GREATER_MANA = 9,
  EFFECT_BLESS_POTION = 10, EFFECT_SOUL_POTION = 11, EFFECT_DISABLE_MAGIC = 12,
  EFFECT_INVISIBILITY = 18, EFFECT_GAME_MASTER = 28, EFFECT_POISON = 55,
  EFFECT_ICE = 56, EFFECT_ICE_ARROW = 57, EFFECT_FIRE_SLASH = 58,
  EFFECT_PHYSI_DAMAGE_IMMUNITY = 59, EFFECT_MAGIC_DAMAGE_IMMUNITY = 60,
  EFFECT_STERN = 61, EFFECT_MAGIC_DEFENSE = 62, EFFECT_MONSTER_PHYSI_DAMAGE_IMMUNITY = 63,
  EFFECT_MONSTER_MAGIC_DAMAGE_IMMUNITY = 64, EFFECT_DAMAGE_REFLECT = 71,
  EFFECT_SLEEP = 72, EFFECT_BLIND = 73
}

ActionType = {
  ACTION_ATTACK1 = 120, ACTION_ATTACK2 = 121, ACTION_STAND1 = 122, ACTION_STAND2 = 123,
  ACTION_MOVE1 = 124, ACTION_MOVE2 = 125, ACTION_DAMAGE1 = 126, ACTION_DIE1 = 127,
  ACTION_SIT1 = 128, ACTION_POSE1 = 129, ACTION_HEALING1 = 130, ACTION_GREETING1 = 131,
  ACTION_GOODBYE1 = 132, ACTION_CLAP1 = 133, ACTION_GESTURE1 = 134, ACTION_DIRECTION1 = 135,
  ACTION_UNKNOWN1 = 136, ACTION_CRY1 = 137, ACTION_CHEER1 = 138, ACTION_AWKWARD1 = 139,
  ACTION_SEE1 = 140, ACTION_WIN1 = 141, ACTION_SMILE1 = 142, ACTION_SLEEP1 = 143,
  ACTION_COLD1 = 144, ACTION_AGAIN1 = 145, ACTION_RESPECT1 = 146, ACTION_SALUTE1 = 147,
  ACTION_RUSH1 = 148, ACTION_SCISSORS = 149, ACTION_ROCK = 150, ACTION_PAPER = 151,
  ACTION_HUSTLE = 152, ACTION_PROVOCATION = 153, ACTION_LOOK_AROUND = 154,
  ACTION_CHEERS = 155, ACTION_HANDCLAP = 156, ACTION_POINTDANCE = 157
}

D. MAPAS, ECONOMÍA Y MENSAJES
Identificadores de mapas, tipos de joyas, monedas e interfaces del juego.
Código (lua) [Seleccionar]
ObjectMap = {
  MAP_LORENCIA = 0, MAP_DUNGEON = 1, MAP_DEVIAS = 2, MAP_NORIA = 3,
  MAP_LOST_TOWER = 4, MAP_ARENA = 6, MAP_ATLANS = 7, MAP_TARKAN = 8,
  MAP_DEVIL_SQUARE1 = 9, MAP_ICARUS = 10, MAP_BLOOD_CASTLE1 = 11, MAP_CHAOS_CASTLE1 = 18,
  MAP_KALIMA1 = 24, MAP_CASTLE_SIEGE = 30, MAP_LAND_OF_TRIALS = 31, MAP_AIDA = 33,
  MAP_CRYWOLF = 34, MAP_KANTURU1 = 37, MAP_KANTURU2 = 38, MAP_KANTURU3 = 39,
  MAP_SILENT = 40, MAP_BARRACKS = 41, MAP_REFUGE = 42, MAP_ILLUSION_TEMPLE1 = 45,
  MAP_ELBELAND = 51, MAP_SWAMP_OF_CALMNESS = 56, MAP_RAKLION1 = 57, MAP_VULCANUS = 63,
  MAP_DUEL_ARENA = 64, MAP_LOREN_MARKET = 79, MAP_KARUTAN1 = 80, MAP_ACHERON1 = 91,
  MAP_NARS = 110, MAP_FEREA = 112, MAP_NIXIES_LAKE = 113, MAP_DEEP_DUNGEON1 = 116,
  MAP_SWAMP_OF_DARKNESS = 122, MAP_KUBERA_MINE1 = 123, MAP_ATLANS_ABYSS1 = 128,
  MAP_SCORCHED_CANYON = 131
}

MapTerrainAttribute = { TERRAIN_ATTRIBUTE_SAFE_ZONE = 1, TERRAIN_ATTRIBUTE_STAND = 2 }
ScreenState = { LOGIN = 2, CHARACTER_SELECT = 4, GAME_PLAY = 5 }

CurrencyType = {
  ZEN = 0, WCOIN_C = 1, WCOIN_P = 2, GOBLIN_POINT = 3,
  RUUD = 4, CUSTOM_COIN_1 = 5, CUSTOM_COIN_2 = 6, CUSTOM_COIN_3 = 7
}

JewelType = {
  BLESS = 1, SOUL = 2, LIFE = 3, CHAOS = 4, CREATION = 5,
  GUARDIAN = 6, HARMONY = 7, HREFIN = 8, LREFIN = 9, GEMSTONE = 10, ALL = 99
}

InterfaceType = {
  NONE = 0, TRADE = 1, PARTY = 2, SHOP = 3, GUILD = 4, GUILD_CREATE = 5, WAREHOUSE = 6,
  CHAOS_BOX = 7, PERSONAL_SHOP = 8, QUEST = 10, TRANSFER = 11, COMMON = 12, TRAINER = 13,
  CS_WEAPON_OFF = 15, CS_WEAPON_DEF = 16, QUEST_WORLD = 17, CASH_SHOP = 18, MINING = 19
}

MessageType = { TYPE_POPUP = 0, TYPE_CHAT = 1, TYPE_NOTIFICATION = 2 }

MessageColor = {
  COLOR_NONE = 0, COLOR_WHITE_CHAT = 1, COLOR_RED_ERROR = 2, COLOR_BLUE_SYSTEM = 3,
  COLOR_RED_PK = 4, COLOR_BACKGROUND_BLUE_PARTY = 5, COLOR_BACKGROUND_GREEN_GUILD = 6,
  COLOR_BACKGROUND_GREEN_ALLIANCE = 7, COLOR_GOLD_GAME_MASTER = 8, COLOR_BACKGROUND_WHITE_GENS = 9
}

E. INTERFAZ Y CREACIÓN DE VENTANAS (UI)
Para dibujar tus paneles, botones y manejar eventos del mouse.
Código (lua) [Seleccionar]
ALIGN_LEFT = 0
ALIGN_CENTER = 1
ALIGN_RIGHT = 2

UIComponent = {
  WINDOW = 1, BUTTON = 2, CHECKBOX = 3, SLIDER = 4,
  SCROLLBAR = 5, TEXTBOX = 6, IMAGE_2D = 7, MODEL_3D = 8, PARTICLE = 9
}

UIEvent = {
  HOVER_IN = 1, HOVER_OUT = 2, MOUSE_DOWN = 3, MOUSE_UP = 4, VALUE_CHANGE = 5
}

-- Funciones Nativas Rápidas
function GET_ITEM(g, i) return g * 512 + i end
function CONVERT_RGBA(r, g, b, a) return r * 16777216 + g * 65536 + b * 256 + a end



3. ¿CÓMO USAR TODA ESTA BASURA? (EJEMPLO PARA IMBÉCILES)

Todo script que vas a armar tiene DOS PARTES OBLIGATORIAS:
1. Leer un evento en el Cliente (Presionar tecla, clic en botón).
2. Procesar la respuesta que te devuelva el Servidor.

EL CÓDIGO MAESTRO DE EJEMPLO (CÓPIALO Y MODIFÍCALO):
Este ejemplo hace que, si estás en Lorencia y presionas la tecla F10, el juego envíe una petición binaria de "Comprar VIP".

Código (lua) [Seleccionar]
-- PASO 1: CAPTURAMOS LA TECLA F10
InterfaceCore.RegisterWindow("SistemaVIP", nil, nil, function(key)
   
    -- Validamos si la tecla es F10 (Usando el diccionario Keys)
    if key == Keys.F10 then
       
        -- Empaquetamos y disparamos al GameServer
        -- Usamos el diccionario NetAction para decirle qué queremos hacer
        local builder = PacketBuilder.New(NetAction.BUY_VIP)
        builder:WriteByte(1) -- Le mandamos un numero (Ej: 1 mes de VIP)
        builder:Send()      -- ¡FUEGO!
       
        Console(2, "Solicitud VIP enviada al servidor.")
        return true -- Bloqueamos la tecla para que MU no haga nada
    end
    return false
end)

-- PASO 2: ESCUCHAMOS LA RESPUESTA DEL SERVER
ProtocolFunctions.ClientProtocol(function(ActionID, PacketArray)
   
    -- Si el servidor nos responde el ActionID de BUY_VIP...
    if ActionID == NetAction.BUY_VIP then
       
        -- Abrimos el paquete
        local reader = PacketReader.New(PacketArray)
        local resultado = reader:ReadByte()
       
        -- Leemos la respuesta. Si el servidor mandó "0" (Fallo) o "1" (Exito)
        if resultado == 1 then
            ImUI.ShowMessage("VIP System", "¡Felicidades, eres VIP!")
        else
            ImUI.ShowMessage("VIP System", "ERROR: No tienes los WCoins necesarios.")
        end
       
        return true -- Paquete procesado con éxito
    end
    return false
end)



4. REGLAS DE ORO DEL DESARROLLADOR

  • MAYÚSCULAS Y MINÚSCULAS: LUA no perdona. Si escribes
    NetAction.ping_test en lugar de
    NetAction.PING_TEST, tu script va a explotar y no funcionará.
  • BACKUPS ANTES DE ENCRIPTAR: Antes de usar el encriptador `.bat` (Bytecode) en tus archivos `.lua`, GUARDA UNA MALDITA COPIA EN TEXTO PLANO. El compilador sobreescribe los archivos, y si pierdes el original, pierdes tu código para siempre.
  • NO ROMPAS LOS NÚCLEOS: Nunca toques ni modifiques archivos que ya funcionan (como ScriptCore.lua o ProtocolCore.lua). Tu único trabajo es crear scripts nuevos usando los diccionarios de arriba y adaptar a medida que el emulador avanza.


🎨 MÓDULO 2: INTERFACES GRÁFICAS (UI) Y DISEÑO VISUAL 🎨
Porque nadie quiere jugar en un servidor con ventanas grises que parecen de Windows 95. Aprende a diseñar como un profesional.



1. LA REGLA DE ORO DE LAS IMÁGENES
Antes de poder usar un fondo `.tga`, `.ozt` o un botón personalizado en tu script, TIENES QUE CARGARLO EN LA MEMORIA DEL JUEGO.
Para eso existe el archivo
LoadImages.lua.

Ejemplo de cómo cargar tu imagen:
Abre tu LoadImages.lua y asignale un número (Index) a tu imagen. Trata de usar números arriba de 40000 para no chocar con las imágenes originales del MU.

Código (lua) [Seleccionar]
function LoadImages()
  -- LoadBitmap("Ruta_de_tu_imagen", ID_Inventado_Por_Ti)
  LoadBitmap("Custom\\ScriptImages\\FondoShop.tga", 40000)
  LoadBitmap("Custom\\ScriptImages\\BotonAceptar.tga", 40001)
  LoadBitmap("Custom\\ScriptImages\\BotonCerrar.tga", 40002)
end



2. EJEMPLO 1: LA INTERFAZ PROFESIONAL (IMÁGENES PROPIAS)
Este es el método que usan los servidores Top. Crean una ventana y en lugar de colores sólidos, usan las imágenes `.tga` que cargaron previamente. Usaremos las constantes
UIComponent y
UIEvent de nuestro diccionario.

Código (lua) [Seleccionar]
-- Registramos la ventana en el motor
InterfaceCore.RegisterWindow("CustomShop", function()
   
    -- 1. CREAMOS LA VENTANA BASE (Invisible por ahora)
    local win = ImUI.Create(UIComponent.WINDOW, "ShopWindow", 100, 50, 400, 300)
   
    -- 2. DIBUJAMOS NUESTRO FONDO .TGA (ID 40000)
    local fondo = win:AddComponent(UIComponent.IMAGE_2D, "Fondo", 0, 0, 400, 300)
    fondo:SetTexture(40000) -- Aquí llamamos a la imagen que cargamos en LoadImages.lua
   
    -- 3. AGREGAMOS UN BOTÓN CON IMAGEN PROPIA (ID 40001)
    local btnComprar = win:AddComponent(UIComponent.BUTTON, "BtnBuy", 150, 200, 100, 35)
    btnComprar:SetTexture(40001)
    btnComprar:SetText("COMPRAR VIP", ALIGN_CENTER)
   
    -- 4. LE DAMOS VIDA AL BOTÓN (Evento MOUSE_DOWN)
    btnComprar:AddEventListener(UIEvent.MOUSE_DOWN, function()
        Console(2, "¡Hiciste clic en el botón personalizado!")
       
        -- Aquí disparamos el paquete al servidor
        local p = PacketBuilder.New(NetAction.BUY_VIP)
        p:Send()
    end)
   
end, nil, nil)



3. EJEMPLO 2: ESTILO MINIMALISTA (FONDOS SEMI-TRANSPARENTES)
A veces no quieres hacer imágenes en Photoshop. Quieres un panel elegante, oscuro y semi-transparente que deje ver el juego de fondo. Para esto usamos la función mágica
CONVERT_RGBA(R, G, B, Alpha).
El "Alpha" va de 0 (Invisible) a 255 (Sólido).

Código (lua) [Seleccionar]
InterfaceCore.RegisterWindow("PanelOpciones", function()
   
    local win = ImUI.Create(UIComponent.WINDOW, "OpcionesWin", 200, 150, 250, 200)
   
    -- MAGIA AQUÍ: Color Negro (0,0,0) con transparencia al 180 (Semi-transparente)
    win:SetColor(CONVERT_RGBA(0, 0, 0, 180))
   
    -- Agregamos un texto simple
    local titulo = win:AddComponent(UIComponent.TEXTBOX, "Titulo", 10, 10, 230, 20)
    titulo:SetText("PANEL DE CONTROL", ALIGN_CENTER)
    titulo:SetTextColor(CONVERT_RGBA(255, 215, 0, 255)) -- Color Dorado sólido
   
    -- BOTÓN DE CERRAR USANDO COLORES (Sin imágenes externas)
    local btnCerrar = win:AddComponent(UIComponent.BUTTON, "BtnCerrar", 75, 150, 100, 30)
    btnCerrar:SetColor(CONVERT_RGBA(200, 0, 0, 255)) -- Rojo sólido
    btnCerrar:SetText("CERRAR X", ALIGN_CENTER)
   
    btnCerrar:AddEventListener(UIEvent.MOUSE_DOWN, function()
        win:Hide() -- Oculta la ventana
    end)
   
end, nil, nil)



4. EJEMPLO 3: CONTROLES AVANZADOS (SLIDERS Y SCROLLERS)
¿Quieres hacer un panel de configuración de Anti-Lag o ajustar el volumen? Usamos los componentes
SLIDER y el evento
VALUE_CHANGE.

Código (lua) [Seleccionar]
InterfaceCore.RegisterWindow("AjustesAvanzados", function()
   
    local win = ImUI.Create(UIComponent.WINDOW, "AjustesWin", 50, 50, 300, 150)
    win:SetColor(CONVERT_RGBA(20, 20, 20, 220)) -- Gris muy oscuro transparente
   
    -- 1. CREAMOS UN SLIDER (Barra deslizable)
    local sliderDistancia = win:AddComponent(UIComponent.SLIDER, "DistanciaSlider", 20, 50, 260, 15)
   
    -- 2. ESCUCHAMOS CUANDO EL JUGADOR MUEVE LA BARRA
    sliderDistancia:AddEventListener(UIEvent.VALUE_CHANGE, function(nuevoValor)
        -- nuevoValor será un porcentaje o medida (ej: 0 a 100)
        Console(2, "Ajustando rango de visión a: " .. nuevoValor)
       
        -- Aquí mandarías el paquete al GameServer o aplicarías el efecto local:
        -- SetCustomFog(nuevoValor)
    end)
   
end, nil, nil)



5. RESUMEN DE COMPONENTES UI (RECORDATORIO)
Si intentas crear algo que no está en esta lista, eres un idiota y el LUA te va a escupir un error.

  • UIComponent.WINDOW: La base obligatoria de todo.
  • UIComponent.IMAGE_2D: Para poner tus renders, fondos o iconos.
  • UIComponent.BUTTON: Botones cliqueables.
  • UIComponent.TEXTBOX: Cajas para escribir o mostrar texto.
  • UIComponent.CHECKBOX: Casillas de marcar (Tickbox).
  • UIComponent.SLIDER: Barras arrastrables (volumen, zoom).
  • UIComponent.SCROLLBAR: Barras para bajar y subir (como en Rankings).
  • UIComponent.PARTICLE: Para poner efectos de brillo a tus interfaces.

Documentación Oficial - EmuPlayers MuEmulators
Diseñado por Victhorinox.
  •  
    Los siguientes usuarios dieron las gracias a este tema: Oscar