Custom Style L2Damage

EmptyPirsys

Vagabond
Customer
This code implements a spawn shop system in a game where players can receive items based on their selection. The items are defined in a rewardMap and assigned to different reward groups (e.g., Flaming Sword, Mystic Wand, etc.). When a player enters the game, the system checks if they have already received a reward and displays an HTML menu based on their status. If the player hasn't received a reward, they can choose an item from the menu and receive it. The player's status is updated in the database to reflect the reward.


I need assistance understanding how to apply the correct bypass line in the HTML file to trigger the handleItemSelection method from the ModSpawnShop class. The action should pass the correct selection value (1, 2, 3, etc.) depending on which item the player selects. Could you help me understand how to properly create the bypass for this?


Code:
package Spawn;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import l2.gameserver.database.DatabaseFactory;
import l2.gameserver.listener.actor.player.OnPlayerEnterListener;
import l2.gameserver.model.Player;
import l2.gameserver.model.actor.listener.CharListenerList;
import l2.gameserver.model.items.ItemInstance;
import l2.gameserver.network.l2.s2c.NpcHtmlMessage;
import l2.gameserver.network.l2.s2c.SystemMessage;
import l2.gameserver.scripts.Functions;
import l2.gameserver.scripts.ScriptFile;
import l2.gameserver.utils.ItemFunctions;

public class ModSpawnShop extends Functions implements ScriptFile, OnPlayerEnterListener {

    // Mapa de recompensas configurado de forma más flexible
    private static final Map<Integer, int[][]> rewardMap = new HashMap<>();

    static {
        rewardMap.put(1, new int[][] {
            {7575, 1, 15},  // Flaming Sword: {ID, Count, Enchant}
            {6660, 1, 15},    // Mystic Wand: {ID, Count, Enchant}
            {6658, 1, 15},    // Mystic Wand: {ID, Count, Enchant}
        });
        rewardMap.put(2, new int[][] {
            {6367, 1, 15},   // Example Item 1: {ID, Count, Enchant}
            {6660, 1, 15}    // Another Example Item: {ID, Count, Enchant}
        });
        rewardMap.put(3, new int[][] {
            {6579, 1, 15}    // Yet Another Example Item: {ID, Count, Enchant}
        });
    }

    private void giveItems(Player player, String rewardVar, int[][] itemsToGive, String alreadyRewardedMessage) {
        if (!player.getVarB(rewardVar) && !checkUsedCheckFromDatabase(player)) {
            // Otorgar los ítems
            for (int[] itemData : itemsToGive) {
                ItemInstance item = ItemFunctions.createItem(itemData[0]);
                item.setCount(itemData[1]);
                item.setEnchantLevel(itemData[2]);
                player.getInventory().addItem(item);
                player.sendPacket(SystemMessage.obtainItems(item.getItemId(), item.getCount(), item.getEnchantLevel()));
                player.sendMessage("You have received: " + item.getTemplate().getName() + " x" + item.getCount());
            }

            // Marcar que el jugador ha usado el check y actualizar la base de datos
            setUsedCheck(player);
            player.setVar(rewardVar, "true", -1);

            // Mostrar un mensaje HTML al jugador para seleccionar otra entrega
            showHtmlMenu(player);
        } else {
            player.sendMessage(alreadyRewardedMessage);
        }
    }

    private void showHtmlMenu(Player player) {
        // Definir los nombres de los archivos
        String htmlFile;
        
        // Comprobamos el valor de 'used_check' desde la base de datos
        boolean hasUsedCheck = checkUsedCheckFromDatabase(player);

        if (hasUsedCheck) {
            htmlFile = "si.htm";  // Si 'used_check' es 1
        } else {
            htmlFile = "no.htm";  // Si 'used_check' es 0
        }

        // Aquí usamos la ruta correcta del archivo
        String filePath = "data/html-en/mods/spelogin/" + htmlFile;  // Ruta completa

        // Mostrar la ruta en la consola
        System.out.println("HTML file path: " + filePath);

        File file = new File(filePath);  // Ruta completa del archivo HTML

        if (!file.exists()) {
            player.sendMessage("Error: HTML file not found.");
            return;
        }

        // Cargar el contenido del archivo HTML y enviarlo al jugador
        try {
            String htmlContent = Files.readString(Paths.get(file.getPath()), StandardCharsets.UTF_8);
            
            // Enviar el HTML al jugador
            NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(0);
            npcHtmlMessage.setHtml(htmlContent);
            player.sendPacket(npcHtmlMessage);
            
        } catch (IOException e) {
            player.sendMessage("Error reading HTML file.");
            e.printStackTrace();
        }
    }

