package org.skfiy.typhon.spi.role;
import java.util.Calendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import org.skfiy.typhon.domain.Player;
import org.skfiy.typhon.domain.RoleData;
import org.skfiy.typhon.session.Session;
import org.skfiy.typhon.session.SessionContext;
import org.skfiy.typhon.spi.store.StoreProvider;
import org.skfiy.util.CustomizableThreadCreator;
public class StoreDatable implements RoleDatable {
private static final String SESSION_SRT_KEY = "__store__refresh__task";
protected static final ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1, new ThreadFactory() {
CustomizableThreadCreator threadCreator = new CustomizableThreadCreator("refresh-store-timer-");
{
threadCreator.setThreadGroupName("Refresh-Store-ThreadGroup");
threadCreator.setDaemon(true);
}
@Override
public Thread newThread(Runnable r) {
return threadCreator.createThread(r);
}
});
@Inject
private StoreProvider storeProvider;
@Override
public void initialize(Player player) {
StoreRefreshTask srt = new StoreRefreshTask(player);
srt.run();
SessionContext.getSession().setAttribute(SESSION_SRT_KEY, srt);
}
@Override
public void serialize(Player player, RoleData roleData) {
}
@Override
public void deserialize(RoleData roleData, Player player) {
initialize(player);
}
private class StoreRefreshTask implements Runnable {
private final Player player;
StoreRefreshTask(Player player) {
this.player = player;
}
@Override
public void run() {
if (!player.getSession().isAvailable()) {
return;
}
boolean isRefresh;
long cdTime = 0;
Calendar nextRefreshTime0;
// 当前时间
Calendar curCal = Calendar.getInstance();
//上次自动刷新时间
Calendar lastCal = Calendar.getInstance();
lastCal.setTimeInMillis(getLastRefreshStoreTime());
//初始帐号
if (lastCal.getTimeInMillis() == 0) {
isRefresh = true;
} else {
//下次刷新时间点
nextRefreshTime0 = nextRefreshTime(getRefreshTimes(), lastCal.getTimeInMillis());
isRefresh = !(lastCal.get(Calendar.DAY_OF_YEAR) == curCal.get(Calendar.DAY_OF_YEAR));
if (nextRefreshTime0.getTimeInMillis() <= curCal.getTimeInMillis()) {
isRefresh = true;
} else {
cdTime = nextRefreshTime0.getTimeInMillis() - curCal.getTimeInMillis();
}
}
if (isRefresh) {
storeProvider.refreshCommodity(player);
nextRefreshTime0 = nextRefreshTime(getRefreshTimes(), curCal.getTimeInMillis());
cdTime = nextRefreshTime0.getTimeInMillis() - curCal.getTimeInMillis();
player.getNormal().setLastRefreshStoreTime(System.currentTimeMillis());
}
scheduler.schedule(new StoreRefreshTask(player), cdTime, TimeUnit.MILLISECONDS);
}
private List<Integer> getRefreshTimes() {
return storeProvider.getRefreshTimes();
}
private long getLastRefreshStoreTime() {
return player.getNormal().getLastRefreshStoreTime();
}
}
protected Calendar nextRefreshTime(List<Integer> refreshTimes, long lastTime) {
Calendar nextCal = Calendar.getInstance();
nextCal.setTimeInMillis(lastTime);
clearMSMS(nextCal);
int cur = nextCal.get(Calendar.HOUR_OF_DAY);
for (int i = 0; i < refreshTimes.size(); i++) {
if (cur < refreshTimes.get(i)) {
nextCal.set(Calendar.HOUR_OF_DAY, refreshTimes.get(i));
return nextCal;
}
if (i >= (refreshTimes.size() - 1)) {
nextCal.add(Calendar.DATE, 1);
nextCal.set(Calendar.HOUR_OF_DAY, refreshTimes.get(0));
}
}
return nextCal;
}
private void clearMSMS(Calendar c) {
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
}
}