Hikari 48 Опубликовано 23 апреля, 2014 (изменено) При добавлении большого кол-ва бафов в схему бафера, он бафает не в том порядке в каком сохраняли. Нарыл 3 класса. ManageBuffer.rar (не влез под спойлер) package l2ft.gameserver.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.List; import l2ft.commons.dbutils.DbUtils; import l2ft.gameserver.database.DatabaseFactory; import l2ft.gameserver.model.ManageBbsBuffer; import l2ft.gameserver.model.ManageBbsBuffer.SBufferScheme; import l2ft.gameserver.model.Player; import l2ft.gameserver.utils.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class CommunityBufferDAO { private static final Logger _log = LoggerFactory.getLogger(CommunityBufferDAO.class); private static final CommunityBufferDAO _instance = new CommunityBufferDAO(); public static final String SELECT_SQL_QUERY = "SELECT * FROM bbs_skillsave"; public static final String DELETE_SQL_QUERY = "DELETE FROM bbs_skillsave WHERE charId=? AND schameid=?"; public static final String INSERT_SQL_QUERY = "INSERT INTO bbs_skillsave (charId,schameid,name,skills) VALUES(?,?,?,?)"; public static CommunityBufferDAO getInstance() { return _instance; } public void select() { Connection con = null; PreparedStatement statement = null; ResultSet rset = null; try { con = DatabaseFactory.getInstance().getConnection(); statement = con.prepareStatement(SELECT_SQL_QUERY); rset = statement.executeQuery(); while (rset.next()) { SBufferScheme scheme = new SBufferScheme(); scheme.id = rset.getInt("schameid"); scheme.obj_id = rset.getInt("charId"); scheme.name = rset.getString("name"); scheme.skills_id = ManageBbsBuffer.StringToInt(rset.getString("skills")); if(!Util.isMatchingRegexp(scheme.name, "[A-Za-z0-9]*")) { delete(scheme); } else { ManageBbsBuffer.getInstance(); ManageBbsBuffer.getSchemeList().add(scheme); } } } catch (Exception e) { _log.error("CommunityBufferDAO.select():" + e, e); } finally { DbUtils.closeQuietly(con, statement, rset); } } public void delete(SBufferScheme scheme) { Connection con = null; PreparedStatement statement = null; try { con = DatabaseFactory.getInstance().getConnection(); statement = con.prepareStatement(DELETE_SQL_QUERY); statement.setInt(1, scheme.obj_id); statement.setInt(2, scheme.id); statement.execute(); ManageBbsBuffer.getInstance(); ManageBbsBuffer.getSchemeList().remove(scheme); } catch (Exception e) { } finally { DbUtils.closeQuietly(con, statement); } } public void insert(SBufferScheme scheme, Player player) { Connection con = null; PreparedStatement stmt = null; scheme.id = ManageBbsBuffer.getAutoIncrement(1); String buff_list = ManageBbsBuffer.IntToString(scheme.skills_id); if(!Util.isMatchingRegexp(scheme.name, "[A-Za-z0-9]*")) { player.sendMessage(player.isLangRus() ? "Не верное имя схемы! Допустимы только" : "Do not correct schema name! Valid only"); player.sendMessage(player.isLangRus() ? "цифры и буквы латинского алфавита!" : "numbers and letters of the alphabet!"); return; } if(buff_list == null || buff_list == "" || buff_list == " ") { player.sendMessage(player.isLangRus() ? "Нет бафов для сохранения!" : "No buffs for the preservation!"); return; } try { con = DatabaseFactory.getInstance().getConnection(); stmt = con.prepareStatement(INSERT_SQL_QUERY); stmt.setInt(1, scheme.obj_id); stmt.setInt(2, scheme.id); stmt.setString(3, scheme.name); stmt.setString(4, buff_list); stmt.execute(); ManageBbsBuffer.getInstance(); ManageBbsBuffer.getSchemeList().add(scheme); } catch (Exception e) { } finally { DbUtils.closeQuietly(con, stmt); } } } package l2ft.gameserver.model; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ManageBbsBuffer { private static final Logger _log = LoggerFactory.getLogger(ManageBbsBuffer.class); private static final ManageBbsBuffer _instance = new ManageBbsBuffer(); private List listScheme; public ManageBbsBuffer() { this.listScheme = new ArrayList(); } public static ManageBbsBuffer getInstance() { return _instance; } public static SBufferScheme getScheme(int id, int obj_id) { for(SBufferScheme scheme : getInstance().listScheme) if(scheme.id == id && scheme.obj_id == obj_id) return scheme; return null; } public static int getAutoIncrement(int ain) { int count = 0; for(SBufferScheme scheme : getInstance().listScheme) if(ain == scheme.id) count++; if(count == 0) return ain; return getAutoIncrement(ain + 1); } public static List StringToInt(String list) { List skills_id = new ArrayList(); String[] s_id = list.split(";"); for(int i = 0; i < s_id.length; i++) skills_id.add(Integer.valueOf(Integer.parseInt(s_id))); return skills_id; } public static String IntToString(List id) { String buff_list = ""; for(int i = 0; i < id.size(); i++) buff_list = buff_list + new StringBuilder().append(id.get(i)).append(";").toString(); return buff_list; } public static List getSchemeList() { return getInstance().listScheme; } public static int getCountOnePlayer(int obj_id) { int count = 0; for(SBufferScheme scheme : getInstance().listScheme) if(obj_id == scheme.obj_id) count++; return count; } public static boolean existName(int obj_id, String name) { for(SBufferScheme scheme : getInstance().listScheme) if(obj_id == scheme.obj_id && name == scheme.name) return true; return false; } public static List getSchemePlayer(int obj_id) { List list = new ArrayList(); for(SBufferScheme sm : getInstance().listScheme) if(sm.obj_id == obj_id) list.add(sm); return list; } public static class SBufferScheme { public int id; public int obj_id; public String name; public List skills_id; public SBufferScheme() { this.id = 0; this.obj_id = 0; this.name = ""; this.skills_id = new ArrayList(); } } } Куда рыть не знаю, исходы FT. Изменено 23 апреля, 2014 пользователем Pacifist 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
GorDeveloper 356 Опубликовано 23 апреля, 2014 Ты в курсе о спойлерах и разметке кода? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Hikari 48 Опубликовано 23 апреля, 2014 (изменено) Ты в курсе о спойлерах и разметке кода? ManageBuffer под спойлер не залезает, большой слишком. Изменено 23 апреля, 2014 пользователем Pacifist 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
HECKBuK 229 Опубликовано 23 апреля, 2014 а разве принципиально, в каком порядке бафать? Или же у вас на сервере есть что-то вроде "сначала бафаешь этот, а потом этот и статы в 2 раза повышаются, а если наоборот, то лапу соси"?) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Kenrix 14 Опубликовано 24 апреля, 2014 для сортировки используй карты HashMap либо LinkedHashMap Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Hikari 48 Опубликовано 28 апреля, 2014 а разве принципиально, в каком порядке бафать? Или же у вас на сервере есть что-то вроде "сначала бафаешь этот, а потом этот и статы в 2 раза повышаются, а если наоборот, то лапу соси"?) игрокам принципиально, тру игроки так против "канцелов" борются 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
dislike 302 Опубликовано 29 апреля, 2014 (изменено) public Effect[] getAllFirstEffects() { if( isEmpty() ) return Effect.EMPTY_L2EFFECT_ARRAY; List<Effect> list = new ArrayList<Effect>(); for(Effect e : _effects) list.add(e); return list.toArray(new Effect[list.size()]); } В EffectList Возможно будут косяки с двойными иконками, нужно тестить Изменено 30 апреля, 2014 пользователем dislike 2 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Gaikotsu 620 Опубликовано 1 мая, 2014 (изменено) как выше уже сказали - сохранять придется в базе не только список скиллов в группе, но еще и их очередность, ну и при обратном восстановлении читать из базы этот список отсортированным по этому полю, где записан порядковый номер баффа в группе. ... а хотя по коду вижу что тут вообще список скиллов в строку сохраняется, так что по идее уже и так очередность есть, так что хз, если честно что там не так. З.Ы. а вообще, приведенный код хранения групп баффов и работы с ними - та еще какашка. Изменено 1 мая, 2014 пользователем Gaikotsu 2 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
dislike 302 Опубликовано 1 мая, 2014 (изменено) как выше уже сказали - сохранять придется в базе не только список скиллов в группе, но еще и их очередность, ну и при обратном восстановлении читать из базы этот список отсортированным по этому полю, где записан порядковый номер баффа в группе. ... а хотя по коду вижу что тут вообще список скиллов в строку сохраняется, так что по идее уже и так очередность есть, так что хз, если честно что там не так. З.Ы. а вообще, приведенный код хранения групп баффов и работы с ними - та еще какашка. Вот в этом вся беда была public Effect[] getAllFirstEffects() { if(isEmpty()) return Effect.EMPTY_L2EFFECT_ARRAY; TIntObjectHashMap<Effect> map = new TIntObjectHashMap<>(); for(Effect e : _effects) map.put(e.getSkill().getId(), e); return map.values(new Effect[map.size()]); } put дополнительную сортировку делал, переписали этот метод через list , всё нормально стало Я тоже вначале не мог понять в чём проблема, везде всё прямо по циклам без сортировки. А нужно было с самого начала рыть. P.S А как лучше посоветуешь сделать ? Загружать схемы к кеш при заходе персонажа ? Изменено 1 мая, 2014 пользователем dislike 1 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты
Gaikotsu 620 Опубликовано 1 мая, 2014 (изменено) а ну да - тут же юзался TIntObjectHashMap - в нем сортировка идет кажется по хэшам ключей, если не ошибаюсь. так что или обычный ArrayList юзать или LinkedHashMap. P.S. да, по мне дак лучше загружать данные именно тогда когда они потребуются, а не все разом + лично у меня к примеру общего хранилища личных групп баффов нет - группы игрока хранятся в его классе, что опять же в какой-то мере упрощает работу с ними. вот для примера фрагмент моего кода, работающего с разными личными данными игрока, используемыми через коммюнити. package l2p.gameserver.model.actor.instances.player; import java.util.LinkedHashMap; import l2p.gameserver.Config; import l2p.gameserver.dao.CommunityBufferDAO; import l2p.gameserver.dao.CommunityFavoritesDAO; import l2p.gameserver.dao.CommunityTeleportDAO; import l2p.gameserver.model.Player; import l2p.gameserver.model.community.BufferGroup; import l2p.gameserver.model.community.FavoriteLink; import l2p.gameserver.model.community.TeleportPoint; /** * @author Gaikotsu */ public class Community { private final Player _player; private int _pageId = 0; private boolean _isUse = false; private LinkedHashMap<Integer, TeleportPoint> _teleportPoints = new LinkedHashMap<Integer, TeleportPoint>(); private LinkedHashMap<Integer, BufferGroup> _bufferGroups = new LinkedHashMap<Integer, BufferGroup>(); private LinkedHashMap<Integer, FavoriteLink> _favoriteLinks = new LinkedHashMap<Integer, FavoriteLink>(); public Community(Player player) { _player = player; } public void restore() { loadTeleportPoints(); loadBufferGroups(); loadFavoriteLinks(); } public void setUse(boolean value) { _isUse = value; } public boolean isUse() { return _isUse; } /** * Устанавливает номер используемой страницы */ public void setPageId(final int pageId) { _pageId = pageId; } /** * Возвращает номер используемой страницы */ public int getPageId() { return _pageId; } /** * Загружает из БД список сохраненных точек телепортаций для телепортов в Community Board */ public void loadTeleportPoints() { if (!Config.ALLOW_CB_TELEPORT) return; CommunityTeleportDAO.getInstance().select(_player); } /** * Возвращает список сохраненных точек телепортации для телепортов в Community Board */ public LinkedHashMap<Integer, TeleportPoint> getTeleportPoints() { return _teleportPoints; } /** * Загружает из БД список сохраненных групп баффов для использования в Community Board */ public void loadBufferGroups() { if (!Config.ALLOW_CB_BUFFER || !Config.CB_BUFFER_ALLOW_CUSTOM_GROUPS) return; CommunityBufferDAO.getInstance().selectGroups(_player); if (_bufferGroups != null && _bufferGroups.size() > 0) for (int groupId : _bufferGroups.keySet()) CommunityBufferDAO.getInstance().selectSkills(_player, groupId); } /** * Возвращает список сохраненных групп баффов для использования в Community Board */ public LinkedHashMap<Integer, BufferGroup> getBufferGroups() { return _bufferGroups; } /** * Загружает из БД список сохраненных сcылок для раздела "Избранное" Community Board */ public void loadFavoriteLinks() { if (!Config.ALLOW_CB_FAVORITE) return; CommunityFavoritesDAO.getInstance().select(_player); } /** * Возвращает список сохраненных ссылок в разделе "Избранное" Community Board */ public LinkedHashMap<Integer, FavoriteLink> getFavoriteLinks() { return _favoriteLinks; } } Изменено 1 мая, 2014 пользователем Gaikotsu 3 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты