/*
* This program 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. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If
* not, see <http://www.gnu.org/licenses/>.
*/
package silentium.gameserver.data.crest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import silentium.commons.database.DatabaseFactory;
import silentium.commons.io.filters.CustomFileNameFilter;
import silentium.gameserver.configs.MainConfig;
import silentium.gameserver.idfactory.IdFactory;
import silentium.gameserver.model.L2Clan;
import silentium.gameserver.tables.ClanTable;
import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import static silentium.commons.io.filters.FilterStrategy.STARTS_WITH;
import static silentium.gameserver.data.crest.CrestCache.CrestType.PLEDGE_OLD;
/**
* @author Layane, reworked by Java-man
*/
public class CrestCache {
private static final Logger log = LoggerFactory.getLogger(CrestCache.class);
private static final List<CrestData> cache = new ArrayList<>();
private static final String CRESTS_DIR = "data/crests/";
private static final File[] EMPTY_FILE_ARRAY = new File[0];
private static final FilenameFilter BMP_FILTER = CustomFileNameFilter.create().setPattern(".bmp");
private static final FilenameFilter OLD_PLEDGE_FILTER = CustomFileNameFilter.create().setStrategy(STARTS_WITH)
.setPattern("Pledge_");
public enum CrestType {
PLEDGE("Crest_"),
PLEDGE_LARGE("Crest_Large_"),
PLEDGE_OLD("Pledge_"),
ALLY("AllyCrest_");
private final String dirPrefix;
CrestType(final String dirPrefix) {
this.dirPrefix = dirPrefix;
}
public String getDirPrefix() {
return dirPrefix;
}
}
static {
if (!new File(CRESTS_DIR).mkdirs())
convertOldPledgeFiles();
}
public static void load() {
cache.clear();
File[] files = new File(MainConfig.DATAPACK_ROOT, CRESTS_DIR).listFiles(BMP_FILTER);
if (files == null)
files = EMPTY_FILE_ARRAY;
String fileName;
byte[] content;
CrestType crestType = null;
int crestId = 0;
for (final File file : files) {
fileName = file.getName();
try (RandomAccessFile f = new RandomAccessFile(file, "r")) {
content = new byte[(int) f.length()];
f.readFully(content);
for (final CrestType type : CrestType.values())
if (fileName.startsWith(type.getDirPrefix())) {
crestType = type;
crestId = getCrestIdFromFileName(fileName, type.getDirPrefix());
}
cache.add(new CrestData(crestType, crestId, content));
} catch (Exception e) {
log.warn("Problem with loading crest bmp file: " + file, e);
}
}
log.info("Cache[Crest]: " + cache.size() + " files loaded.");
}
public static void convertOldPledgeFiles() {
int clanId, newId;
L2Clan clan;
final File[] files = new File(MainConfig.DATAPACK_ROOT, CRESTS_DIR).listFiles(OLD_PLEDGE_FILTER);
for (final File file : files) {
clanId = getCrestIdFromFileName(file.getName(), PLEDGE_OLD.getDirPrefix());
newId = IdFactory.getInstance().getNextId();
clan = ClanTable.getInstance().getClan(clanId);
log.info("Found old crest file \"" + file.getName() + "\" for clanId " + clanId);
if (clan != null) {
removeCrest(CrestType.PLEDGE_LARGE, clan.getCrestId());
file.renameTo(new File(MainConfig.DATAPACK_ROOT, CRESTS_DIR + "Crest_" + newId + ".bmp"));
log.info("Renamed Clan crest to new format: Crest_" + newId + ".bmp");
try (Connection con = DatabaseFactory.getConnection();
PreparedStatement statement = con.prepareStatement("UPDATE clan_data SET crest_id = ? WHERE clan_id = ?")) {
statement.setInt(1, newId);
statement.setInt(2, clan.getClanId());
statement.executeUpdate();
} catch (SQLException e) {
log.warn("Could not update the crest id:", e);
}
clan.setCrestId(newId);
} else {
log.info("Clan Id: " + clanId + " does not exist in table.. deleting.");
file.delete();
}
}
}
public static byte[] getCrestHash(final CrestType crestType, final int id) {
for (final CrestData crest : cache)
if (crest.getCrestType() == crestType && crest.getCrestId() == id)
return crest.getHash();
return null;
}
public static void removeCrest(final CrestType crestType, final int id) {
final String crestDirPrefix = crestType.getDirPrefix();
if (!"Pledge_".equals(crestDirPrefix))
for (final CrestData crestData : cache)
if (crestData.getCrestType() == crestType && crestData.getCrestId() == id) {
cache.remove(crestData);
break;
}
final File crestFile = new File(MainConfig.DATAPACK_ROOT, CRESTS_DIR + crestDirPrefix + id + ".bmp");
try {
crestFile.delete();
} catch (Exception e) {
log.warn("", e);
}
}
public static boolean saveCrest(final CrestType crestType, final int newId, final byte[] data) {
final File crestFile = new File(MainConfig.DATAPACK_ROOT, CRESTS_DIR + crestType.getDirPrefix() + newId + ".bmp");
try (FileOutputStream out = new FileOutputStream(crestFile)) {
out.write(data);
cache.add(new CrestData(crestType, newId, data));
return true;
} catch (IOException e) {
log.info("Error saving pledge crest" + crestFile + ':', e);
return false;
}
}
public static int getCrestIdFromFileName(final String fileName, final String dirPrefix) {
return Integer.valueOf(fileName.substring(dirPrefix.length(), fileName.length() - 4));
}
private static class CrestData {
private final CrestType crestType;
private final int crestId;
private final byte[] hash;
CrestData(final CrestType crestType, final int crestId, final byte[] hash) {
this.crestType = crestType;
this.crestId = crestId;
this.hash = hash;
}
public CrestType getCrestType() {
return crestType;
}
public int getCrestId() {
return crestId;
}
public byte[] getHash() {
return hash;
}
}
}