package scripting.event;
import client.MapleCharacter;
import handling.channel.ChannelServer;
import handling.world.party.MapleParty;
import handling.world.party.MaplePartyCharacter;
import java.util.*;
import java.util.concurrent.ScheduledFuture;
import javax.script.Invocable;
import javax.script.ScriptException;
import org.apache.log4j.Logger;
import server.Randomizer;
import server.Timer.EventTimer;
import server.events.MapleEvent;
import server.events.MapleEventType;
import server.life.MapleLifeFactory;
import server.life.MapleMonster;
import server.life.OverrideMonsterStats;
import server.maps.MapleMap;
import server.maps.MapleMapFactory;
import server.maps.MapleMapObject;
import server.maps.MapleReactor;
import server.maps.MapleReactorFactory;
import server.squad.MapleSquad;
import tools.FileoutputUtil;
import tools.MaplePacketCreator;
public class EventManager {
private static final int[] eventChannel = new int[2];
private final Invocable iv;
private final int channel;
private final Map<String, EventInstanceManager> instances = new WeakHashMap();
private final Properties props = new Properties();
private final String name;
private static final Logger log = Logger.getLogger(EventManager.class);
public EventManager(ChannelServer cserv, Invocable iv, String name) {
this.iv = iv;
this.channel = cserv.getChannel();
this.name = name;
}
public void cancel() {
try {
this.iv.invokeFunction("cancelSchedule", new Object[]{(Object) null});
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : cancelSchedule:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : cancelSchedule:\r\n").append(ex).toString());
}
}
public ScheduledFuture<?> schedule(final String methodName, long delay) {
return EventTimer.getInstance().schedule(new Runnable() {
@Override
public void run() {
try {
EventManager.this.iv.invokeFunction(methodName, new Object[]{(Object) null});
} catch (ScriptException | NoSuchMethodException ex) {
EventManager.log.error("Event name : " + EventManager.this.name + ", method Name : " + methodName + ":\r\n" + ex);
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, "Event name : " + EventManager.this.name + ", method Name : " + methodName + ":\r\n" + ex);
}
}
}, delay);
}
public ScheduledFuture<?> schedule(final String methodName, long delay, final EventInstanceManager eim) {
return EventTimer.getInstance().schedule(new Runnable() {
@Override
public void run() {
try {
EventManager.this.iv.invokeFunction(methodName, new Object[]{eim});
} catch (ScriptException | NoSuchMethodException ex) {
EventManager.log.error("Event name : " + EventManager.this.name + ", method Name : " + methodName + ":\r\n" + ex);
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, "Event name : " + EventManager.this.name + ", method Name : " + methodName + ":\r\n" + ex);
}
}
}, delay);
}
public ScheduledFuture<?> scheduleAtTimestamp(final String methodName, long timestamp) {
return EventTimer.getInstance().scheduleAtTimestamp(new Runnable() {
@Override
public void run() {
try {
EventManager.this.iv.invokeFunction(methodName, new Object[]{(Object) null});
} catch (ScriptException | NoSuchMethodException ex) {
EventManager.log.error("Event name : " + EventManager.this.name + ", method Name : " + methodName + ":\r\n" + ex);
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, "Event name : " + EventManager.this.name + ", method Name : " + methodName + ":\r\n" + ex);
}
}
}, timestamp);
}
public int getCurentMin(){
Calendar cal = Calendar.getInstance();
return cal.get(12);
}
public void log(String str){
FileoutputUtil.log(str);
}
public int getChannel() {
return this.channel;
}
public ChannelServer getChannelServer() {
return ChannelServer.getInstance(this.channel);
}
public EventInstanceManager getInstance(String name) {
return (EventInstanceManager) this.instances.get(name);
}
public Collection<EventInstanceManager> getInstances() {
return Collections.unmodifiableCollection(this.instances.values());
}
/**
* 创建一个实例
* @param name
* @return
*/
public EventInstanceManager newInstance(String name) {
EventInstanceManager ret = new EventInstanceManager(this, name, this.channel);
this.instances.put(name, ret);
return ret;
}
public void disposeInstance(String name) {
this.instances.remove(name);
if ((getProperty("state") != null) && (this.instances.isEmpty())) {
setProperty("state", "0");
}
if ((getProperty("leader") != null) && (this.instances.isEmpty()) && (getProperty("leader").equals("false"))) {
setProperty("leader", "true");
}
if (this.name.equals("CWKPQ")) {
MapleSquad squad = ChannelServer.getInstance(this.channel).getMapleSquad("CWKPQ");
if (squad != null) {
squad.clear();
squad.copy();
}
}
}
public Invocable getIv() {
return this.iv;
}
public void setProperty(String key, String value) {
this.props.setProperty(key, value);
}
public String getProperty(String key) {
return this.props.getProperty(key);
}
public final Properties getProperties() {
return this.props;
}
public String getName() {
return this.name;
}
public void startInstance() {
try {
this.iv.invokeFunction("setup", new Object[]{(Object) null});
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
}
}
public void startInstance_Solo(String mapid, MapleCharacter chr) {
try {
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{mapid});
eim.registerPlayer(chr);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
}
}
public void startInstance(String mapid, MapleCharacter chr) {
try {
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{mapid});
eim.registerCarnivalParty(chr, chr.getMap(), (byte) 0);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
}
}
public void startInstance_Party(String mapid, MapleCharacter chr, int maxlevel) {
try {
int averageLevel = 0;
int size = 0;
for (MaplePartyCharacter mpc : chr.getParty().getMembers()) {
if (mpc.isOnline() && mpc.getMapid() == chr.getMap().getId() && mpc.getChannel() == chr.getMap().getChannel()) {
averageLevel += mpc.getLevel();
size++;
}
}
if (size <= 0) {
return;
}
averageLevel /= size;
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{mapid, Math.min(maxlevel, averageLevel <= 0 ? chr.getLevel() : averageLevel)});
eim.registerParty(chr.getParty(), chr.getMap());
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
}
}
public void startInstance_Party(String mapid, MapleCharacter chr) {
try {
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{mapid});
eim.registerParty(chr.getParty(), chr.getMap());
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup:\r\n").append(ex).toString());
}
}
public void startInstance(MapleCharacter character, String leader) {
try {
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{(Object) null});
eim.registerPlayer(character);
eim.setProperty("leader", leader);
eim.setProperty("guildid", String.valueOf(character.getGuildId()));
setProperty("guildid", String.valueOf(character.getGuildId()));
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-Guild:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-Guild:\r\n").append(ex).toString());
}
}
public void startInstance_CharID(MapleCharacter character) {
try {
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{character.getId()});
eim.registerPlayer(character);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-CharID:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-CharID:\r\n").append(ex).toString());
}
}
public void startInstance_CharMapID(MapleCharacter character) {
try {
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{character.getId(), character.getMapId()});
eim.registerPlayer(character);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-CharID:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-CharID:\r\n").append(ex).toString());
}
}
public void startInstance(MapleCharacter character) {
try {
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{(Object) null});
eim.registerPlayer(character);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-character:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-character:\r\n").append(ex).toString());
}
}
public void startInstance(MapleParty party, MapleMap map) {
startInstance(party, map, 255);
}
public void startInstance(MapleParty party, MapleMap map, int maxLevel) {
try {
int averageLevel = 0;
int size = 0;
for (MaplePartyCharacter mpc : party.getMembers()) {
if (mpc.isOnline() && mpc.getMapid() == map.getId() && mpc.getChannel() == map.getChannel()) {
averageLevel += mpc.getLevel();
size++;
}
}
if (size <= 0) {
return;
}
averageLevel /= size;
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{Math.min(maxLevel, averageLevel), party.getId()});
eim.registerParty(party, map);
} catch (ScriptException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-partyid:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-partyid:\r\n").append(ex).toString());
} catch (NoSuchMethodException ex) {
startInstance_NoID(party, map, ex);
}
}
public void startInstance_NoID(MapleParty party, MapleMap map) {
startInstance_NoID(party, map, null);
}
public void startInstance_NoID(MapleParty party, MapleMap map, Exception old) {
try {
EventInstanceManager eim = (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{(Object) null});
eim.registerParty(party, map);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-party:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-party:\r\n").append(ex).append("\r\n").append(old == null ? "no old exception" : old).toString());
}
}
public void startInstance(EventInstanceManager eim, String leader) {
try {
this.iv.invokeFunction("setup", new Object[]{eim});
eim.setProperty("leader", leader);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-leader:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-leader:\r\n").append(ex).toString());
}
}
public void startInstance(MapleSquad squad, MapleMap map) {
startInstance(squad, map, -1);
}
public void startInstance(MapleSquad squad, MapleMap map, int questID) {
if (squad.getStatus() == 0) {
return;
}
if (!squad.getLeader().isGM()) {
int mapid = map.getId();
int chrSize = 0;
for (String chr : squad.getMembers()) {
MapleCharacter player = squad.getChar(chr);
if ((player != null) && (player.getMapId() == mapid)) {
chrSize++;
}
}
if (chrSize < squad.getType().i) {
squad.getLeader().dropMessage(5, new StringBuilder().append("远征队中人员少于 ").append(squad.getType().i).append(" 人,无法开始远征任务。注意必须队伍中的角色在线且在同一地图。当前人数: ").append(chrSize).toString());
return;
}
if ((this.name.equals("CWKPQ")) && (squad.getJobs().size() < 5)) {
squad.getLeader().dropMessage(5, "远征队中成员职业的类型小于5种,无法开始远征任务。");
return;
}
}
try {
EventInstanceManager eim = (EventInstanceManager) (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{squad.getLeaderName()});
eim.registerSquad(squad, map, questID);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-squad:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-squad:\r\n").append(ex).toString());
}
}
public void startInstance(MapleSquad squad, MapleMap map, String bossid) {
startInstance(squad, map, bossid, true);
}
public void startInstance(MapleSquad squad, MapleMap map, String bossid, boolean checkSize) {
if (squad.getStatus() == 0) {
return;
}
if ((!squad.getLeader().isGM()) && (checkSize)) {
int mapid = map.getId();
int chrSize = 0;
for (String chr : squad.getMembers()) {
MapleCharacter player = squad.getChar(chr);
if ((player != null) && (player.getMapId() == mapid)) {
chrSize++;
}
}
if (chrSize < squad.getType().i) {
squad.getLeader().dropMessage(5, new StringBuilder().append("远征队中人员少于 ").append(squad.getType().i).append(" 人,无法开始远征任务。注意必须队伍中的角色在线且在同一地图。当前人数: ").append(chrSize).toString());
return;
}
if ((this.name.equals("CWKPQ")) && (squad.getJobs().size() < 5)) {
squad.getLeader().dropMessage(5, "远征队中成员职业的类型小于5种,无法开始远征任务。");
return;
}
}
try {
EventInstanceManager eim = (EventInstanceManager) (EventInstanceManager) this.iv.invokeFunction("setup", new Object[]{squad.getLeaderName()});
eim.registerSquad(squad, map, bossid);
} catch (ScriptException | NoSuchMethodException ex) {
log.error(new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-squad:\r\n").append(ex).toString());
FileoutputUtil.log(FileoutputUtil.Event_ScriptEx_Log, new StringBuilder().append("Event name : ").append(this.name).append(", method Name : setup-squad:\r\n").append(ex).toString());
}
}
public void warpAllPlayer(int from, int to) {
MapleMap tomap = getMapFactory().getMap(to);
MapleMap frommap = getMapFactory().getMap(from);
List<MapleCharacter> list = frommap.getCharactersThreadsafe();
if ((tomap != null) && (list != null) && (frommap.getCharactersSize() > 0)) {
for (MapleMapObject mmo : list) {
((MapleCharacter) mmo).changeMap(tomap, tomap.getPortal(0));
}
}
}
public MapleMapFactory getMapFactory() {
return getChannelServer().getMapFactory();
}
public OverrideMonsterStats newMonsterStats() {
return new OverrideMonsterStats();
}
public List<MapleCharacter> newCharList() {
return new ArrayList();
}
public MapleMonster getMonster(int id) {
return MapleLifeFactory.getMonster(id);
}
public MapleReactor getReactor(int id) {
return new MapleReactor(MapleReactorFactory.getReactor(id), id);
}
public byte[] sendBoat(boolean isEnter){
return MaplePacketCreator.boatPacket(isEnter);
}
public byte[] sendMonsterBoat(boolean isEnter){return MaplePacketCreator.MonsterBoat(isEnter);}
public byte[] musicChange(String name){
return MaplePacketCreator.musicChange(name);
}
public void broadcastYellowMsg(String msg) {
getChannelServer().broadcastPacket(MaplePacketCreator.yellowChat(msg));
}
public void broadcastServerMsg(String msg) {
getChannelServer().broadcastPacket(MaplePacketCreator.serverNotice(6, msg));
}
public void broadcastServerMsg(int type, String msg, boolean weather) {
if (!weather) {
getChannelServer().broadcastPacket(MaplePacketCreator.serverNotice(type, msg));
} else {
for (MapleMap load : getMapFactory().getAllMaps()) {
if (load.getCharactersSize() > 0) {
load.startMapEffect(msg, type);
}
}
}
}
public boolean scheduleRandomEvent() {
boolean omg = false;
for (int i = 0; i < eventChannel.length; i++) {
omg |= scheduleRandomEventInChannel(eventChannel[i]);
}
return omg;
}
public boolean scheduleRandomEventInChannel(int chz) {
final ChannelServer cs = ChannelServer.getInstance(chz);
if ((cs == null) || (cs.getEvent() > -1)) {
return false;
}
MapleEventType t = null;
while (t == null) {
for (MapleEventType x : MapleEventType.values()) {
if ((Randomizer.nextInt(MapleEventType.values().length) == 0) && (x != MapleEventType.OxQuiz)) {
t = x;
break;
}
}
}
String msg = MapleEvent.scheduleEvent(t, cs);
if (msg.length() > 0) {
broadcastYellowMsg(msg);
return false;
}
EventTimer.getInstance().schedule(new Runnable() {
@Override
public void run() {
if (cs.getEvent() >= 0) {
MapleEvent.setEvent(cs, true);
}
}
}, 180000L);
return true;
}
public void setWorldEvent() {
for (int i = 0; i < eventChannel.length; i++) {
eventChannel[i] = (Randomizer.nextInt(ChannelServer.getAllInstances().size() - 4) + 2 + i);
}
}
}