Chronicle 4 branch.

This commit is contained in:
MobiusDev
2017-07-19 21:24:06 +00:00
parent 9a69bec286
commit 3a0bf3539a
13496 changed files with 641683 additions and 0 deletions

View File

@ -0,0 +1,323 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 com.l2jmobius.gameserver.cache;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.L2DatabaseFactory;
import com.l2jmobius.gameserver.datatables.ClanTable;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.model.L2Clan;
import javolution.util.FastMap;
/**
* @author Layane
*/
public class CrestCache
{
private static Logger _log = Logger.getLogger(CrestCache.class.getName());
private static CrestCache _instance;
private final FastMRUCache<Integer, byte[]> _cachePledge = new FastMRUCache<>();
private final FastMRUCache<Integer, byte[]> _cachePledgeLarge = new FastMRUCache<>();
private final FastMRUCache<Integer, byte[]> _cacheAlly = new FastMRUCache<>();
private int _loadedFiles;
private long _bytesBuffLen;
public static CrestCache getInstance()
{
if (_instance == null)
{
_instance = new CrestCache();
}
return _instance;
}
public CrestCache()
{
convertOldPledgeFiles();
reload();
}
public void reload()
{
final FileFilter filter = new BmpFilter();
final File dir = new File(Config.DATAPACK_ROOT, "data/crests/");
final File[] files = dir.listFiles(filter);
byte[] content;
synchronized (this)
{
_loadedFiles = 0;
_bytesBuffLen = 0;
_cachePledge.clear();
_cachePledgeLarge.clear();
_cacheAlly.clear();
}
final FastMap<Integer, byte[]> _mapPledge = _cachePledge.getContentMap();
final FastMap<Integer, byte[]> _mapPledgeLarge = _cachePledgeLarge.getContentMap();
final FastMap<Integer, byte[]> _mapAlly = _cacheAlly.getContentMap();
for (final File file : files)
{
synchronized (this)
{
try (RandomAccessFile f = new RandomAccessFile(file, "r"))
{
content = new byte[(int) f.length()];
f.readFully(content);
if (file.getName().startsWith("Crest_Large_"))
{
_mapPledgeLarge.put(Integer.valueOf(file.getName().substring(12, file.getName().length() - 4)), content);
}
else if (file.getName().startsWith("Crest_"))
{
_mapPledge.put(Integer.valueOf(file.getName().substring(6, file.getName().length() - 4)), content);
}
else if (file.getName().startsWith("AllyCrest_"))
{
_mapAlly.put(Integer.valueOf(file.getName().substring(10, file.getName().length() - 4)), content);
}
_loadedFiles++;
_bytesBuffLen += content.length;
}
catch (final Exception e)
{
_log.warning("problem with crest bmp file " + e);
}
}
}
_log.info("Cache[Crest]: " + String.format("%.3f", getMemoryUsage()) + "MB on " + getLoadedFiles() + " files loaded. (Forget Time: " + (_cachePledge.getForgetTime() / 1000) + "s , Capacity: " + _cachePledge.capacity() + ")");
}
public void convertOldPledgeFiles()
{
final File dir = new File(Config.DATAPACK_ROOT, "data/crests/");
final File[] files = dir.listFiles(new OldPledgeFilter());
for (final File file : files)
{
final int clanId = Integer.parseInt(file.getName().substring(7, file.getName().length() - 4));
_log.info("Found old crest file \"" + file.getName() + "\" for clanId " + clanId);
final int newId = IdFactory.getInstance().getNextId();
final L2Clan clan = ClanTable.getInstance().getClan(clanId);
if (clan != null)
{
removeOldPledgeCrest(clan.getCrestId());
file.renameTo(new File(Config.DATAPACK_ROOT, "data/crests/Crest_" + newId + ".bmp"));
_log.info("Renamed Clan crest to new format: Crest_" + newId + ".bmp");
try (Connection con = L2DatabaseFactory.getInstance().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 (final SQLException e)
{
_log.warning("could not update the crest id:" + e.getMessage());
}
clan.setCrestId(newId);
clan.setHasCrest(true);
}
else
{
_log.info("Clan Id: " + clanId + " does not exist in table.. deleting.");
file.delete();
}
}
}
public float getMemoryUsage()
{
return ((float) _bytesBuffLen / 1048576);
}
public int getLoadedFiles()
{
return _loadedFiles;
}
public byte[] getPledgeCrest(int id)
{
return _cachePledge.get(id);
}
public byte[] getPledgeCrestLarge(int id)
{
return _cachePledgeLarge.get(id);
}
public byte[] getAllyCrest(int id)
{
return _cacheAlly.get(id);
}
public void removePledgeCrest(int id)
{
final File crestFile = new File(Config.DATAPACK_ROOT, "data/crests/Crest_" + id + ".bmp");
_cachePledge.remove(id);
try
{
crestFile.delete();
}
catch (final Exception e)
{
}
}
public void removePledgeCrestLarge(int id)
{
final File crestFile = new File(Config.DATAPACK_ROOT, "data/crests/Crest_Large_" + id + ".bmp");
_cachePledgeLarge.remove(id);
try
{
crestFile.delete();
}
catch (final Exception e)
{
}
}
public void removeOldPledgeCrest(int id)
{
final File crestFile = new File(Config.DATAPACK_ROOT, "data/crests/Pledge_" + id + ".bmp");
try
{
crestFile.delete();
}
catch (final Exception e)
{
}
}
public void removeAllyCrest(int id)
{
final File crestFile = new File(Config.DATAPACK_ROOT, "data/crests/AllyCrest_" + id + ".bmp");
_cacheAlly.remove(id);
try
{
crestFile.delete();
}
catch (final Exception e)
{
}
}
public boolean savePledgeCrest(int newId, byte[] data)
{
final File crestFile = new File(Config.DATAPACK_ROOT, "data/crests/Crest_" + newId + ".bmp");
try (FileOutputStream out = new FileOutputStream(crestFile))
{
out.write(data);
_cachePledge.getContentMap().put(newId, data);
return true;
}
catch (final IOException e)
{
_log.log(Level.INFO, "Error saving pledge crest" + crestFile + ":", e);
return false;
}
}
public boolean savePledgeCrestLarge(int newId, byte[] data)
{
final File crestFile = new File(Config.DATAPACK_ROOT, "data/crests/Crest_Large_" + newId + ".bmp");
try (FileOutputStream out = new FileOutputStream(crestFile))
{
out.write(data);
_cachePledgeLarge.getContentMap().put(newId, data);
return true;
}
catch (final IOException e)
{
_log.log(Level.INFO, "Error saving Large pledge crest" + crestFile + ":", e);
return false;
}
}
public boolean saveAllyCrest(int newId, byte[] data)
{
final File crestFile = new File(Config.DATAPACK_ROOT, "data/crests/AllyCrest_" + newId + ".bmp");
try (FileOutputStream out = new FileOutputStream(crestFile))
{
out.write(data);
_cacheAlly.getContentMap().put(newId, data);
return true;
}
catch (final IOException e)
{
_log.log(Level.INFO, "Error saving ally crest" + crestFile + ":", e);
return false;
}
}
class BmpFilter implements FileFilter
{
@Override
public boolean accept(File file)
{
return (file.getName().endsWith(".bmp"));
}
}
class OldPledgeFilter implements FileFilter
{
@Override
public boolean accept(File file)
{
return (file.getName().startsWith("Pledge_"));
}
}
}

View File

@ -0,0 +1,227 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 com.l2jmobius.gameserver.cache;
import javolution.context.ObjectFactory;
import javolution.lang.Reusable;
import javolution.util.FastCollection;
import javolution.util.FastComparator;
import javolution.util.FastList;
import javolution.util.FastMap;
import javolution.util.FastMap.Entry;
/**
* @author Layane
* @param <K>
* @param <V>
*/
public class FastMRUCache<K, V>extends FastCollection<Object> implements Reusable
{
private static final long serialVersionUID = 1L;
public static final int DEFAULT_CAPACITY = 50;
public static final int DEFAULT_FORGET_TIME = 300000; // 5 Minutes
FastMap<K, CacheNode> _cache = new FastMap<K, CacheNode>().setKeyComparator(FastComparator.DIRECT);
FastMap<K, V> _map;
FastList<K> _mruList = new FastList<>();
int _cacheSize;
int _forgetTime;
class CacheNode
{
long lastModified;
V node;
public CacheNode(V object)
{
lastModified = System.currentTimeMillis();
node = object;
}
@Override
public boolean equals(Object object)
{
return node == object;
}
}
/**
* Holds the set factory.
*/
private static final ObjectFactory<?> FACTORY = new ObjectFactory<Object>()
{
@Override
public Object create()
{
return new FastMRUCache<>();
}
@Override
public void cleanup(Object obj)
{
((FastMRUCache<?, ?>) obj).reset();
}
};
/**
* Returns a set allocated from the stack when executing in a PoolContext}).
* @return a new, pre-allocated or recycled set instance.
*/
public static FastMRUCache<?, ?> newInstance()
{
return (FastMRUCache<?, ?>) FACTORY.object();
}
public FastMRUCache()
{
this(new FastMap<K, V>(), DEFAULT_CAPACITY, DEFAULT_FORGET_TIME);
}
public FastMRUCache(FastMap<K, V> map)
{
this(map, DEFAULT_CAPACITY, DEFAULT_FORGET_TIME);
}
public FastMRUCache(FastMap<K, V> map, int max)
{
this(map, max, DEFAULT_FORGET_TIME);
}
public FastMRUCache(FastMap<K, V> map, int max, int forgetTime)
{
_map = map;
_cacheSize = max;
_forgetTime = forgetTime;
_map.setKeyComparator(FastComparator.DIRECT);
}
// Implements Reusable.
@Override
public synchronized void reset()
{
_map.reset();
_cache.reset();
_mruList.reset();
_map.setKeyComparator(FastComparator.DIRECT);
_cache.setKeyComparator(FastComparator.DIRECT);
}
public synchronized V get(K key)
{
V result;
if (!_cache.containsKey(key))
{
if (_mruList.size() >= _cacheSize)
{
_cache.remove(_mruList.getLast());
_mruList.removeLast();
}
result = _map.get(key);
_cache.put(key, new CacheNode(result));
_mruList.addFirst(key);
}
else
{
final CacheNode current = _cache.get(key);
if ((current.lastModified + _forgetTime) <= System.currentTimeMillis())
{
current.lastModified = System.currentTimeMillis();
current.node = _map.get(key);
_cache.put(key, current);
}
_mruList.remove(key);
_mruList.addFirst(key);
result = current.node;
}
return result;
}
@Override
public synchronized boolean remove(Object key)
{
_cache.remove(key);
_mruList.remove(key);
return _map.remove(key) == key;
}
public FastMap<K, V> getContentMap()
{
return _map;
}
@Override
public int size()
{
return _mruList.size();
}
public int capacity()
{
return _cacheSize;
}
public int getForgetTime()
{
return _forgetTime;
}
@Override
public synchronized void clear()
{
_cache.clear();
_mruList.clear();
_map.clear();
}
// Implements FastCollection abstract method.
@Override
public final Record head()
{
return _mruList.head();
}
@Override
public final Record tail()
{
return _mruList.tail();
}
@Override
public final Object valueOf(Record record)
{
return ((Entry<?, ?>) record).getKey();
}
@Override
public final void delete(Record record)
{
remove(((Entry<?, ?>) record).getKey());
}
}

View File

@ -0,0 +1,222 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 com.l2jmobius.gameserver.cache;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.util.Util;
import javolution.util.FastMap;
/**
* @author Layane
*/
public class HtmCache
{
private static Logger _log = Logger.getLogger(HtmCache.class.getName());
private static HtmCache _instance;
private final FastMap<Integer, String> _cache;
private int _loadedFiles;
private long _bytesBuffLen;
public static HtmCache getInstance()
{
if (_instance == null)
{
_instance = new HtmCache();
}
return _instance;
}
public HtmCache()
{
_cache = new FastMap<>();
reload();
}
public void reload()
{
reload(Config.DATAPACK_ROOT);
}
public void reload(File f)
{
if (!Config.LAZY_CACHE)
{
_log.info("Html cache start...");
parseDir(f);
_log.info("Cache[HTML]: " + String.format("%.3f", getMemoryUsage()) + " megabytes on " + getLoadedFiles() + " files loaded");
}
else
{
_cache.clear();
_loadedFiles = 0;
_bytesBuffLen = 0;
_log.info("Cache[HTML]: Running lazy cache");
}
}
public void reloadPath(File f)
{
parseDir(f);
_log.info("Cache[HTML]: Reloaded specified path.");
}
public double getMemoryUsage()
{
return ((float) _bytesBuffLen / 1048576);
}
public int getLoadedFiles()
{
return _loadedFiles;
}
class HtmFilter implements FileFilter
{
@Override
public boolean accept(File file)
{
if (!file.isDirectory())
{
return (file.getName().endsWith(".htm") || file.getName().endsWith(".html"));
}
return true;
}
}
private void parseDir(File dir)
{
final FileFilter filter = new HtmFilter();
final File[] files = dir.listFiles(filter);
for (final File file : files)
{
if (!file.isDirectory())
{
loadFile(file);
}
else
{
parseDir(file);
}
}
}
public String loadFile(File file)
{
final HtmFilter filter = new HtmFilter();
if (file.exists() && filter.accept(file) && !file.isDirectory())
{
String content;
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis))
{
final int bytes = bis.available();
final byte[] raw = new byte[bytes];
bis.read(raw);
content = new String(raw, "UTF-8");
content.replaceAll("\r\n", "\n");
final String relpath = Util.getRelativePath(Config.DATAPACK_ROOT, file);
final int hashcode = relpath.hashCode();
final String oldContent = _cache.get(hashcode);
if (oldContent == null)
{
_bytesBuffLen += bytes;
_loadedFiles++;
}
else
{
_bytesBuffLen = (_bytesBuffLen - oldContent.length()) + bytes;
}
_cache.put(hashcode, content);
return content;
}
catch (final Exception e)
{
_log.warning("problem with htm file " + e);
}
}
return null;
}
public String getHtmForce(String path)
{
String content = getHtm(path);
if (content == null)
{
content = "<html><body>My text is missing:<br>" + path + "</body></html>";
_log.warning("Cache[HTML]: Missing HTML page: " + path);
}
return content;
}
public String getHtm(String path)
{
String content = _cache.get(path.hashCode());
if (Config.LAZY_CACHE && (content == null))
{
content = loadFile(new File(Config.DATAPACK_ROOT, path));
}
return content;
}
public boolean contains(String path)
{
return _cache.containsKey(path.hashCode());
}
/**
* Check if an HTM exists and can be loaded
* @param path The path to the HTM
* @return
*/
public boolean isLoadable(String path)
{
final File file = new File(path);
final HtmFilter filter = new HtmFilter();
if (file.exists() && filter.accept(file) && !file.isDirectory())
{
return true;
}
return false;
}
}

