NpcTable и DropTable, отказ от sql и dom4j в пользу JAXB

Tyrel

Путник
Пользователь
Сообщения
65
Розыгрыши
0
Репутация
161
Реакции
23
Баллы
0
Вчера пришла мне идея задействовать JAXB более глобально, посадить на эту технологию Npc и Drop.
Сборка была взята L2NextGen HighFive

Итак под снос пошли следующие классы:
NpcTable, L2NpcTemplate, DropListHolder, DropListParser (какими они были можно посмотреть тут L2NextGen)
Ключевой момент это парс дроплиста и п***о при чтении из БД, весь этот ужас под спойлером
Код:
-        for(final Iterator<Element> npcIterator = rootElement.elementIterator(); npcIterator.hasNext();)
-        {
-            final Element element = npcIterator.next();
-            final int npcId = Integer.parseInt(element.attributeValue("id"));
-
-            for(final Iterator<Element> rewardlistIterator = element.elementIterator(); rewardlistIterator.hasNext();)
-            {
-                final Element firstElement = rewardlistIterator.next();
-                final String nodeName = firstElement.getName();
-                if(nodeName.equalsIgnoreCase("rewardlist"))
-                {
-                    final RewardType type = RewardType.valueOf(firstElement.attributeValue("type"));
-                    final boolean autoLoot = firstElement.attributeValue("auto_loot") != null && Boolean.parseBoolean(firstElement.attributeValue("auto_loot"));
-                    final RewardList list = new RewardList(type, autoLoot);
-
-                    for(final Iterator<Element> nextIterator = firstElement.elementIterator(); nextIterator.hasNext();)
-                    {
-                        final Element nextElement = nextIterator.next();
-                        final String nextName = nextElement.getName();
-                        if(nextName.equalsIgnoreCase("group"))
-                        {
-                            final double enterChance = nextElement.attributeValue("chance") == null ? RewardList.MAX_CHANCE : Double.parseDouble(nextElement.attributeValue("chance")) * 10000;
-
-                            final RewardGroup group = type == RewardType.SWEEP || type == RewardType.NOT_RATED_NOT_GROUPED ? null : new RewardGroup(enterChance);
-                            for(final Iterator<Element> rewardIterator = nextElement.elementIterator(); rewardIterator.hasNext();)
-                            {
-                                final Element rewardElement = rewardIterator.next();
-                                final RewardData data = parseReward(rewardElement);
-                                if(data == null)
-                                    continue;
-                                if(type == RewardType.SWEEP || type == RewardType.NOT_RATED_NOT_GROUPED)
-                                    warn("Can't load rewardlist from group: " + npcId + "; type: " + type);
-                                else
-                                    group.addData(data);
-                            }
-
-                            if(group != null)
-                                list.add(group);
-                        }
-                        else if(nextName.equalsIgnoreCase("reward"))
-                        {
-                            if(type != RewardType.SWEEP && type != RewardType.NOT_RATED_NOT_GROUPED)
-                            {
-                                warn("Reward can't be without group(and not grouped): " + npcId + "; type: " + type);
-                                continue;
-                            }
-
-                            final RewardData data = parseReward(nextElement);
-                            if(data == null)
-                                continue;
-                            final RewardGroup g = new RewardGroup(RewardList.MAX_CHANCE);
-                            g.addData(data);
-                            list.add(g);
-                        }
-                    }
-
-                    if(type == RewardType.RATED_GROUPED || type == RewardType.NOT_RATED_GROUPED)
-                        if(!list.validate())
-                            warn("Problems with rewardlist for npc: " + npcId + "; type: " + type);
-
-                    getHolder().putList(npcId, type, list);
-                }
-            }
-        }

