Вчера пришла мне идея задействовать JAXB более глобально, посадить на эту технологию Npc и Drop.
Сборка была взята L2NextGen HighFive
Итак под снос пошли следующие классы:
NpcTable, L2NpcTemplate, DropListHolder, DropListParser (какими они были можно посмотреть тут L2NextGen)
Ключевой момент это парс дроплиста и п***о при чтении из БД, весь этот ужас под спойлером
Что же нам дала новая система ?
Вместо кучи непонятного кода, по парсу и чтению из БД, мы создаем обьект с полями представленными в xml
Например дроп (Вырезка из кода):
И чтение:
Согласитесь просто и интуитивно понятно
В прикреплении пример xml и полный код чтения этого добра
P.s. Буду рад конструктивной критике от более опытных разработчиков
P.s.2 С парсом всего это добра в XML помогал GenCloud, за что ему отдельная благодарность.
Сборка была взята 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, за что ему отдельная благодарность.
Вложения
Последнее редактирование модератором: