Reformat and clean up "scripting" package

This commit is contained in:
P0nk
2021-09-09 23:26:45 +02:00
parent 9b1dc76854
commit d389665bd7
18 changed files with 3636 additions and 3568 deletions

View File

@@ -54,7 +54,6 @@ import java.util.logging.Logger;
//import jdk.nashorn.api.scripting.ScriptUtils;
/**
*
* @author Matze
* @author Ronan
*/
@@ -63,59 +62,61 @@ public class EventManager {
private Channel cserv;
private World wserv;
private Server server;
private EventScriptScheduler ess = new EventScriptScheduler();
private Map<String, EventInstanceManager> instances = new HashMap<>();
private Map<String, Integer> instanceLocks = new HashMap<>();
private final EventScriptScheduler ess = new EventScriptScheduler();
private final Map<String, EventInstanceManager> instances = new HashMap<>();
private final Map<String, Integer> instanceLocks = new HashMap<>();
private final Queue<Integer> queuedGuilds = new LinkedList<>();
private final Map<Integer, Integer> queuedGuildLeaders = new HashMap<>();
private List<Boolean> openedLobbys;
private List<EventInstanceManager> readyInstances = new LinkedList<>();
private final List<Boolean> openedLobbys;
private final List<EventInstanceManager> readyInstances = new LinkedList<>();
private Integer readyId = 0, onLoadInstances = 0;
private Properties props = new Properties();
private String name;
private final Properties props = new Properties();
private final String name;
private MonitoredReentrantLock lobbyLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EM_LOBBY);
private MonitoredReentrantLock queueLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EM_QUEUE);
private MonitoredReentrantLock startLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EM_START);
private Set<Integer> playerPermit = new HashSet<>();
private Semaphore startSemaphore = new Semaphore(7);
private final Set<Integer> playerPermit = new HashSet<>();
private final Semaphore startSemaphore = new Semaphore(7);
private static final int maxLobbys = 8; // an event manager holds up to this amount of concurrent lobbys
public EventManager(Channel cserv, Invocable iv, String name) {
this.server = Server.getInstance();
this.iv = iv;
this.cserv = cserv;
this.wserv = server.getWorld(cserv.getWorld());
this.name = name;
this.openedLobbys = new ArrayList<>();
for(int i = 0; i < maxLobbys; i++) this.openedLobbys.add(false);
for (int i = 0; i < maxLobbys; i++) {
this.openedLobbys.add(false);
}
}
private boolean isDisposed() {
return onLoadInstances <= -1000;
}
public void cancel() { // make sure to only call this when there are NO PLAYERS ONLINE to mess around with the event manager!
ess.dispose();
try {
iv.invokeFunction("cancelSchedule", (Object) null);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
Collection<EventInstanceManager> eimList;
synchronized(instances) {
synchronized (instances) {
eimList = getInstances();
instances.clear();
}
for(EventInstanceManager eim : eimList) {
for (EventInstanceManager eim : eimList) {
eim.dispose(true);
}
List<EventInstanceManager> readyEims;
queueLock.lock();
try {
@@ -125,24 +126,24 @@ public class EventManager {
} finally {
queueLock.unlock();
}
for(EventInstanceManager eim : readyEims) {
for (EventInstanceManager eim : readyEims) {
eim.dispose(true);
}
props.clear();
cserv = null;
wserv = null;
server = null;
iv = null;
disposeLocks();
}
private void disposeLocks() {
LockCollector.getInstance().registerDisposeAction(() -> emptyLocks());
}
private void emptyLocks() {
lobbyLock = lobbyLock.dispose();
queueLock = queueLock.dispose();
@@ -158,11 +159,11 @@ public class EventManager {
return intList;
}
public long getLobbyDelay() {
return YamlConfig.config.server.EVENT_LOBBY_DELAY;
}
private int getMaxLobbies() {
try {
return (int) iv.invokeFunction("getMaxLobbies");
@@ -183,9 +184,9 @@ public class EventManager {
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex);
}
};
ess.registerEntry(r, delay);
// hate to do that, but those schedules can still be cancelled, so well... Let GC do it's job
return new EventScheduledFuture(r, ess);
}
@@ -198,7 +199,7 @@ public class EventManager {
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex);
}
};
ess.registerEntry(r, timestamp - server.getCurrentTime());
return new EventScheduledFuture(r, ess);
}
@@ -206,11 +207,11 @@ public class EventManager {
public World getWorldServer() {
return wserv;
}
public Channel getChannelServer() {
return cserv;
}
public Invocable getIv() {
return iv;
}
@@ -227,31 +228,31 @@ public class EventManager {
public EventInstanceManager newInstance(String name) throws EventInstanceInProgressException {
EventInstanceManager ret = getReadyInstance();
if(ret == null) {
if (ret == null) {
ret = new EventInstanceManager(this, name);
} else {
ret.setName(name);
}
synchronized (instances) {
if (instances.containsKey(name)) {
throw new EventInstanceInProgressException(name, this.getName());
}
instances.put(name, ret);
}
return ret;
}
public Marriage newMarriage(String name) throws EventInstanceInProgressException {
Marriage ret = new Marriage(this, name);
synchronized (instances) {
if (instances.containsKey(name)) {
throw new EventInstanceInProgressException(name, this.getName());
}
instances.put(name, ret);
}
return ret;
@@ -270,11 +271,11 @@ public class EventManager {
public void setProperty(String key, String value) {
props.setProperty(key, value);
}
public void setIntProperty(String key, int value) {
setProperty(key, value);
}
public void setProperty(String key, int value) {
props.setProperty(key, value + "");
}
@@ -282,11 +283,11 @@ public class EventManager {
public String getProperty(String key) {
return props.getProperty(key);
}
public int getIntProperty(String key) {
return Integer.parseInt(props.getProperty(key));
}
private void setLockLobby(int lobbyId, boolean lock) {
lobbyLock.lock();
try {
@@ -295,7 +296,7 @@ public class EventManager {
lobbyLock.unlock();
}
}
private boolean startLobbyInstance(int lobbyId) {
lobbyLock.lock();
try {
@@ -304,24 +305,28 @@ public class EventManager {
} else if (lobbyId >= maxLobbys) {
lobbyId = maxLobbys - 1;
}
if(!openedLobbys.get(lobbyId)) {
if (!openedLobbys.get(lobbyId)) {
openedLobbys.set(lobbyId, true);
return true;
}
return false;
} finally {
lobbyLock.unlock();
}
}
private void freeLobbyInstance(String lobbyName) {
Integer i = instanceLocks.get(lobbyName);
if(i == null) return;
if (i == null) {
return;
}
instanceLocks.remove(lobbyName);
if(i > -1) setLockLobby(i, false);
if (i > -1) {
setLockLobby(i, false);
}
}
public String getName() {
@@ -341,62 +346,67 @@ public class EventManager {
return -1;
}
private String getInternalScriptExceptionMessage(Throwable a) {
if (!(a instanceof ScriptException)) {
return null;
}
while(true) {
while (true) {
Throwable t = a;
a = a.getCause();
if (a == null) {
return t.getMessage();
}
}
}
private EventInstanceManager createInstance(String name, Object... args) throws ScriptException, NoSuchMethodException {
return (EventInstanceManager) iv.invokeFunction(name, args);
}
private void registerEventInstance(String eventName, int lobbyId) {
Integer oldLobby = instanceLocks.get(eventName);
if (oldLobby != null) {
setLockLobby(oldLobby, false);
}
instanceLocks.put(eventName, lobbyId);
}
public boolean startInstance(Expedition exped) {
return startInstance(-1, exped);
}
public boolean startInstance(int lobbyId, Expedition exped) {
return startInstance(lobbyId, exped, exped.getLeader());
}
//Expedition method: starts an expedition
public boolean startInstance(int lobbyId, Expedition exped, Character leader) {
if (this.isDisposed()) return false;
if (this.isDisposed()) {
return false;
}
try {
if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
playerPermit.add(leader.getId());
startLock.lock();
try {
try {
if(lobbyId == -1) {
if (lobbyId == -1) {
lobbyId = availableLobbyInstance();
if(lobbyId == -1) return false;
if (lobbyId == -1) {
return false;
}
} else {
if (!startLobbyInstance(lobbyId)) {
return false;
}
}
else {
if(!startLobbyInstance(lobbyId)) return false;
}
EventInstanceManager eim;
try {
eim = createInstance("setup", leader.getClient().getChannel());
@@ -406,13 +416,13 @@ public class EventManager {
if (message != null && !message.startsWith(EventInstanceInProgressException.EIIP_KEY)) {
throw e;
}
if(lobbyId > -1) {
if (lobbyId > -1) {
setLockLobby(lobbyId, false);
}
return false;
}
eim.setLeader(leader);
exped.start();
@@ -430,10 +440,10 @@ public class EventManager {
startSemaphore.release();
}
}
} catch(InterruptedException ie) {
} catch (InterruptedException ie) {
playerPermit.remove(leader.getId());
}
return false;
}
@@ -441,33 +451,34 @@ public class EventManager {
public boolean startInstance(Character chr) {
return startInstance(-1, chr);
}
public boolean startInstance(int lobbyId, Character leader) {
return startInstance(lobbyId, leader, leader, 1);
}
public boolean startInstance(int lobbyId, Character chr, Character leader, int difficulty) {
if (this.isDisposed()) return false;
if (this.isDisposed()) {
return false;
}
try {
if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
playerPermit.add(leader.getId());
startLock.lock();
try {
try {
if(lobbyId == -1) {
if (lobbyId == -1) {
lobbyId = availableLobbyInstance();
if(lobbyId == -1) {
if (lobbyId == -1) {
return false;
}
} else {
if (!startLobbyInstance(lobbyId)) {
return false;
}
}
else {
if(!startLobbyInstance(lobbyId)) {
return false;
}
}
EventInstanceManager eim;
try {
eim = createInstance("setup", difficulty, (lobbyId > -1) ? lobbyId : leader.getId());
@@ -477,15 +488,17 @@ public class EventManager {
if (message != null && !message.startsWith(EventInstanceInProgressException.EIIP_KEY)) {
throw e;
}
if(lobbyId > -1) {
if (lobbyId > -1) {
setLockLobby(lobbyId, false);
}
return false;
}
eim.setLeader(leader);
if(chr != null) eim.registerPlayer(chr);
if (chr != null) {
eim.registerPlayer(chr);
}
eim.startEvent();
} catch (ScriptException | NoSuchMethodException ex) {
@@ -499,40 +512,45 @@ public class EventManager {
startSemaphore.release();
}
}
} catch(InterruptedException ie) {
} catch (InterruptedException ie) {
playerPermit.remove(leader.getId());
}
return false;
}
}
//PQ method: starts a PQ
public boolean startInstance(Party party, MapleMap map) {
return startInstance(-1, party, map);
}
public boolean startInstance(int lobbyId, Party party, MapleMap map) {
return startInstance(lobbyId, party, map, party.getLeader().getPlayer());
}
public boolean startInstance(int lobbyId, Party party, MapleMap map, Character leader) {
if (this.isDisposed()) return false;
if (this.isDisposed()) {
return false;
}
try {
if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
playerPermit.add(leader.getId());
startLock.lock();
try {
try {
if(lobbyId == -1) {
if (lobbyId == -1) {
lobbyId = availableLobbyInstance();
if(lobbyId == -1) return false;
if (lobbyId == -1) {
return false;
}
} else {
if (!startLobbyInstance(lobbyId)) {
return false;
}
}
else {
if(!startLobbyInstance(lobbyId)) return false;
}
EventInstanceManager eim;
try {
eim = createInstance("setup", (Object) null);
@@ -542,13 +560,13 @@ public class EventManager {
if (message != null && !message.startsWith(EventInstanceInProgressException.EIIP_KEY)) {
throw e;
}
if(lobbyId > -1) {
if (lobbyId > -1) {
setLockLobby(lobbyId, false);
}
return false;
}
eim.setLeader(leader);
eim.registerParty(party, map);
@@ -566,40 +584,45 @@ public class EventManager {
startSemaphore.release();
}
}
} catch(InterruptedException ie) {
} catch (InterruptedException ie) {
playerPermit.remove(leader.getId());
}
return false;
}
//PQ method: starts a PQ with a difficulty level, requires function setup(difficulty, leaderid) instead of setup()
public boolean startInstance(Party party, MapleMap map, int difficulty) {
return startInstance(-1, party, map, difficulty);
}
public boolean startInstance(int lobbyId, Party party, MapleMap map, int difficulty) {
return startInstance(lobbyId, party, map, difficulty, party.getLeader().getPlayer());
}
public boolean startInstance(int lobbyId, Party party, MapleMap map, int difficulty, Character leader) {
if (this.isDisposed()) return false;
if (this.isDisposed()) {
return false;
}
try {
if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
playerPermit.add(leader.getId());
startLock.lock();
try {
try {
if(lobbyId == -1) {
if (lobbyId == -1) {
lobbyId = availableLobbyInstance();
if(lobbyId == -1) return false;
if (lobbyId == -1) {
return false;
}
} else {
if (!startLobbyInstance(lobbyId)) {
return false;
}
}
else {
if(!startLobbyInstance(lobbyId)) return false;
}
EventInstanceManager eim;
try {
eim = createInstance("setup", difficulty, (lobbyId > -1) ? lobbyId : party.getLeaderId());
@@ -609,13 +632,13 @@ public class EventManager {
if (message != null && !message.startsWith(EventInstanceInProgressException.EIIP_KEY)) {
throw e;
}
if(lobbyId > -1) {
if (lobbyId > -1) {
setLockLobby(lobbyId, false);
}
return false;
}
eim.setLeader(leader);
eim.registerParty(party, map);
@@ -633,10 +656,10 @@ public class EventManager {
startSemaphore.release();
}
}
} catch(InterruptedException ie) {
} catch (InterruptedException ie) {
playerPermit.remove(leader.getId());
}
return false;
}
@@ -644,35 +667,40 @@ public class EventManager {
public boolean startInstance(EventInstanceManager eim, String ldr) {
return startInstance(-1, eim, ldr);
}
public boolean startInstance(EventInstanceManager eim, Character ldr) {
return startInstance(-1, eim, ldr.getName(), ldr);
}
public boolean startInstance(int lobbyId, EventInstanceManager eim, String ldr) {
return startInstance(-1, eim, ldr, eim.getEm().getChannelServer().getPlayerStorage().getCharacterByName(ldr)); // things they make me do...
}
public boolean startInstance(int lobbyId, EventInstanceManager eim, String ldr, Character leader) {
if (this.isDisposed()) return false;
if (this.isDisposed()) {
return false;
}
try {
if(!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
if (!playerPermit.contains(leader.getId()) && startSemaphore.tryAcquire(7777, TimeUnit.MILLISECONDS)) {
playerPermit.add(leader.getId());
startLock.lock();
try {
try {
if(lobbyId == -1) {
if (lobbyId == -1) {
lobbyId = availableLobbyInstance();
if(lobbyId == -1) return false;
}
else {
if(!startLobbyInstance(lobbyId)) return false;
if (lobbyId == -1) {
return false;
}
} else {
if (!startLobbyInstance(lobbyId)) {
return false;
}
}
if(eim == null) {
if(lobbyId > -1) {
if (eim == null) {
if (lobbyId > -1) {
setLockLobby(lobbyId, false);
}
return false;
@@ -695,20 +723,20 @@ public class EventManager {
startSemaphore.release();
}
}
} catch(InterruptedException ie) {
} catch (InterruptedException ie) {
playerPermit.remove(leader.getId());
}
return false;
}
public List<PartyCharacter> getEligibleParty(Party party) {
if (party == null) {
return new ArrayList<>();
}
try {
Object o = iv.invokeFunction("getEligibleParty", party.getPartyMembersOnline());
if (o instanceof PartyCharacter[] partyChrs) {
final List<PartyCharacter> eligibleParty = new ArrayList<>(Arrays.asList(partyChrs));
party.setEligibleMembers(eligibleParty);
@@ -720,7 +748,7 @@ public class EventManager {
return new ArrayList<>();
}
public void clearPQ(EventInstanceManager eim) {
try {
iv.invokeFunction("clearPQ", eim);
@@ -728,7 +756,7 @@ public class EventManager {
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void clearPQ(EventInstanceManager eim, MapleMap toMap) {
try {
iv.invokeFunction("clearPQ", eim, toMap);
@@ -736,66 +764,71 @@ public class EventManager {
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
public Monster getMonster(int mid) {
return(LifeFactory.getMonster(mid));
return (LifeFactory.getMonster(mid));
}
private void exportReadyGuild(Integer guildId) {
Guild mg = server.getGuild(guildId);
String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
+ " and HAS JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort."
+ " Check out Shuang at the excavation site in Perion for more info.";
String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
+ " and HAS JUST STARTED THE STRATEGY PHASE. After 3 minutes, no more guild members will be allowed to join the effort."
+ " Check out Shuang at the excavation site in Perion for more info.";
mg.dropMessage(6, callout);
}
private void exportMovedQueueToGuild(Integer guildId, int place) {
Guild mg = server.getGuild(guildId);
String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
+ " and is currently on the " + GameConstants.ordinal(place) + " place on the waiting queue.";
String callout = "[Guild Quest] Your guild has been registered to attend to the Sharenian Guild Quest at channel " + this.getChannelServer().getId()
+ " and is currently on the " + GameConstants.ordinal(place) + " place on the waiting queue.";
mg.dropMessage(6, callout);
}
private List<Integer> getNextGuildQueue() {
synchronized(queuedGuilds) {
synchronized (queuedGuilds) {
Integer guildId = queuedGuilds.poll();
if(guildId == null) return null;
if (guildId == null) {
return null;
}
wserv.removeGuildQueued(guildId);
Integer leaderId = queuedGuildLeaders.remove(guildId);
int place = 1;
for(Integer i: queuedGuilds) {
for (Integer i : queuedGuilds) {
exportMovedQueueToGuild(i, place);
place++;
}
List<Integer> list = new ArrayList<>(2);
list.add(guildId); list.add(leaderId);
list.add(guildId);
list.add(leaderId);
return list;
}
}
public boolean isQueueFull() {
synchronized(queuedGuilds) {
synchronized (queuedGuilds) {
return queuedGuilds.size() >= YamlConfig.config.server.EVENT_MAX_GUILD_QUEUE;
}
}
public int getQueueSize() {
synchronized(queuedGuilds) {
synchronized (queuedGuilds) {
return queuedGuilds.size();
}
}
public byte addGuildToQueue(Integer guildId, Integer leaderId) {
if(wserv.isGuildQueued(guildId)) return -1;
if(!isQueueFull()) {
if (wserv.isGuildQueued(guildId)) {
return -1;
}
if (!isQueueFull()) {
boolean canStartAhead;
synchronized(queuedGuilds) {
synchronized (queuedGuilds) {
canStartAhead = queuedGuilds.isEmpty();
queuedGuilds.add(guildId);
@@ -805,10 +838,10 @@ public class EventManager {
int place = queuedGuilds.size();
exportMovedQueueToGuild(guildId, place);
}
if(canStartAhead) {
if(!attemptStartGuildInstance()) {
synchronized(queuedGuilds) {
if (canStartAhead) {
if (!attemptStartGuildInstance()) {
synchronized (queuedGuilds) {
queuedGuilds.add(guildId);
wserv.putGuildQueued(guildId);
queuedGuildLeaders.put(guildId, leaderId);
@@ -817,33 +850,33 @@ public class EventManager {
return 2;
}
}
return 1;
} else {
return 0;
}
}
public boolean attemptStartGuildInstance() {
Character chr = null;
List<Integer> guildInstance = null;
while(chr == null) {
while (chr == null) {
guildInstance = getNextGuildQueue();
if(guildInstance == null) {
if (guildInstance == null) {
return false;
}
chr = cserv.getPlayerStorage().getCharacterById(guildInstance.get(1));
}
if(startInstance(chr)) {
exportReadyGuild(guildInstance.get(0));
if (startInstance(chr)) {
exportReadyGuild(guildInstance.get(0));
return true;
} else {
return false;
}
}
public void startQuest(Character chr, int id, int npcid) {
try {
Quest.getInstance(id).forceStart(chr, npcid);
@@ -859,63 +892,65 @@ public class EventManager {
ex.printStackTrace();
}
}
public int getTransportationTime(int travelTime) {
return this.getWorldServer().getTransportationTime(travelTime);
}
private void fillEimQueue() {
ThreadManager.getInstance().newTask(new EventManagerTask()); //call new thread to fill up readied instances queue
}
private EventInstanceManager getReadyInstance() {
queueLock.lock();
try {
if(readyInstances.isEmpty()) {
if (readyInstances.isEmpty()) {
fillEimQueue();
return null;
}
EventInstanceManager eim = readyInstances.remove(0);
fillEimQueue();
return eim;
} finally {
queueLock.unlock();
}
}
private void instantiateQueuedInstance() {
int nextEventId;
queueLock.lock();
try {
if (this.isDisposed() || readyInstances.size() + onLoadInstances >= Math.ceil((double)maxLobbys / 3.0)) return;
if (this.isDisposed() || readyInstances.size() + onLoadInstances >= Math.ceil((double) maxLobbys / 3.0)) {
return;
}
onLoadInstances++;
nextEventId = readyId;
readyId++;
} finally {
queueLock.unlock();
}
EventInstanceManager eim = new EventInstanceManager(this, "sampleName" + nextEventId);
queueLock.lock();
try {
if (this.isDisposed()) { // EM already disposed
return;
}
readyInstances.add(eim);
onLoadInstances--;
} finally {
queueLock.unlock();
}
instantiateQueuedInstance(); // keep filling the queue until reach threshold.
}
private class EventManagerTask implements Runnable {
@Override
public void run() {
instantiateQueuedInstance();