Код:
//    private static void loadNpcTemplate(final Statement statement, ResultSet data)
//    {
//        try
//        {
//            data = statement.executeQuery("SELECT * FROM npc AS c LEFT JOIN npc_elementals AS cs ON (c.id = cs.npc_id) WHERE ai_type IS NOT NULL");
//
//            int maxId = 0;
//            final GArray<L2NpcTemplate> temp = new GArray<>(10000);
//            while (data.next())
//            {
//                final StatsSet npcDat = new StatsSet();
//                final int id = data.getInt("id");
//                final int level = data.getByte("level");
//
//                if(maxId < id)
//                    maxId = id;
//
//                npcDat.set("npcId", id);
//                npcDat.set("displayId", data.getInt("displayId"));
//                npcDat.set("level", level);
//                npcDat.set("jClass", data.getString("class"));
//
//                npcDat.set("name", data.getString("name"));
//                npcDat.set("title", data.getString("title"));
//                npcDat.set("collision_radius", data.getDouble("collision_radius"));
//                npcDat.set("collision_height", data.getDouble("collision_height"));
//                npcDat.set("type", data.getString("type"));
//                npcDat.set("ai_type", data.getString("ai_type"));
//                npcDat.set("baseAtkRange", data.getInt("attackrange"));
//                npcDat.set("revardExp", data.getInt("exp"));
//                npcDat.set("revardSp", data.getInt("sp"));
//                npcDat.set("basePAtkSpd", data.getInt("atkspd"));
//                npcDat.set("baseMAtkSpd", data.getInt("matkspd"));
//                npcDat.set("aggroRange", data.getShort("aggro"));
//                npcDat.set("rhand", data.getInt("rhand"));
//                npcDat.set("lhand", data.getInt("lhand"));
//                npcDat.set("baseWalkSpd", data.getInt("walkspd"));
//                npcDat.set("baseRunSpd", data.getInt("runspd"));
//
//                npcDat.set("baseHpReg", data.getDouble("base_hp_regen"));
//                npcDat.set("baseCpReg", 0);
//                npcDat.set("baseMpReg", data.getDouble("base_mp_regen"));
//
//                npcDat.set("baseSTR", data.getInt("str"));
//                npcDat.set("baseCON", data.getInt("con"));
//                npcDat.set("baseDEX", data.getInt("dex"));
//                npcDat.set("baseINT", data.getInt("int"));
//                npcDat.set("baseWIT", data.getInt("wit"));
//                npcDat.set("baseMEN", data.getInt("men"));
//
//                npcDat.set("baseHpMax", data.getInt("hp"));
//                npcDat.set("baseCpMax", 0);
//                npcDat.set("baseMpMax", data.getInt("mp"));
//                npcDat.set("basePAtk", data.getInt("patk"));
//                npcDat.set("basePDef", data.getInt("pdef"));
//                npcDat.set("baseMAtk", data.getInt("matk"));
//                npcDat.set("baseMDef", data.getInt("mdef"));
//
//                npcDat.set("baseShldDef", data.getInt("shield_defense"));
//                npcDat.set("baseShldRate", data.getInt("shield_defense_rate"));
//
//                if(data.getString("type").equalsIgnoreCase("L2Pet"))
//                    if(data.getString("name").equalsIgnoreCase("Cursed Man"))
//                        npcDat.set("baseCritRate", 80);
//                    else
//                        npcDat.set("baseCritRate", 44);
//                else
//                    npcDat.set("baseCritRate", Math.max(1, data.getInt("base_critical")) * 10);
//
//                String factionId = data.getString("faction_id");
//                if(factionId != null)
//                    factionId = factionId.trim();
//
//                npcDat.set("factionId", factionId);
//                npcDat.set("factionRange", factionId == null || factionId.equals("") ? 0 : data.getShort("faction_range"));
//
//                npcDat.set("drop_herbs", data.getInt("drop_herbs"));
//                npcDat.set("shots", data.getString("shots"));
//
//                // load elementals data
//                if(Config.ALT_LOAD_ELEMENTSTABLE)
//                    if(data.getInt("npc_id") > 0 && data.getInt("npc_id") == id)
//                    {
//                        switch (data.getByte("elem_atk_type"))
//                        {
//                            case L2Elementals.ATTRIBUTE_FIRE:
//                                npcDat.set("baseFireAttack", data.getInt("elem_atk_value"));
//                                break;
//                            case L2Elementals.ATTRIBUTE_WATER:
//                                npcDat.set("baseWaterAttack", data.getInt("elem_atk_value"));
//                                break;
//                            case L2Elementals.ATTRIBUTE_WIND:
//                                npcDat.set("baseWindAttack", data.getInt("elem_atk_value"));
//                                break;
//                            case L2Elementals.ATTRIBUTE_EARTH:
//                                npcDat.set("baseEarthAttack", data.getInt("elem_atk_value"));
//                                break;
//                            case L2Elementals.ATTRIBUTE_SACRED:
//                                npcDat.set("baseSacredAttack", data.getInt("elem_atk_value"));
//                                break;
//                            case L2Elementals.ATTRIBUTE_UNHOLY:
//                                npcDat.set("baseUnholyAttack", data.getInt("elem_atk_value"));
//                                break;
//                            case L2Elementals.ATTRIBUTE_NONE:
//                                break;
//                            default:
//                                _log.error("NpcTable: elementals error with id: " + id + "; unknown elementType: " + data.getByte("elem_atk_type"));
//                        }
//
//                        // defens value
//                        npcDat.set("baseFireDefend", data.getInt("fire_def_value"));
//                        npcDat.set("baseWaterDefend", data.getInt("water_def_value"));
//                        npcDat.set("baseWindDefend", data.getInt("wind_def_value"));
//                        npcDat.set("baseEarthDefend", data.getInt("earth_def_value"));
//                        npcDat.set("baseSacredDefend", data.getInt("holy_def_value"));
//                        npcDat.set("baseUnholyDefend", data.getInt("dark_def_value"));
//                    }
//
//                final L2NpcTemplate template = new L2NpcTemplate(npcDat, ai_params.get(id));
//                temp.add(template);
//
//                if(npcsByLevel[level] == null)
//                    npcsByLevel[level] = new TemplateHolderByLevel();
//                npcsByLevel[level].add(template);
//            }
//
//            _allTemplates = new L2NpcTemplate[maxId + 1];
//            for(final L2NpcTemplate template : temp)
//                _allTemplates[template.npcId] = template;
//
//            _log.info("NpcTable: Loaded " + temp.size() + " Npc Templates.");
//        }
//        catch(final Exception e)
//        {
//            _log.error("error while creating npc table ", e);
//        }
//        finally
//        {
//            DbUtils.closeQuietly(data);
//        }
//    }
Что же нам дала новая система ?
Вместо кучи непонятного кода, по парсу и чтению из БД, мы создаем обьект с полями представленными в xml
Например дроп (Вырезка из кода):
Код:
package services.lineage.data.npc.elements;