View File

@ -0,0 +1,76 @@
/*
* This file is part of the L2J Mobius project.
*
* 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 com.l2jmobius.gameserver.cache;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import javolution.util.FastMap;
/**
* @author -Nemesiss-
*/
public class WarehouseCacheManager
{
private static WarehouseCacheManager _instance;
protected final FastMap<L2PcInstance, Long> _CachedWh;
protected final long _CacheTime;
public static WarehouseCacheManager getInstance()
{
if (_instance == null)
{
_instance = new WarehouseCacheManager();
}
return _instance;
}
private WarehouseCacheManager()
{
_CacheTime = Config.WAREHOUSE_CACHE_TIME * 60 * 1000;
_CachedWh = new FastMap<L2PcInstance, Long>().shared();
ThreadPoolManager.getInstance().scheduleAiAtFixedRate(new CacheScheduler(), 120000, 60000);
}
public void addCacheTask(L2PcInstance pc)
{
_CachedWh.put(pc, System.currentTimeMillis());
}
public void remCacheTask(L2PcInstance pc)
{
_CachedWh.remove(pc);
}
public class CacheScheduler implements Runnable
{
@Override
public void run()
{
final long cTime = System.currentTimeMillis();
for (final L2PcInstance pc : _CachedWh.keySet())
{
if ((cTime - _CachedWh.get(pc)) > _CacheTime)
{
pc.clearWarehouse();
_CachedWh.remove(pc);
}
}
}
}
}