From 1e005056717b776f5240ed9b371d842d1e6c2c48 Mon Sep 17 00:00:00 2001 From: P0nk Date: Thu, 9 Sep 2021 21:59:17 +0200 Subject: [PATCH] Rename and clean up MapleExpedition --- .../command/commands/gm3/ExpedsCommand.java | 6 +- src/main/java/net/server/channel/Channel.java | 12 +- .../scripting/AbstractPlayerInteraction.java | 12 +- .../scripting/event/EventInstanceManager.java | 8 +- .../java/scripting/event/EventManager.java | 8 +- .../scripting/npc/NPCConversationManager.java | 6 +- .../java/server/expeditions/Expedition.java | 430 ++++++++++++++++++ .../server/expeditions/MapleExpedition.java | 412 ----------------- .../expeditions/MapleExpeditionBossLog.java | 2 +- .../server/partyquest/AriantColiseum.java | 6 +- src/main/java/tools/LogHelper.java | 4 +- 11 files changed, 462 insertions(+), 444 deletions(-) create mode 100644 src/main/java/server/expeditions/Expedition.java delete mode 100644 src/main/java/server/expeditions/MapleExpedition.java diff --git a/src/main/java/client/command/commands/gm3/ExpedsCommand.java b/src/main/java/client/command/commands/gm3/ExpedsCommand.java index 4ecb4ebf84..ed54ea911f 100644 --- a/src/main/java/client/command/commands/gm3/ExpedsCommand.java +++ b/src/main/java/client/command/commands/gm3/ExpedsCommand.java @@ -28,7 +28,7 @@ import client.Client; import client.command.Command; import net.server.Server; import net.server.channel.Channel; -import server.expeditions.MapleExpedition; +import server.expeditions.Expedition; import java.util.List; import java.util.Map.Entry; @@ -42,14 +42,14 @@ public class ExpedsCommand extends Command { public void execute(Client c, String[] params) { Character player = c.getPlayer(); for (Channel ch : Server.getInstance().getChannelsFromWorld(c.getWorld())) { - List expeds = ch.getExpeditions(); + List expeds = ch.getExpeditions(); if (expeds.isEmpty()) { player.yellowMessage("No Expeditions in Channel " + ch.getId()); continue; } player.yellowMessage("Expeditions in Channel " + ch.getId()); int id = 0; - for (MapleExpedition exped : expeds) { + for (Expedition exped : expeds) { id++; player.yellowMessage("> Expedition " + id); player.yellowMessage(">> Type: " + exped.getType().toString()); diff --git a/src/main/java/net/server/channel/Channel.java b/src/main/java/net/server/channel/Channel.java index d8e22b6d7a..a7ef234f13 100644 --- a/src/main/java/net/server/channel/Channel.java +++ b/src/main/java/net/server/channel/Channel.java @@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory; import scripting.event.EventScriptManager; import server.TimerManager; import server.events.gm.Event; -import server.expeditions.MapleExpedition; +import server.expeditions.Expedition; import server.expeditions.MapleExpeditionType; import server.maps.*; import tools.PacketCreator; @@ -73,7 +73,7 @@ public final class Channel { private Map hiredMerchants = new HashMap<>(); private final Map storedVars = new HashMap<>(); private Set playersAway = new HashSet<>(); - private Map expeditions = new HashMap<>(); + private Map expeditions = new HashMap<>(); private Map dungeons = new HashMap<>(); private List expedType = new ArrayList<>(); private Set ownedMaps = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>())); @@ -398,7 +398,7 @@ public final class Channel { return retArr; } - public boolean addExpedition(MapleExpedition exped) { + public boolean addExpedition(Expedition exped) { synchronized (expeditions) { if (expeditions.containsKey(exped.getType())) { return false; @@ -410,17 +410,17 @@ public final class Channel { } } - public void removeExpedition(MapleExpedition exped) { + public void removeExpedition(Expedition exped) { synchronized (expeditions) { expeditions.remove(exped.getType()); } } - public MapleExpedition getExpedition(MapleExpeditionType type) { + public Expedition getExpedition(MapleExpeditionType type) { return expeditions.get(type); } - public List getExpeditions() { + public List getExpeditions() { synchronized (expeditions) { return new ArrayList<>(expeditions.values()); } diff --git a/src/main/java/scripting/AbstractPlayerInteraction.java b/src/main/java/scripting/AbstractPlayerInteraction.java index 80e22d8a74..6e39b9c30f 100644 --- a/src/main/java/scripting/AbstractPlayerInteraction.java +++ b/src/main/java/scripting/AbstractPlayerInteraction.java @@ -38,7 +38,7 @@ import scripting.event.EventManager; import scripting.npc.NPCScriptManager; import server.MapleItemInformationProvider; import server.MapleMarriage; -import server.expeditions.MapleExpedition; +import server.expeditions.Expedition; import server.expeditions.MapleExpeditionBossLog; import server.expeditions.MapleExpeditionType; import server.life.*; @@ -1073,7 +1073,7 @@ public class AbstractPlayerInteraction { public int createExpedition(MapleExpeditionType type, boolean silent, int minPlayers, int maxPlayers) { Character player = getPlayer(); - MapleExpedition exped = new MapleExpedition(player, type, silent, minPlayers, maxPlayers); + Expedition exped = new Expedition(player, type, silent, minPlayers, maxPlayers); int channel = player.getMap().getChannelServer().getId(); if (!MapleExpeditionBossLog.attemptBoss(player.getId(), channel, exped, false)) { // thanks Conrad for noticing missing expeditions entry limit @@ -1087,18 +1087,18 @@ public class AbstractPlayerInteraction { } } - public void endExpedition(MapleExpedition exped) { + public void endExpedition(Expedition exped) { exped.dispose(true); exped.removeChannelExpedition(getPlayer().getClient().getChannelServer()); } - public MapleExpedition getExpedition(MapleExpeditionType type) { + public Expedition getExpedition(MapleExpeditionType type) { return getPlayer().getClient().getChannelServer().getExpedition(type); } public String getExpeditionMemberNames(MapleExpeditionType type) { String members = ""; - MapleExpedition exped = getExpedition(type); + Expedition exped = getExpedition(type); for (String memberName : exped.getMembers().values()) { members += "" + memberName + ", "; } @@ -1106,7 +1106,7 @@ public class AbstractPlayerInteraction { } public boolean isLeaderExpedition(MapleExpeditionType type) { - MapleExpedition exped = getExpedition(type); + Expedition exped = getExpedition(type); return exped.isLeader(getPlayer()); } diff --git a/src/main/java/scripting/event/EventInstanceManager.java b/src/main/java/scripting/event/EventInstanceManager.java index fe668f6bfb..8f2c9b40e5 100644 --- a/src/main/java/scripting/event/EventInstanceManager.java +++ b/src/main/java/scripting/event/EventInstanceManager.java @@ -40,7 +40,7 @@ import server.MapleItemInformationProvider; import server.MapleStatEffect; import server.ThreadManager; import server.TimerManager; -import server.expeditions.MapleExpedition; +import server.expeditions.Expedition; import server.life.MapleLifeFactory; import server.life.MapleMonster; import server.life.MapleNPC; @@ -77,7 +77,7 @@ public class EventInstanceManager { private Map objectProps = new HashMap<>(); private long timeStarted = 0; private long eventTime = 0; - private MapleExpedition expedition = null; + private Expedition expedition = null; private List mapIds = new LinkedList<>(); private final MonitoredReentrantReadWriteLock lock = new MonitoredReentrantReadWriteLock(MonitoredLockType.EIM, true); @@ -361,12 +361,12 @@ public class EventInstanceManager { } } - public void registerExpedition(MapleExpedition exped) { + public void registerExpedition(Expedition exped) { expedition = exped; registerExpeditionTeam(exped, exped.getRecruitingMap().getId()); } - private void registerExpeditionTeam(MapleExpedition exped, int recruitMap) { + private void registerExpeditionTeam(Expedition exped, int recruitMap) { expedition = exped; for (Character chr: exped.getActiveMembers()) { diff --git a/src/main/java/scripting/event/EventManager.java b/src/main/java/scripting/event/EventManager.java index 13f14960de..138ed7209f 100644 --- a/src/main/java/scripting/event/EventManager.java +++ b/src/main/java/scripting/event/EventManager.java @@ -37,7 +37,7 @@ import net.server.world.World; import scripting.event.scheduler.EventScriptScheduler; import server.MapleMarriage; import server.ThreadManager; -import server.expeditions.MapleExpedition; +import server.expeditions.Expedition; import server.life.MapleLifeFactory; import server.life.MapleMonster; import server.maps.MapleMap; @@ -370,16 +370,16 @@ public class EventManager { instanceLocks.put(eventName, lobbyId); } - public boolean startInstance(MapleExpedition exped) { + public boolean startInstance(Expedition exped) { return startInstance(-1, exped); } - public boolean startInstance(int lobbyId, MapleExpedition exped) { + public boolean startInstance(int lobbyId, Expedition exped) { return startInstance(lobbyId, exped, exped.getLeader()); } //Expedition method: starts an expedition - public boolean startInstance(int lobbyId, MapleExpedition exped, Character leader) { + public boolean startInstance(int lobbyId, Expedition exped, Character leader) { if (this.isDisposed()) return false; try { diff --git a/src/main/java/scripting/npc/NPCConversationManager.java b/src/main/java/scripting/npc/NPCConversationManager.java index 0383cf4c5a..56fe988367 100644 --- a/src/main/java/scripting/npc/NPCConversationManager.java +++ b/src/main/java/scripting/npc/NPCConversationManager.java @@ -45,7 +45,7 @@ import scripting.AbstractPlayerInteraction; import server.*; import server.MapleSkillbookInformationProvider.SkillBookEntry; import server.events.gm.Event; -import server.expeditions.MapleExpedition; +import server.expeditions.Expedition; import server.expeditions.MapleExpeditionType; import server.gachapon.MapleGachapon; import server.gachapon.MapleGachapon.MapleGachaponItem; @@ -1014,7 +1014,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction { } } - private synchronized boolean setupAriantBattle(MapleExpedition exped, int mapid) { + private synchronized boolean setupAriantBattle(Expedition exped, int mapid) { MapleMap arenaMap = this.getMap().getChannelServer().getMapFactory().getMap(mapid + 1); if (!arenaMap.getAllPlayers().isEmpty()) { return false; @@ -1029,7 +1029,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction { return "You cannot start an Ariant tournament from outside the Battle Arena Entrance."; } - MapleExpedition exped = this.getMap().getChannelServer().getExpedition(expedType); + Expedition exped = this.getMap().getChannelServer().getExpedition(expedType); if (exped == null) { return "Please register on an expedition before attempting to start an Ariant tournament."; } diff --git a/src/main/java/server/expeditions/Expedition.java b/src/main/java/server/expeditions/Expedition.java new file mode 100644 index 0000000000..f22eda9873 --- /dev/null +++ b/src/main/java/server/expeditions/Expedition.java @@ -0,0 +1,430 @@ +/* + This file is part of the OdinMS Maple Story Server + Copyright (C) 2008 Patrick Huy + Matthias Butz + Jan Christian Meyer + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation version 3 as published by + the Free Software Foundation. You may not use, modify or distribute + this program under any other version of the GNU Affero General Public + License. + + 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package server.expeditions; + +import client.Character; +import net.packet.Packet; +import net.server.PlayerStorage; +import net.server.Server; +import net.server.audit.locks.MonitoredLockType; +import net.server.audit.locks.MonitoredReentrantLock; +import net.server.audit.locks.factory.MonitoredReentrantLockFactory; +import net.server.channel.Channel; +import server.TimerManager; +import server.life.MapleMonster; +import server.maps.MapleMap; +import tools.LogHelper; +import tools.PacketCreator; + +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ScheduledFuture; + +/** + * @author Alan (SharpAceX) + */ +public class Expedition { + + private static final int[] EXPEDITION_BOSSES = { + 8800000,// - Zakum's first body + 8800001,// - Zakum's second body + 8800002,// - Zakum's third body + 8800003,// - Zakum's Arm 1 + 8800004,// - Zakum's Arm 2 + 8800005,// - Zakum's Arm 3 + 8800006,// - Zakum's Arm 4 + 8800007,// - Zakum's Arm 5 + 8800008,// - Zakum's Arm 6 + 8800009,// - Zakum's Arm 7 + 8800010,// - Zakum's Arm 8 + 8810000,// - Horntail's Left Head + 8810001,// - Horntail's Right Head + 8810002,// - Horntail's Head A + 8810003,// - Horntail's Head B + 8810004,// - Horntail's Head C + 8810005,// - Horntail's Left Hand + 8810006,// - Horntail's Right Hand + 8810007,// - Horntail's Wings + 8810008,// - Horntail's Legs + 8810009,// - Horntail's Tails + 9420546,// - Scarlion Boss + 9420547,// - Scarlion Boss + 9420548,// - Angry Scarlion Boss + 9420549,// - Furious Scarlion Boss + 9420541,// - Targa + 9420542,// - Targa + 9420543,// - Angry Targa + 9420544,// - Furious Targa + }; + + private final Character leader; + private final MapleExpeditionType type; + private boolean registering; + private final MapleMap startMap; + private final List bossLogs; + private ScheduledFuture schedule; + private final Map members = new ConcurrentHashMap<>(); + private final List banned = new CopyOnWriteArrayList<>(); + private long startTime; + private final Properties props = new Properties(); + private final boolean silent; + private final int minSize; + private final int maxSize; + private final MonitoredReentrantLock pL = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EIM_PARTY, true); + + public Expedition(Character player, MapleExpeditionType met, boolean sil, int minPlayers, int maxPlayers) { + leader = player; + members.put(player.getId(), player.getName()); + startMap = player.getMap(); + type = met; + silent = sil; + minSize = (minPlayers != 0) ? minPlayers : type.getMinSize(); + maxSize = (maxPlayers != 0) ? maxPlayers : type.getMaxSize(); + bossLogs = new CopyOnWriteArrayList<>(); + } + + public int getMinSize() { + return minSize; + } + + public int getMaxSize() { + return maxSize; + } + + public void beginRegistration() { + registering = true; + leader.sendPacket(PacketCreator.getClock(type.getRegistrationTime() * 60)); + if (!silent) { + startMap.broadcastMessage(leader, PacketCreator.serverNotice(6, "[Expedition] " + leader.getName() + " has been declared the expedition captain. Please register for the expedition."), false); + leader.sendPacket(PacketCreator.serverNotice(6, "[Expedition] You have become the expedition captain. Gather enough people for your team then talk to the NPC to start.")); + } + scheduleRegistrationEnd(); + } + + private void scheduleRegistrationEnd() { + final Expedition exped = this; + startTime = System.currentTimeMillis() + type.getRegistrationTime() * 60 * 1000; + + schedule = TimerManager.getInstance().schedule(() -> { + if (registering) { + exped.removeChannelExpedition(startMap.getChannelServer()); + if (!silent) { + startMap.broadcastMessage(PacketCreator.serverNotice(6, "[Expedition] The time limit has been reached. Expedition has been disbanded.")); + } + + dispose(false); + } + }, type.getRegistrationTime() * 60 * 1000); + } + + public void dispose(boolean log) { + broadcastExped(PacketCreator.removeClock()); + + if (schedule != null) { + schedule.cancel(false); + } + if (log && !registering) { + LogHelper.logExpedition(this); + } + } + + public void finishRegistration() { + registering = false; + } + + public void start() { + finishRegistration(); + registerExpeditionAttempt(); + broadcastExped(PacketCreator.removeClock()); + if (!silent) { + broadcastExped(PacketCreator.serverNotice(6, "[Expedition] The expedition has started! Good luck, brave heroes!")); + } + startTime = System.currentTimeMillis(); + Server.getInstance().broadcastGMMessage(startMap.getWorld(), PacketCreator.serverNotice(6, "[Expedition] " + type.toString() + " Expedition started with leader: " + leader.getName())); + } + + public String addMember(Character player) { + if (!registering) { + return "Sorry, this expedition is already underway. Registration is closed!"; + } + if (banned.contains(player.getId())) { + return "Sorry, you've been banned from this expedition by #b" + leader.getName() + "#k."; + } + if (members.size() >= this.getMaxSize()) { //Would be a miracle if anybody ever saw this + return "Sorry, this expedition is full!"; + } + + int channel = this.getRecruitingMap().getChannelServer().getId(); + if (!MapleExpeditionBossLog.attemptBoss(player.getId(), channel, this, false)) { // thanks Conrad, Cato for noticing some expeditions have entry limit + return "Sorry, you've already reached the quota of attempts for this expedition! Try again another day..."; + } + + members.put(player.getId(), player.getName()); + player.sendPacket(PacketCreator.getClock((int) (startTime - System.currentTimeMillis()) / 1000)); + if (!silent) { + broadcastExped(PacketCreator.serverNotice(6, "[Expedition] " + player.getName() + " has joined the expedition!")); + } + return "You have registered for the expedition successfully!"; + } + + public int addMemberInt(Character player) { + if (!registering) { + return 1; //"Sorry, this expedition is already underway. Registration is closed!"; + } + if (banned.contains(player.getId())) { + return 2; //"Sorry, you've been banned from this expedition by #b" + leader.getName() + "#k."; + } + if (members.size() >= this.getMaxSize()) { //Would be a miracle if anybody ever saw this + return 3; //"Sorry, this expedition is full!"; + } + + members.put(player.getId(), player.getName()); + player.sendPacket(PacketCreator.getClock((int) (startTime - System.currentTimeMillis()) / 1000)); + if (!silent) { + broadcastExped(PacketCreator.serverNotice(6, "[Expedition] " + player.getName() + " has joined the expedition!")); + } + return 0; //"You have registered for the expedition successfully!"; + } + + private void registerExpeditionAttempt() { + int channel = this.getRecruitingMap().getChannelServer().getId(); + + for (Character chr : getActiveMembers()) { + MapleExpeditionBossLog.attemptBoss(chr.getId(), channel, this, true); + } + } + + private void broadcastExped(Packet packet) { + for (Character chr : getActiveMembers()) { + chr.sendPacket(packet); + } + } + + public boolean removeMember(Character chr) { + if (members.remove(chr.getId()) != null) { + chr.sendPacket(PacketCreator.removeClock()); + if (!silent) { + broadcastExped(PacketCreator.serverNotice(6, "[Expedition] " + chr.getName() + " has left the expedition.")); + chr.dropMessage(6, "[Expedition] You have left this expedition."); + } + return true; + } + + return false; + } + + public void ban(Entry chr) { + int cid = chr.getKey(); + if (!banned.contains(cid)) { + banned.add(cid); + members.remove(cid); + + if (!silent) { + broadcastExped(PacketCreator.serverNotice(6, "[Expedition] " + chr.getValue() + " has been banned from the expedition.")); + } + + Character player = startMap.getWorldServer().getPlayerStorage().getCharacterById(cid); + if (player != null && player.isLoggedinWorld()) { + player.sendPacket(PacketCreator.removeClock()); + if (!silent) { + player.dropMessage(6, "[Expedition] You have been banned from this expedition."); + } + if (MapleExpeditionType.ARIANT.equals(type) || MapleExpeditionType.ARIANT1.equals(type) || MapleExpeditionType.ARIANT2.equals(type)) { + player.changeMap(980010000); + } + } + } + } + + public void monsterKilled(Character chr, MapleMonster mob) { + for (int expeditionBoss : EXPEDITION_BOSSES) { + if (mob.getId() == expeditionBoss) { //If the monster killed was a boss + String timeStamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); + bossLogs.add(">" + mob.getName() + " was killed after " + LogHelper.getTimeString(startTime) + " - " + timeStamp + "\r\n"); + return; + } + } + } + + public void setProperty(String key, String value) { + pL.lock(); + try { + props.setProperty(key, value); + } finally { + pL.unlock(); + } + } + + public String getProperty(String key) { + pL.lock(); + try { + return props.getProperty(key); + } finally { + pL.unlock(); + } + } + + public MapleExpeditionType getType() { + return type; + } + + public List getActiveMembers() { // thanks MedicOP for figuring out an issue with broadcasting packets to offline members + PlayerStorage ps = startMap.getWorldServer().getPlayerStorage(); + + List activeMembers = new LinkedList<>(); + for (Integer chrid : getMembers().keySet()) { + Character chr = ps.getCharacterById(chrid); + if (chr != null && chr.isLoggedinWorld()) { + activeMembers.add(chr); + } + } + + return activeMembers; + } + + public Map getMembers() { + return new HashMap<>(members); + } + + public List> getMemberList() { + List> memberList = new LinkedList<>(); + Entry leaderEntry = null; + + for (Entry e : getMembers().entrySet()) { + if (!isLeader(e.getKey())) { + memberList.add(e); + } else { + leaderEntry = e; + } + } + + if (leaderEntry != null) { + memberList.add(0, leaderEntry); + } + + return memberList; + } + + public final boolean isExpeditionTeamTogether() { + List chars = getActiveMembers(); + if (chars.size() <= 1) { + return true; + } + + Iterator iterator = chars.iterator(); + Character mc = iterator.next(); + int mapId = mc.getMapId(); + + for (; iterator.hasNext(); ) { + mc = iterator.next(); + if (mc.getMapId() != mapId) { + return false; + } + } + + return true; + } + + public final void warpExpeditionTeam(int warpFrom, int warpTo) { + List players = getActiveMembers(); + + for (Character chr : players) { + if (chr.getMapId() == warpFrom) { + chr.changeMap(warpTo); + } + } + } + + public final void warpExpeditionTeam(int warpTo) { + List players = getActiveMembers(); + + for (Character chr : players) { + chr.changeMap(warpTo); + } + } + + public final void warpExpeditionTeamToMapSpawnPoint(int warpFrom, int warpTo, int toSp) { + List players = getActiveMembers(); + + for (Character chr : players) { + if (chr.getMapId() == warpFrom) { + chr.changeMap(warpTo, toSp); + } + } + } + + public final void warpExpeditionTeamToMapSpawnPoint(int warpTo, int toSp) { + List players = getActiveMembers(); + + for (Character chr : players) { + chr.changeMap(warpTo, toSp); + } + } + + public final boolean addChannelExpedition(Channel ch) { + return ch.addExpedition(this); + } + + public final void removeChannelExpedition(Channel ch) { + ch.removeExpedition(this); + } + + public Character getLeader() { + return leader; + } + + public MapleMap getRecruitingMap() { + return startMap; + } + + public boolean contains(Character player) { + return members.containsKey(player.getId()) || isLeader(player); + } + + public boolean isLeader(Character player) { + return isLeader(player.getId()); + } + + public boolean isLeader(int playerid) { + return leader.getId() == playerid; + } + + public boolean isRegistering() { + return registering; + } + + public boolean isInProgress() { + return !registering; + } + + public long getStartTime() { + return startTime; + } + + public List getBossLogs() { + return bossLogs; + } +} diff --git a/src/main/java/server/expeditions/MapleExpedition.java b/src/main/java/server/expeditions/MapleExpedition.java deleted file mode 100644 index d5bcd7a25d..0000000000 --- a/src/main/java/server/expeditions/MapleExpedition.java +++ /dev/null @@ -1,412 +0,0 @@ -/* - This file is part of the OdinMS Maple Story Server - Copyright (C) 2008 Patrick Huy - Matthias Butz - Jan Christian Meyer - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation version 3 as published by - the Free Software Foundation. You may not use, modify or distribute - this program under any other version of the GNU Affero General Public - License. - - 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 Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ - -package server.expeditions; - -import client.Character; -import net.packet.Packet; -import net.server.PlayerStorage; -import net.server.Server; -import net.server.audit.locks.MonitoredLockType; -import net.server.audit.locks.MonitoredReentrantLock; -import net.server.audit.locks.factory.MonitoredReentrantLockFactory; -import net.server.channel.Channel; -import server.TimerManager; -import server.life.MapleMonster; -import server.maps.MapleMap; -import tools.LogHelper; -import tools.PacketCreator; - -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ScheduledFuture; - -/** - * - * @author Alan (SharpAceX) - */ -public class MapleExpedition { - - private static final int [] EXPEDITION_BOSSES = { - 8800000,// - Zakum's first body - 8800001,// - Zakum's second body - 8800002,// - Zakum's third body - 8800003,// - Zakum's Arm 1 - 8800004,// - Zakum's Arm 2 - 8800005,// - Zakum's Arm 3 - 8800006,// - Zakum's Arm 4 - 8800007,// - Zakum's Arm 5 - 8800008,// - Zakum's Arm 6 - 8800009,// - Zakum's Arm 7 - 8800010,// - Zakum's Arm 8 - 8810000,// - Horntail's Left Head - 8810001,// - Horntail's Right Head - 8810002,// - Horntail's Head A - 8810003,// - Horntail's Head B - 8810004,// - Horntail's Head C - 8810005,// - Horntail's Left Hand - 8810006,// - Horntail's Right Hand - 8810007,// - Horntail's Wings - 8810008,// - Horntail's Legs - 8810009,// - Horntail's Tails - 9420546,// - Scarlion Boss - 9420547,// - Scarlion Boss - 9420548,// - Angry Scarlion Boss - 9420549,// - Furious Scarlion Boss - 9420541,// - Targa - 9420542,// - Targa - 9420543,// - Angry Targa - 9420544,// - Furious Targa - }; - - private Character leader; - private MapleExpeditionType type; - private boolean registering; - private MapleMap startMap; - private List bossLogs; - private ScheduledFuture schedule; - private Map members = new ConcurrentHashMap<>(); - private List banned = new CopyOnWriteArrayList<>(); - private long startTime; - private Properties props = new Properties(); - private boolean silent; - private int minSize, maxSize; - private MonitoredReentrantLock pL = MonitoredReentrantLockFactory.createLock(MonitoredLockType.EIM_PARTY, true); - - public MapleExpedition(Character player, MapleExpeditionType met, boolean sil, int minPlayers, int maxPlayers) { - leader = player; - members.put(player.getId(), player.getName()); - startMap = player.getMap(); - type = met; - silent = sil; - minSize = (minPlayers != 0) ? minPlayers : type.getMinSize(); - maxSize = (maxPlayers != 0) ? maxPlayers : type.getMaxSize(); - bossLogs = new CopyOnWriteArrayList<>(); - } - - public int getMinSize() { - return minSize; - } - - public int getMaxSize() { - return maxSize; - } - - public void beginRegistration() { - registering = true; - leader.sendPacket(PacketCreator.getClock(type.getRegistrationTime() * 60)); - if (!silent) { - startMap.broadcastMessage(leader, PacketCreator.serverNotice(6, "[Expedition] " + leader.getName() + " has been declared the expedition captain. Please register for the expedition."), false); - leader.sendPacket(PacketCreator.serverNotice(6, "[Expedition] You have become the expedition captain. Gather enough people for your team then talk to the NPC to start.")); - } - scheduleRegistrationEnd(); - } - - private void scheduleRegistrationEnd() { - final MapleExpedition exped = this; - startTime = System.currentTimeMillis() + type.getRegistrationTime() * 60 * 1000; - - schedule = TimerManager.getInstance().schedule(() -> { - if (registering){ -exped.removeChannelExpedition(startMap.getChannelServer()); - if (!silent) startMap.broadcastMessage(PacketCreator.serverNotice(6, "[Expedition] The time limit has been reached. Expedition has been disbanded.")); - -dispose(false); - } - }, type.getRegistrationTime() * 60 * 1000); - } - - public void dispose(boolean log) { - broadcastExped(PacketCreator.removeClock()); - - if (schedule != null) { - schedule.cancel(false); - } - if (log && !registering) { - LogHelper.logExpedition(this); - } - } - - public void finishRegistration() { - registering = false; - } - - public void start(){ - finishRegistration(); - registerExpeditionAttempt(); - broadcastExped(PacketCreator.removeClock()); - if (!silent) broadcastExped(PacketCreator.serverNotice(6, "[Expedition] The expedition has started! Good luck, brave heroes!")); - startTime = System.currentTimeMillis(); - Server.getInstance().broadcastGMMessage(startMap.getWorld(), PacketCreator.serverNotice(6, "[Expedition] " + type.toString() + " Expedition started with leader: " + leader.getName())); - } - - public String addMember(Character player) { - if (!registering){ - return "Sorry, this expedition is already underway. Registration is closed!"; - } - if (banned.contains(player.getId())){ - return "Sorry, you've been banned from this expedition by #b" + leader.getName() + "#k."; - } - if (members.size() >= this.getMaxSize()){ //Would be a miracle if anybody ever saw this - return "Sorry, this expedition is full!"; - } - - int channel = this.getRecruitingMap().getChannelServer().getId(); - if (!MapleExpeditionBossLog.attemptBoss(player.getId(), channel, this, false)) { // thanks Conrad, Cato for noticing some expeditions have entry limit - return "Sorry, you've already reached the quota of attempts for this expedition! Try again another day..."; - } - - members.put(player.getId(), player.getName()); - player.sendPacket(PacketCreator.getClock((int)(startTime - System.currentTimeMillis()) / 1000)); - if (!silent) broadcastExped(PacketCreator.serverNotice(6, "[Expedition] " + player.getName() + " has joined the expedition!")); - return "You have registered for the expedition successfully!"; - } - - public int addMemberInt(Character player) { - if (!registering) { - return 1; //"Sorry, this expedition is already underway. Registration is closed!"; - } - if (banned.contains(player.getId())) { - return 2; //"Sorry, you've been banned from this expedition by #b" + leader.getName() + "#k."; - } - if (members.size() >= this.getMaxSize()) { //Would be a miracle if anybody ever saw this - return 3; //"Sorry, this expedition is full!"; - } - - members.put(player.getId(), player.getName()); - player.sendPacket(PacketCreator.getClock((int) (startTime - System.currentTimeMillis()) / 1000)); - if (!silent) broadcastExped(PacketCreator.serverNotice(6, "[Expedition] " + player.getName() + " has joined the expedition!")); - return 0; //"You have registered for the expedition successfully!"; - } - - private void registerExpeditionAttempt(){ - int channel = this.getRecruitingMap().getChannelServer().getId(); - - for (Character chr : getActiveMembers()){ - MapleExpeditionBossLog.attemptBoss(chr.getId(), channel, this, true); - } - } - - private void broadcastExped(Packet packet){ - for (Character chr : getActiveMembers()){ - chr.sendPacket(packet); - } - } - - public boolean removeMember(Character chr) { - if(members.remove(chr.getId()) != null) { - chr.sendPacket(PacketCreator.removeClock()); - if (!silent) { - broadcastExped(PacketCreator.serverNotice(6, "[Expedition] " + chr.getName() + " has left the expedition.")); - chr.dropMessage(6, "[Expedition] You have left this expedition."); - } - return true; - } - - return false; - } - - public void ban(Entry chr) { - int cid = chr.getKey(); - if (!banned.contains(cid)) { - banned.add(cid); - members.remove(cid); - - if (!silent) broadcastExped(PacketCreator.serverNotice(6, "[Expedition] " + chr.getValue() + " has been banned from the expedition.")); - - Character player = startMap.getWorldServer().getPlayerStorage().getCharacterById(cid); - if (player != null && player.isLoggedinWorld()) { - player.sendPacket(PacketCreator.removeClock()); - if (!silent) player.dropMessage(6, "[Expedition] You have been banned from this expedition."); - if (MapleExpeditionType.ARIANT.equals(type) || MapleExpeditionType.ARIANT1.equals(type) || MapleExpeditionType.ARIANT2.equals(type)) { - player.changeMap(980010000); - } - } - } - } - - public void monsterKilled(Character chr, MapleMonster mob) { - for (int expeditionBoss : EXPEDITION_BOSSES) { - if (mob.getId() == expeditionBoss) { //If the monster killed was a boss - String timeStamp = new SimpleDateFormat("HH:mm:ss").format(new Date()); - bossLogs.add(">" + mob.getName() + " was killed after " + LogHelper.getTimeString(startTime) + " - " + timeStamp + "\r\n"); - return; - } - } - } - - public void setProperty(String key, String value) { - pL.lock(); - try { - props.setProperty(key, value); - } finally { - pL.unlock(); - } - } - - public String getProperty(String key) { - pL.lock(); - try { - return props.getProperty(key); - } finally { - pL.unlock(); - } - } - - public MapleExpeditionType getType() { - return type; - } - - public List getActiveMembers() { // thanks MedicOP for figuring out an issue with broadcasting packets to offline members - PlayerStorage ps = startMap.getWorldServer().getPlayerStorage(); - - List activeMembers = new LinkedList<>(); - for (Integer chrid : getMembers().keySet()){ - Character chr = ps.getCharacterById(chrid); - if (chr != null && chr.isLoggedinWorld()) { - activeMembers.add(chr); - } - } - - return activeMembers; - } - - public Map getMembers() { - return new HashMap<>(members); - } - - public List> getMemberList() { - List> memberList = new LinkedList<>(); - Entry leaderEntry = null; - - for (Entry e : getMembers().entrySet()) { - if (!isLeader(e.getKey())) { - memberList.add(e); - } else { - leaderEntry = e; - } - } - - if (leaderEntry != null) { - memberList.add(0, leaderEntry); - } - - return memberList; - } - - public final boolean isExpeditionTeamTogether() { - List chars = getActiveMembers(); - if(chars.size() <= 1) return true; - - Iterator iterator = chars.iterator(); - Character mc = iterator.next(); - int mapId = mc.getMapId(); - - for (; iterator.hasNext();) { - mc = iterator.next(); - if(mc.getMapId() != mapId) return false; - } - - return true; - } - - public final void warpExpeditionTeam(int warpFrom, int warpTo) { - List players = getActiveMembers(); - - for (Character chr : players) { - if(chr.getMapId() == warpFrom) - chr.changeMap(warpTo); - } - } - - public final void warpExpeditionTeam(int warpTo) { - List players = getActiveMembers(); - - for (Character chr : players) { - chr.changeMap(warpTo); - } - } - - public final void warpExpeditionTeamToMapSpawnPoint(int warpFrom, int warpTo, int toSp) { - List players = getActiveMembers(); - - for (Character chr : players) { - if(chr.getMapId() == warpFrom) - chr.changeMap(warpTo, toSp); - } - } - - public final void warpExpeditionTeamToMapSpawnPoint(int warpTo, int toSp) { - List players = getActiveMembers(); - - for (Character chr : players) { - chr.changeMap(warpTo, toSp); - } - } - - public final boolean addChannelExpedition(Channel ch) { - return ch.addExpedition(this); - } - - public final void removeChannelExpedition(Channel ch) { - ch.removeExpedition(this); - } - - public Character getLeader(){ - return leader; - } - - public MapleMap getRecruitingMap() { - return startMap; - } - - public boolean contains(Character player) { - return members.containsKey(player.getId()) || isLeader(player); - } - - public boolean isLeader(Character player) { - return isLeader(player.getId()); - } - - public boolean isLeader(int playerid) { - return leader.getId() == playerid; - } - - public boolean isRegistering(){ - return registering; - } - - public boolean isInProgress(){ - return !registering; - } - - public long getStartTime(){ - return startTime; - } - - public List getBossLogs(){ - return bossLogs; - } -} diff --git a/src/main/java/server/expeditions/MapleExpeditionBossLog.java b/src/main/java/server/expeditions/MapleExpeditionBossLog.java index 9907e65c0e..69040107a6 100644 --- a/src/main/java/server/expeditions/MapleExpeditionBossLog.java +++ b/src/main/java/server/expeditions/MapleExpeditionBossLog.java @@ -168,7 +168,7 @@ public class MapleExpeditionBossLog { } } - public static boolean attemptBoss(int cid, int channel, MapleExpedition exped, boolean log) { + public static boolean attemptBoss(int cid, int channel, Expedition exped, boolean log) { if (!YamlConfig.config.server.USE_ENABLE_DAILY_EXPEDITIONS) { return true; } diff --git a/src/main/java/server/partyquest/AriantColiseum.java b/src/main/java/server/partyquest/AriantColiseum.java index cbe124b482..fef66e3a0b 100644 --- a/src/main/java/server/partyquest/AriantColiseum.java +++ b/src/main/java/server/partyquest/AriantColiseum.java @@ -22,7 +22,7 @@ package server.partyquest; import client.Character; import constants.game.GameConstants; import server.TimerManager; -import server.expeditions.MapleExpedition; +import server.expeditions.Expedition; import server.expeditions.MapleExpeditionType; import server.maps.MapleMap; import tools.PacketCreator; @@ -40,7 +40,7 @@ import java.util.concurrent.ScheduledFuture; */ public class AriantColiseum { - private MapleExpedition exped; + private Expedition exped; private MapleMap map; private Map score; @@ -55,7 +55,7 @@ public class AriantColiseum { private boolean eventClear = false; - public AriantColiseum(MapleMap eventMap, MapleExpedition expedition) { + public AriantColiseum(MapleMap eventMap, Expedition expedition) { exped = expedition; exped.finishRegistration(); diff --git a/src/main/java/tools/LogHelper.java b/src/main/java/tools/LogHelper.java index ed36d9396a..201467d992 100644 --- a/src/main/java/tools/LogHelper.java +++ b/src/main/java/tools/LogHelper.java @@ -6,7 +6,7 @@ import client.inventory.Item; import net.server.Server; import server.MapleItemInformationProvider; import server.MapleTrade; -import server.expeditions.MapleExpedition; +import server.expeditions.Expedition; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -34,7 +34,7 @@ public class LogHelper { FilePrinter.print(FilePrinter.LOG_TRADE, log); } - public static void logExpedition(MapleExpedition expedition) { + public static void logExpedition(Expedition expedition) { Server.getInstance().broadcastGMMessage(expedition.getLeader().getWorld(), PacketCreator.serverNotice(6, expedition.getType().toString() + " Expedition with leader " + expedition.getLeader().getName() + " finished after " + getTimeString(expedition.getStartTime()))); String log = expedition.getType().toString() + " EXPEDITION\r\n";