/* * This file is part of the OdinMS Maple Story Server Copyright (C) 2008 ~ 2010 * Patrick Huy <patrick.huy@frz.cc> Matthias Butz <matze@odinms.de> Jan * Christian Meyer <vimes@odinms.de> * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License version 3 as published by * the Free Software Foundation. You may not use, modify or distribute this * program under any other version of the GNU Affero General Public License. * * This program 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 Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package javastory.channel.client; import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import java.util.Map.Entry; import javastory.client.GameClient; import javastory.db.Database; import javastory.game.GameConstants; import javastory.game.data.ItemInfoProvider; import javastory.io.PacketBuilder; import javastory.tools.packets.MonsterBookPacket; import com.google.common.collect.Maps; public class MonsterBook implements Serializable { private static final long serialVersionUID = 7179541993413738569L; private boolean changed = false; private int specialCardCount = 0, normalCardCount = 0, bookLevel = 1; private final Map<Integer, Integer> cards = Maps.newLinkedHashMap(); public final int getTotalCards() { return this.specialCardCount + this.normalCardCount; } public static MonsterBook loadFromDb(final int characterId) throws SQLException { final Connection connection = Database.getConnection(); final MonsterBook instance = new MonsterBook(); try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM monsterbook WHERE charid = ? ORDER BY cardid ASC")) { ps.setInt(1, characterId); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { final int cardId = rs.getInt("cardid"); final int level = rs.getInt("level"); if (GameConstants.isSpecialCard(cardId)) { instance.specialCardCount += level; } else { instance.normalCardCount += level; } instance.cards.put(cardId, level); } } } instance.calculateLevel(); return instance; } public final void saveCards(final int charid) throws SQLException { if (!this.changed || this.cards.isEmpty()) { return; } final Connection con = Database.getConnection(); PreparedStatement ps = con.prepareStatement("DELETE FROM monsterbook WHERE charid = ?"); ps.setInt(1, charid); ps.execute(); ps.close(); boolean first = true; final StringBuilder query = new StringBuilder(); for (final Entry<Integer, Integer> all : this.cards.entrySet()) { if (first) { first = false; query.append("INSERT INTO monsterbook VALUES (DEFAULT,"); } else { query.append(",(DEFAULT,"); } query.append(charid); query.append(","); query.append(all.getKey()); // Card ID query.append(","); query.append(all.getValue()); // Card level query.append(")"); } ps = con.prepareStatement(query.toString()); ps.execute(); ps.close(); } private void calculateLevel() { final int Size = this.normalCardCount + this.specialCardCount; this.bookLevel = 8; for (int i = 0; i < 8; i++) { if (Size <= GameConstants.getBookLevel(i)) { this.bookLevel = i + 1; break; } } } public final void addCardPacket(final PacketBuilder builder) { builder.writeAsShort(this.cards.size()); for (final Entry<Integer, Integer> all : this.cards.entrySet()) { builder.writeAsShort(GameConstants.getCardShortId(all.getKey())); // Id builder.writeAsByte(all.getValue()); // Level } } public final void addCharInfoPacket(final int bookcover, final PacketBuilder builder) { builder.writeInt(this.bookLevel); builder.writeInt(this.normalCardCount); builder.writeInt(this.specialCardCount); builder.writeInt(this.normalCardCount + this.specialCardCount); builder.writeInt(ItemInfoProvider.getInstance().getCardMobId(bookcover)); } public final void updateCard(final GameClient c, final int cardid) { c.write(MonsterBookPacket.changeCover(cardid)); } public final void addCard(final GameClient c, final int cardid) { this.changed = true; for (final Entry<Integer, Integer> all : this.cards.entrySet()) { if (all.getKey() == cardid) { if (all.getValue() >= 5) { c.write(MonsterBookPacket.addCard(true, cardid, all.getValue())); } else { c.write(MonsterBookPacket.addCard(false, cardid, all.getValue())); c.write(MonsterBookPacket.showGainCard(cardid)); all.setValue(all.getValue() + 1); this.calculateLevel(); } return; } } // New card this.cards.put(cardid, 1); c.write(MonsterBookPacket.addCard(false, cardid, 1)); c.write(MonsterBookPacket.showGainCard(cardid)); this.calculateLevel(); } }