import javax.xml.bind.annotation.XmlAttribute;

/**
Tyrel
22.08.2015
*/
public class Reward
{
    int itemId;
    int min;
    int max;
    float chance;

    public int getItemId()
    {
        return itemId;
    }

    @XmlAttribute(name = "item_id")
    public void setItemId(int itemId)
    {
        this.itemId = itemId;
    }

    public int getMin()
    {
        return min;
    }

    @XmlAttribute(name = "min")
    public void setMin(int min)
    {
        this.min = min;
    }

    public int getMax()
    {
        return max;
    }

    @XmlAttribute(name = "max")
    public void setMax(int max)
    {
        this.max = max;
    }

    public float getChance()
    {
        return chance;
    }

    @XmlAttribute(name = "chance")
    public void setChance(float chance)
    {
        this.chance = chance;
    }
}
И чтение:
Код:
        try
        {
            JAXBContext context = JAXBContext.newInstance(NpcAll.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            Object object = unmarshaller.unmarshal(file);

            NpcAll npcAll = (NpcAll) object;
            for(L2NpcTemplate npc : npcAll.getNpcs())
            {
                npcs.put(npc.getNpcId(), npc);
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
Согласитесь просто и интуитивно понятно :)
В прикреплении пример xml и полный код чтения этого добра
P.s. Буду рад конструктивной критике от более опытных разработчиков
P.s.2 С парсом всего это добра в XML помогал GenCloud, за что ему отдельная благодарность.
 

Вложения

  • services.rar
    6,7 КБ · Просмотры: 51
  • data.rar
    1,3 КБ · Просмотры: 50
Последнее редактирование модератором:
У меня появился такой вопрос, ведь в первом и во втором случае в конце мы получаем один и тот же набор данных в памяти? И весь процесс загрузки данных проходит в момент загрузки сервера? Если я прав, то получается что смысла в проделанной вами работе не особо то и много. Как я считаю, сколько памяти и времени скушает сервер во время загрузки, не особо важно, ибо оно не велико совсем...
По крайней мере я бы уделил время более интересным вещам в серверах. Тем вещам которые непосредственно задействованы в процессе игры, в процессе работы сервера...
 
  • Мне нравится
Реакции: zcxv
У меня появился такой вопрос, ведь в первом и во втором случае в конце мы получаем один и тот же набор данных в памяти? И весь процесс загрузки данных проходит в момент загрузки сервера? Если я прав, то получается что смысла в проделанной вами работе не особо то и много. Как я считаю, сколько памяти и времени скушает сервер во время загрузки, не особо важно, ибо оно не велико совсем...
По крайней мере я бы уделил время более интересным вещам в серверах. Тем вещам которые непосредственно задействованы в процессе игры, в процессе работы сервера...
Так и есть, но если писать с нуля поддержку каких либо хмл ? Мой вариант проще понятнее и быстрее.
В данном случае это был пример чисто в образовательных целях.
 
Назад
Сверху Снизу