com.l2jserver.model.template.NPCTemplateConverter.java Source code

Java tutorial

Introduction

Here is the source code for com.l2jserver.model.template.NPCTemplateConverter.java

Source

/*
 * This file is part of l2jserver2 <l2jserver2.com>.
 *
 * l2jserver2 is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * l2jserver2 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with l2jserver2.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jserver.model.template;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.MarshalException;
import javax.xml.bind.Marshaller;

import org.apache.commons.io.FileUtils;

import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.id.template.NPCTemplateID;
import com.l2jserver.model.id.template.SkillTemplateID;
import com.l2jserver.model.id.template.TeleportationTemplateID;
import com.l2jserver.model.template.NPCTemplate.Droplist;
import com.l2jserver.model.template.NPCTemplate.Droplist.Item.DropCategory;
import com.l2jserver.model.template.NPCTemplate.Skills;
import com.l2jserver.model.template.NPCTemplate.Talk;
import com.l2jserver.model.template.NPCTemplate.Talk.Chat;
import com.l2jserver.model.template.TeleportationTemplate.Restrictions;
import com.l2jserver.model.template.actor.ActorSex;
import com.l2jserver.model.template.npc.NPCRace;
import com.l2jserver.model.world.npc.BaseNPCController;
import com.l2jserver.model.world.npc.NPCController;
import com.l2jserver.model.world.npc.controller.impl.MonsterController;
import com.l2jserver.model.world.npc.controller.impl.NotImplementedNPCController;
import com.l2jserver.model.world.npc.controller.impl.TeleporterController;
import com.l2jserver.util.factory.CollectionFactory;
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

@SuppressWarnings("restriction")
public class NPCTemplateConverter {
    private static final String JDBC_URL = "jdbc:mysql://localhost/l2jserver_legacy";
    private static final String JDBC_USERNAME = "root";
    private static final String JDBC_PASSWORD = "";
    private static final File L2J_HTML_FOLDER = new File("../../L2J_DataPack_BETA/dist/game/data/html");

    private static final Map<String, Class<? extends NPCController>> controllers = CollectionFactory.newMap();

    private static List<NPCTemplate> templates = CollectionFactory.newList();
    private static Collection<File> htmlScannedFiles;
    private static Teleports teleportation = new Teleports();

    public static void main(String[] args) throws SQLException, IOException, ClassNotFoundException, JAXBException {
        controllers.put("L2Teleporter", TeleporterController.class);
        controllers.put("L2CastleTeleporter", TeleporterController.class);
        controllers.put("L2Npc", BaseNPCController.class);
        controllers.put("L2Monster", MonsterController.class);
        controllers.put("L2FlyMonster", MonsterController.class);
        Class.forName("com.mysql.jdbc.Driver");

        final File target = new File("generated/template/npc");

        System.out.println("Scaning legacy HTML files...");
        htmlScannedFiles = FileUtils.listFiles(L2J_HTML_FOLDER, new String[] { "html", "htm" }, true);

        final JAXBContext c = JAXBContext.newInstance(NPCTemplate.class, Teleports.class);

        final Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USERNAME, JDBC_PASSWORD);
        {
            System.out.println("Converting teleport templates...");
            teleportation.teleport = CollectionFactory.newList();

            final Marshaller m = c.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            final PreparedStatement st = conn.prepareStatement("SELECT * FROM teleport");
            st.execute();
            final ResultSet rs = st.getResultSet();
            while (rs.next()) {
                final TeleportationTemplate template = new TeleportationTemplate();

                template.id = new TeleportationTemplateID(rs.getInt("id"), null);
                template.name = rs.getString("Description");
                TemplateCoordinate coord = new TemplateCoordinate();
                coord.x = rs.getInt("loc_x");
                coord.y = rs.getInt("loc_y");
                coord.z = rs.getInt("loc_z");
                template.point = coord;
                template.price = rs.getInt("price");
                template.item = rs.getInt("itemId");
                if (rs.getBoolean("fornoble")) {
                    template.restrictions = new Restrictions();
                    template.restrictions.restriction = Arrays.asList("NOBLE");
                }
                teleportation.teleport.add(template);
            }
            m.marshal(teleportation, getXMLSerializer(new FileOutputStream(new File(target, "../teleports.xml"))));
            // System.exit(0);
        }

        System.out.println("Generating template XML files...");
        // c.generateSchema(new SchemaOutputResolver() {
        // @Override
        // public Result createOutput(String namespaceUri,
        // String suggestedFileName) throws IOException {
        // // System.out.println(new File(target, suggestedFileName));
        // // return null;
        // return new StreamResult(new File(target, suggestedFileName));
        // }
        // });

        try {
            final Marshaller m = c.createMarshaller();
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            final PreparedStatement st = conn.prepareStatement(
                    "SELECT npc.*, npcskills.level AS race " + "FROM npc " + "LEFT JOIN npcskills "
                            + "ON(npc.idTemplate = npcskills.npcid AND npcskills.skillid = ?)");
            st.setInt(1, 4416);
            st.execute();
            final ResultSet rs = st.getResultSet();
            while (rs.next()) {
                Object[] result = fillNPC(rs);
                NPCTemplate t = (NPCTemplate) result[0];
                String type = (String) result[1];

                String folder = createFolder(type);
                if (folder.isEmpty()) {
                    m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "npc ../npc.xsd");
                } else {
                    m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "npc ../../npc.xsd");
                }

                final File file = new File(target, "npc/" + folder + "/" + t.getID().getID()
                        + (t.getInfo().getName() != null ? "-" + camelCase(t.getInfo().getName().getValue()) : "")
                        + ".xml");
                file.getParentFile().mkdirs();
                templates.add(t);

                try {
                    m.marshal(t, getXMLSerializer(new FileOutputStream(file)));
                } catch (MarshalException e) {
                    System.err.println("Could not generate XML template file for "
                            + t.getInfo().getName().getValue() + " - " + t.getID());
                    file.delete();
                }
            }

            System.out.println("Generated " + templates.size() + " templates");

            System.gc();
            System.out.println("Free: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().freeMemory()));
            System.out.println("Total: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().totalMemory()));
            System.out.println("Used: " + FileUtils.byteCountToDisplaySize(
                    Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
            System.out.println("Max: " + FileUtils.byteCountToDisplaySize(Runtime.getRuntime().maxMemory()));
        } finally {
            conn.close();
        }
    }

    private static Object[] fillNPC(ResultSet rs) throws SQLException, IOException {
        final ObjectFactory factory = new ObjectFactory();

        final NPCTemplate template = factory.createNPCTemplate();
        template.setID(new NPCTemplateID(rs.getInt("idTemplate"), null));

        template.setController(controllers.get(rs.getString("type")));
        if (template.getController() == null)
            template.setController(NotImplementedNPCController.class);
        template.setInfo(factory.createNPCTemplateInfo());

        template.getInfo().setName(factory.createNPCTemplateInfoName());
        template.getInfo().getName().setValue(rs.getString("name"));
        // template.getInfo().getName().setDisplay(rs.getBoolean("show_name"));
        template.getInfo().getName().setSend(rs.getBoolean("serverSideName"));

        template.getInfo().setTitle(factory.createNPCTemplateInfoTitle());
        template.getInfo().getTitle().setValue(rs.getString("title"));
        template.getInfo().getTitle().setSend(rs.getBoolean("serverSideTitle"));

        if (template.getInfo().getName().getValue().length() == 0)
            template.getInfo().setName(null);
        if (template.getInfo().getTitle().getValue().length() == 0)
            template.getInfo().setTitle(null);

        template.getInfo().setLevel(rs.getInt("level"));
        template.getInfo().setRace(getRace(rs.getInt("race")));
        if (!rs.getString("sex").equals("etc"))
            template.getInfo().setSex(ActorSex.valueOf(rs.getString("sex").toUpperCase()));
        // template.info.attackable = rs.getBoolean("attackable");
        // template.getInfo().setTargetable(rs.getBoolean("targetable"));
        template.getInfo().setTargetable(true);
        // template.getInfo().setAggressive(rs.getBoolean("aggro"));
        template.getInfo().setAggressive(true);
        template.getInfo().setAttackable(true); // FIXME

        template.getInfo().setStats(factory.createNPCTemplateInfoStats());

        template.getInfo().getStats().setHp(factory.createNPCTemplateInfoStatsHp());
        template.getInfo().getStats().getHp().setMax(rs.getDouble("hp"));
        template.getInfo().getStats().getHp().setRegen(rs.getDouble("hpreg"));

        template.getInfo().getStats().setMp(factory.createNPCTemplateInfoStatsMp());
        template.getInfo().getStats().getMp().setMax(rs.getDouble("mp"));
        template.getInfo().getStats().getMp().setRegen(rs.getDouble("mpreg"));

        template.getInfo().getStats().setAttack(factory.createNPCTemplateInfoStatsAttack());
        template.getInfo().getStats().getAttack().setRange(rs.getInt("attackrange"));
        template.getInfo().getStats().getAttack().setCritical(rs.getInt("critical"));

        template.getInfo().getStats().getAttack().setPhysical(factory.createNPCTemplateInfoStatsAttackPhysical());
        template.getInfo().getStats().getAttack().getPhysical().setDamage(rs.getDouble("patk"));
        template.getInfo().getStats().getAttack().getPhysical().setSpeed(rs.getDouble("atkspd"));

        template.getInfo().getStats().getAttack().setMagical(factory.createNPCTemplateInfoStatsAttackMagical());
        template.getInfo().getStats().getAttack().getMagical().setDamage(rs.getDouble("matk"));
        template.getInfo().getStats().getAttack().getMagical().setSpeed(rs.getDouble("matkspd"));

        template.getInfo().getStats().setDefense(factory.createNPCTemplateInfoStatsDefense());
        template.getInfo().getStats().getDefense().setPhysical(factory.createNPCTemplateInfoStatsDefensePhysical());
        template.getInfo().getStats().getDefense().getPhysical().setValue(rs.getDouble("pdef"));
        template.getInfo().getStats().getDefense().setMagical(factory.createNPCTemplateInfoStatsDefenseMagical());
        template.getInfo().getStats().getDefense().getMagical().setValue(rs.getDouble("mdef"));

        template.getInfo().getStats().setMove(factory.createNPCTemplateInfoStatsMove());
        template.getInfo().getStats().getMove().setRun(rs.getDouble("runspd"));
        template.getInfo().getStats().getMove().setWalk(rs.getDouble("walkspd"));

        template.getInfo().getStats().setBase(factory.createNPCTemplateInfoStatsBase());
        template.getInfo().getStats().getBase().setInt(rs.getInt("int"));
        template.getInfo().getStats().getBase().setStr(rs.getInt("str"));
        template.getInfo().getStats().getBase().setCon(rs.getInt("con"));
        template.getInfo().getStats().getBase().setDex(rs.getInt("dex"));
        template.getInfo().getStats().getBase().setWit(rs.getInt("wit"));
        template.getInfo().getStats().getBase().setMen(rs.getInt("men"));

        template.getInfo().setExperience(rs.getLong("exp"));
        template.getInfo().setSp(rs.getInt("sp"));

        if (rs.getInt("rhand") > 0 || rs.getInt("lhand") > 0)
            template.getInfo().setItem(factory.createNPCTemplateInfoItem());
        if (rs.getInt("rhand") > 0)
            template.getInfo().getItem().setRightHand(new ItemTemplateID(rs.getInt("rhand"), null));
        if (rs.getInt("lhand") > 0)
            template.getInfo().getItem().setLeftHand(new ItemTemplateID(rs.getInt("lhand"), null));

        template.getInfo().setCollision(factory.createNPCTemplateInfoCollision());
        template.getInfo().getCollision().setRadius(rs.getDouble("collision_radius"));
        template.getInfo().getCollision().setHeigth(rs.getDouble("collision_height"));

        template.setDroplist(fillDropList(factory, rs, template.getID().getID()));
        template.setSkills(fillSkillList(factory, rs, template.getID().getID()));
        template.setTalk(fillHtmlChat(factory, template.getID().getID()));

        return new Object[] { template, createParentType(rs.getString("type")) };
    }

    private static Droplist fillDropList(final ObjectFactory factory, ResultSet npcRs, int npcId)
            throws SQLException {
        final Connection conn = npcRs.getStatement().getConnection();
        final Droplist drops = factory.createNPCTemplateDroplist();

        final PreparedStatement st = conn.prepareStatement("SELECT * FROM droplist WHERE mobId = ?");
        st.setInt(1, npcId);
        st.execute();
        final ResultSet rs = st.getResultSet();
        while (rs.next()) {
            final Droplist.Item item = factory.createNPCTemplateDroplistItem();
            item.setId(new ItemTemplateID(rs.getInt("itemId"), null));
            item.setMin(rs.getInt("min"));
            item.setMax(rs.getInt("max"));
            item.setChance(rs.getInt("chance"));
            item.setCategory(getCategory(rs.getInt("category")));
            drops.getItem().add(item);
        }
        if (drops.getItem().size() == 0)
            return null;
        return drops;
    }

    private static Talk fillHtmlChat(final ObjectFactory factory, int npcId) throws IOException {
        final Talk talk = factory.createNPCTemplateTalk();
        talk.setDefault("default");
        for (final File file : htmlScannedFiles) {
            String id = null;
            if (file.getName().startsWith(npcId + "-")) {
                int preffixLength = (npcId + "-").length();
                id = file.getName().substring(preffixLength, file.getName().indexOf("."));
            } else if (file.getName().startsWith(npcId + ".")) {
                id = "default";
            }
            if (id != null && !file.getAbsolutePath().contains("/half/")
                    && !file.getAbsolutePath().contains("/free/")) {
                Chat chat = new Chat();
                chat.setId(id);
                chat.setValue(FileUtils.readFileToString(file));
                talk.getChat().add(chat);
            }
        }

        if (talk.getChat().size() == 0)
            return null;
        return talk;
    }

    private static Skills fillSkillList(final ObjectFactory factory, ResultSet npcRs, int npcId)
            throws SQLException {
        final Connection conn = npcRs.getStatement().getConnection();
        final Skills skills = factory.createNPCTemplateSkills();

        final PreparedStatement st = conn.prepareStatement("SELECT * FROM npcskills WHERE npcid = ?");
        st.setInt(1, npcId);
        st.execute();
        final ResultSet rs = st.getResultSet();
        while (rs.next()) {
            Skills.Skill s = factory.createNPCTemplateSkillsSkill();
            s.setId(new SkillTemplateID(rs.getInt("skillid"), null));
            s.setLevel(rs.getInt("level"));
            skills.getSkill().add(s);
        }
        if (skills.getSkill().size() == 0)
            return null;
        return skills;
    }

    private static String camelCase(String c) {
        Pattern p = Pattern.compile("[a-zA-Z0-9]+");
        Matcher m = p.matcher(c.replaceAll("_", " ").replaceAll("\\.", " "));
        StringBuffer result = new StringBuffer();
        String word;
        while (m.find()) {
            word = m.group();
            result.append(word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase());
        }
        return result.toString();
    }

    private static String createParentType(String l2j) {
        if (l2j.startsWith("L2"))
            l2j = l2j.substring(2);
        if (l2j.equals("Npc"))
            return "";
        if (l2j.contains("VillageMaster"))
            return (l2j.replaceAll("VillageMaster", "") + "VillageMaster");
        if (l2j.contains("Npc"))
            l2j = l2j.replaceAll("Npc", "");
        return l2j;
    }

    private static String createFolder(String l2j) {
        if (l2j.startsWith("L2"))
            l2j = l2j.substring(2);
        if (l2j.equals("Npc"))
            return "";
        if (l2j.toLowerCase().contains("monster"))
            return "monster";
        if (l2j.toLowerCase().contains("castle"))
            return "castle";
        if (l2j.toLowerCase().contains("fort"))
            return "fort";
        if (l2j.toLowerCase().contains("xmasstree"))
            return "misc";
        return l2j.toLowerCase();
    }

    private static XMLSerializer getXMLSerializer(OutputStream w) {
        // configure an OutputFormat to handle CDATA
        OutputFormat of = new OutputFormat();

        // specify which of your elements you want to be handled as CDATA.
        // The use of the '^' between the namespaceURI and the localname
        // seems to be an implementation detail of the xerces code.
        // When processing xml that doesn't use namespaces, simply omit the
        // namespace prefix as shown in the third CDataElement below.
        of.setCDataElements(new String[] { "^chat" });

        // set any other options you'd like
        of.setPreserveSpace(false);
        of.setIndenting(true);

        // create the serializer
        XMLSerializer serializer = new XMLSerializer(of);
        serializer.setOutputByteStream(w);

        return serializer;
    }

    public static NPCRace getRace(int id) {
        switch (id) {
        case 1:
            return NPCRace.UNDEAD;
        case 2:
            return NPCRace.MAGIC_CREATURE;
        case 3:
            return NPCRace.BEAST;
        case 4:
            return NPCRace.ANIMAL;
        case 5:
            return NPCRace.PLANT;
        case 6:
            return NPCRace.HUMANOID;
        case 7:
            return NPCRace.SPIRIT;
        case 8:
            return NPCRace.ANGEL;
        case 9:
            return NPCRace.DEMON;
        case 10:
            return NPCRace.DRAGON;
        case 11:
            return NPCRace.GIANT;
        case 12:
            return NPCRace.BUG;
        case 13:
            return NPCRace.FAIRIE;
        case 14:
            return NPCRace.HUMAN;
        case 15:
            return NPCRace.ELVEN;
        case 16:
            return NPCRace.DARKELVEN;
        case 17:
            return NPCRace.ORC;
        case 18:
            return NPCRace.DWARVEN;
        case 19:
            return NPCRace.OTHER;
        case 20:
            return NPCRace.NON_LIVING;
        case 21:
            return NPCRace.SIEGE_WEAPON;
        case 22:
            return NPCRace.DEFENDING_ARMY;
        case 23:
            return NPCRace.MERCENARIE;
        case 24:
            return NPCRace.UNKNOWN;
        case 25:
            return NPCRace.KAMAEL;
        default:
            return NPCRace.NONE;
        }
    }

    public static DropCategory getCategory(int id) {
        switch (id) {
        case -1:
            return DropCategory.SPOIL;
        case 0:
            return DropCategory.DROP;
        default:
            return DropCategory.valueOf("UNK_" + id);
        }
    }
}