    // Unificado el código de verificación del 'used_check' de la base de datos
    private boolean checkUsedCheckFromDatabase(Player player) {
        try (Connection con = DatabaseFactory.getInstance().getConnection();
             PreparedStatement ps = con.prepareStatement("SELECT `used_check` FROM `characters` WHERE `obj_Id` = ?")) {
            ps.setInt(1, player.getObjectId());
            try (ResultSet rs = ps.executeQuery()) {
                return rs.next() && rs.getInt("used_check") == 1;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // Método para actualizar el estado del check (usado o no)
    private void setUsedCheck(Player player) {
        try (Connection con = DatabaseFactory.getInstance().getConnection();
             PreparedStatement ps = con.prepareStatement("UPDATE `characters` SET `used_check` = 1 WHERE `obj_Id` = ?")) {
            ps.setInt(1, player.getObjectId());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // Método para manejar la elección del jugador en base a la selección del ítem
    public void handleItemSelection(Player player, int selection) {
        if (checkUsedCheckFromDatabase(player)) {
            player.sendMessage("You have already used this reward. You cannot use it again.");
            return;
        }

        int[][] itemsToGive = rewardMap.getOrDefault(selection, new int[0][0]);
        if (itemsToGive.length == 0) {
            player.sendMessage("Invalid selection, no items to give.");
            return;
        }

        // Dar los ítems y marcar que el jugador ha usado el check
        giveItems(player, "multiple_items_rewarded", itemsToGive, "Items already rewarded");
    }

    @Override
    public void onPlayerEnter(Player activeChar) {
        showHtmlMenu(activeChar);
    }

    public void onLoad() {
        CharListenerList.addGlobal(this);
    }

    public void onReload() {
        // Implementa aquí la lógica de recarga, si es necesario
    }

    @Override
    public void onShutdown() {
        // Implementa aquí la lógica de apagado, si es necesario
    }
}
 
Code:
package pirsysmods;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import l2.gameserver.database.DatabaseFactory;
import l2.gameserver.listener.actor.player.OnPlayerEnterListener;
import l2.gameserver.model.Player;
import l2.gameserver.model.actor.listener.CharListenerList;
import l2.gameserver.model.items.ItemInstance;
import l2.gameserver.network.l2.s2c.NpcHtmlMessage;
import l2.gameserver.network.l2.s2c.SystemMessage;
import l2.gameserver.scripts.Functions;
import l2.gameserver.scripts.ScriptFile;
import l2.gameserver.utils.ItemFunctions;

public class modspawnshop extends Functions implements ScriptFile, OnPlayerEnterListener {

    // Mapa de recompensas configurado de forma más flexible
    private static final Map<Integer, int[][]> rewardMap = new HashMap<>();

    static {
        addRewardSet1();
        addRewardSet2();
        addRewardSet3();
    }

    // Métodos para agregar los sets de recompensas
    public static void addRewardSet1() {
        rewardMap.put(1, new int[][] {
            {7575, 1, 15},  // Flaming Sword: {ID, Count, Enchant}
            {6660, 1, 15},  // Mystic Wand: {ID, Count, Enchant}
            {6658, 1, 15},  // Mystic Wand: {ID, Count, Enchant}
        });
    }

    public static void addRewardSet2() {
        rewardMap.put(2, new int[][] {
            {6367, 1, 15},  // Example Item 1: {ID, Count, Enchant}
            {6660, 1, 15}   // Another Example Item: {ID, Count, Enchant}
        });
    }

    public static void addRewardSet3() {
        rewardMap.put(3, new int[][] {
            {6579, 1, 15}   // Yet Another Example Item: {ID, Count, Enchant}
        });
    }

    // Método optimizado para dar ítems y gestionar el proceso de recompensa
    private void giveItems(Player player, String rewardVar, int[][] itemsToGive, String alreadyRewardedMessage) {
        if (player.getVarB(rewardVar) || checkUsedCheckFromDatabase(player)) {
            player.sendMessage(alreadyRewardedMessage);
            return;
        }

        // Otorgar los ítems
        for (int[] itemData : itemsToGive) {
            ItemInstance item = ItemFunctions.createItem(itemData[0]);
            item.setCount(itemData[1]);
            item.setEnchantLevel(itemData[2]);
            player.getInventory().addItem(item);
            player.sendPacket(SystemMessage.obtainItems(item.getItemId(), item.getCount(), item.getEnchantLevel()));
            player.sendMessage("You have received: " + item.getTemplate().getName() + " x" + item.getCount());
        }

        // Marcar que el jugador ha usado el check y actualizar la base de datos
        setUsedCheck(player);
        player.setVar(rewardVar, "true", -1);

        // Mostrar un mensaje HTML al jugador para seleccionar otra entrega
        showHtmlMenu(player);
    }

    // Refactorización de la carga y envío de HTML
    private void showHtmlMenu(Player player) {
        String htmlFile = checkUsedCheckFromDatabase(player) ? "si.htm" : "no.htm";
        String filePath = "data/html-en/mods/spelogin/" + htmlFile;

        try {
            String htmlContent = loadHtmlContent(filePath);
            if (htmlContent != null) {
                NpcHtmlMessage npcHtmlMessage = new NpcHtmlMessage(0);
                npcHtmlMessage.setHtml(htmlContent);
                player.sendPacket(npcHtmlMessage);
            } else {
                player.sendMessage("Error: HTML file not found or could not be read.");
            }
        } catch (IOException e) {
            player.sendMessage("Error reading HTML file.");
            e.printStackTrace();
        }
    }

    private String loadHtmlContent(String filePath) throws IOException {
        File file = new File(filePath);
        if (file.exists()) {
            return Files.readString(Paths.get(file.getPath()), StandardCharsets.UTF_8);
        }
        return null;
    }

    // Optimización de la consulta a la base de datos para verificar si ya se ha utilizado el check
    private boolean checkUsedCheckFromDatabase(Player player) {
        try (Connection con = DatabaseFactory.getInstance().getConnection();
             PreparedStatement ps = con.prepareStatement("SELECT `used_check` FROM `characters` WHERE `obj_Id` = ?")) {
            ps.setInt(1, player.getObjectId());
            try (ResultSet rs = ps.executeQuery()) {
                return rs.next() && rs.getInt("used_check") == 1;
            }
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
    }

    // Optimización de la actualización del estado en la base de datos
    private void setUsedCheck(Player player) {
        try (Connection con = DatabaseFactory.getInstance().getConnection();
             PreparedStatement ps = con.prepareStatement("UPDATE `characters` SET `used_check` = 1 WHERE `obj_Id` = ?")) {
            ps.setInt(1, player.getObjectId());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // Manejo de selección de ítem con validación más clara
    public void handleItemSelection(Player player, int selection) {
        int[][] itemsToGive = rewardMap.getOrDefault(selection, new int[0][0]);
        if (itemsToGive.length == 0) {
            player.sendMessage("Invalid selection, no items to give.");
            return;
        }

        giveItems(player, "multiple_items_rewarded", itemsToGive, "You have already claimed this reward.");
    }

    @Override
    public void onPlayerEnter(Player activeChar) {
        showHtmlMenu(activeChar);
    }

    public void onLoad() {
        CharListenerList.addGlobal(this);
    }

    public void onReload() {
        // Implementa aquí la lógica de recarga, si es necesario
    }

    @Override
    public void onShutdown() {
        // Implementa aquí la lógica de apagado, si es necesario
    }
}
 
Back
Top