Wrap around hpDec schedules (#75)
* Wrap around hpDec schedules Merges hpDec schedules at character into a world schedule. * Patch hpDec timer reset on changing maps Patch timer reset on changing maps with hpDec. * Update Character.java * Update Client.java * Update World.java Co-authored-by: Ronan Lana <rcpl2010@gmail.com>
This commit is contained in:
@@ -332,7 +332,8 @@ server:
|
|||||||
ITEM_EXPIRE_CHECK: 10000 # (10 * 10000) Interval between item expiring tasks on maps, which checks and makes disappear expired items.
|
ITEM_EXPIRE_CHECK: 10000 # (10 * 10000) Interval between item expiring tasks on maps, which checks and makes disappear expired items.
|
||||||
ITEM_LIMIT_ON_MAP: 200 #Max number of items allowed on a map.
|
ITEM_LIMIT_ON_MAP: 200 #Max number of items allowed on a map.
|
||||||
MAP_VISITED_SIZE: 5 #Max length for last mapids visited by a player. This is used to recover and update drops on these maps accordingly with player actions.
|
MAP_VISITED_SIZE: 5 #Max length for last mapids visited by a player. This is used to recover and update drops on these maps accordingly with player actions.
|
||||||
MAP_DAMAGE_OVERTIME_INTERVAL: 5000 #Interval in milliseconds between map environment damage (e.g. El Nath and Aqua Road surrondings).
|
MAP_DAMAGE_OVERTIME_INTERVAL: 2500 #Interval in milliseconds between map environment damage (e.g. El Nath and Aqua Road surrondings).
|
||||||
|
MAP_DAMAGE_OVERTIME_COUNT: 2
|
||||||
|
|
||||||
#Channel Mob Disease Monitor Configuration
|
#Channel Mob Disease Monitor Configuration
|
||||||
MOB_STATUS_MONITOR_PROC: 200 #Frequency in milliseconds between each proc on the mob disease monitor schedule.
|
MOB_STATUS_MONITOR_PROC: 200 #Frequency in milliseconds between each proc on the mob disease monitor schedule.
|
||||||
|
|||||||
@@ -251,7 +251,6 @@ public class Character extends AbstractCharacterObject {
|
|||||||
private boolean loggedIn = false;
|
private boolean loggedIn = false;
|
||||||
private boolean useCS; //chaos scroll upon crafting item.
|
private boolean useCS; //chaos scroll upon crafting item.
|
||||||
private long npcCd;
|
private long npcCd;
|
||||||
private long lastHpDec = 0;
|
|
||||||
private int newWarpMap = -1;
|
private int newWarpMap = -1;
|
||||||
private boolean canWarpMap = true; //only one "warp" must be used per call, and this will define the right one.
|
private boolean canWarpMap = true; //only one "warp" must be used per call, and this will define the right one.
|
||||||
private int canWarpCounter = 0; //counts how many times "inner warps" have been called.
|
private int canWarpCounter = 0; //counts how many times "inner warps" have been called.
|
||||||
@@ -1720,10 +1719,6 @@ public class Character extends AbstractCharacterObject {
|
|||||||
Character.this.getParty().setEnemy(k);
|
Character.this.getParty().setEnemy(k);
|
||||||
}
|
}
|
||||||
silentPartyUpdateInternal(getParty()); // EIM script calls inside
|
silentPartyUpdateInternal(getParty()); // EIM script calls inside
|
||||||
|
|
||||||
if (getMap().getHPDec() > 0) {
|
|
||||||
resetHpDecreaseTask();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.warn("Chr {} got stuck when moving to map {}", getName(), map.getId());
|
log.warn("Chr {} got stuck when moving to map {}", getName(), map.getId());
|
||||||
client.disconnect(true, false); // thanks BHB for noticing a player storage stuck case here
|
client.disconnect(true, false); // thanks BHB for noticing a player storage stuck case here
|
||||||
@@ -2768,31 +2763,12 @@ public class Character extends AbstractCharacterObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doHurtHp() {
|
public void doHurtHp() {
|
||||||
if (!(this.getInventory(InventoryType.EQUIPPED).findById(getMap().getHPDecProtect()) != null || buffMapProtection())) {
|
if (!(this.getInventory(InventoryType.EQUIPPED).findById(getMap().getHPDecProtect()) != null || buffMapProtection())) {
|
||||||
addHP(-getMap().getHPDec());
|
addHP(-getMap().getHPDec());
|
||||||
lastHpDec = Server.getInstance().getCurrentTime();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startHpDecreaseTask(long lastHpTask) {
|
|
||||||
hpDecreaseTask = TimerManager.getInstance().register(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
doHurtHp();
|
|
||||||
}
|
|
||||||
}, YamlConfig.config.server.MAP_DAMAGE_OVERTIME_INTERVAL, YamlConfig.config.server.MAP_DAMAGE_OVERTIME_INTERVAL - lastHpTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetHpDecreaseTask() {
|
|
||||||
if (hpDecreaseTask != null) {
|
|
||||||
hpDecreaseTask.cancel(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
long lastHpTask = Server.getInstance().getCurrentTime() - lastHpDec;
|
|
||||||
startHpDecreaseTask((lastHpTask > YamlConfig.config.server.MAP_DAMAGE_OVERTIME_INTERVAL) ? YamlConfig.config.server.MAP_DAMAGE_OVERTIME_INTERVAL : lastHpTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dropMessage(String message) {
|
public void dropMessage(String message) {
|
||||||
dropMessage(0, message);
|
dropMessage(0, message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -940,6 +940,10 @@ public class Client extends ChannelInboundHandlerAdapter {
|
|||||||
if (MapId.isDojo(mapId)) {
|
if (MapId.isDojo(mapId)) {
|
||||||
this.getChannelServer().freeDojoSectionIfEmpty(mapId);
|
this.getChannelServer().freeDojoSectionIfEmpty(mapId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player.getMap().getHPDec() > 0) {
|
||||||
|
getWorldServer().removePlayerHpDecrease(player);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final Throwable t) {
|
} catch (final Throwable t) {
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ public class ServerConfig {
|
|||||||
public int ITEM_LIMIT_ON_MAP;
|
public int ITEM_LIMIT_ON_MAP;
|
||||||
public int MAP_VISITED_SIZE;
|
public int MAP_VISITED_SIZE;
|
||||||
public int MAP_DAMAGE_OVERTIME_INTERVAL;
|
public int MAP_DAMAGE_OVERTIME_INTERVAL;
|
||||||
|
public int MAP_DAMAGE_OVERTIME_COUNT;
|
||||||
|
|
||||||
//Channel Mob Disease Monitor Configuration
|
//Channel Mob Disease Monitor Configuration
|
||||||
public int MOB_STATUS_MONITOR_PROC;
|
public int MOB_STATUS_MONITOR_PROC;
|
||||||
|
|||||||
@@ -55,9 +55,6 @@ public final class ItemMoveHandler extends AbstractPacketHandler {
|
|||||||
InventoryManipulator.move(c, type, src, action);
|
InventoryManipulator.move(c, type, src, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.getPlayer().getMap().getHPDec() > 0) {
|
|
||||||
c.getPlayer().resetHpDecreaseTask();
|
|
||||||
}
|
|
||||||
c.getPlayer().getAutobanManager().spam(6);
|
c.getPlayer().getAutobanManager().spam(6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -386,10 +386,6 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler {
|
|||||||
player.commitExcludedItems();
|
player.commitExcludedItems();
|
||||||
showDueyNotification(c, player);
|
showDueyNotification(c, player);
|
||||||
|
|
||||||
if (player.getMap().getHPDec() > 0) {
|
|
||||||
player.resetHpDecreaseTask();
|
|
||||||
}
|
|
||||||
|
|
||||||
player.resetPlayerRates();
|
player.resetPlayerRates();
|
||||||
if (YamlConfig.config.server.USE_ADD_RATES_BY_LEVEL) {
|
if (YamlConfig.config.server.USE_ADD_RATES_BY_LEVEL) {
|
||||||
player.setPlayerRates();
|
player.setPlayerRates();
|
||||||
|
|||||||
37
src/main/java/net/server/task/CharacterHpDecreaseTask.java
Normal file
37
src/main/java/net/server/task/CharacterHpDecreaseTask.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
This file is part of the HeavenMS MapleStory Server
|
||||||
|
Copyleft (L) 2016 - 2019 RonanLana
|
||||||
|
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.server.task;
|
||||||
|
|
||||||
|
import net.server.world.World;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Ronan
|
||||||
|
*/
|
||||||
|
public class CharacterHpDecreaseTask extends BaseTask implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
wserv.runPlayerHpDecreaseSchedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharacterHpDecreaseTask(World world) {
|
||||||
|
super(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -153,6 +153,7 @@ public class World {
|
|||||||
private MonitoredReentrantLock timedMapObjectLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_MAPOBJS, true);
|
private MonitoredReentrantLock timedMapObjectLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.WORLD_MAPOBJS, true);
|
||||||
|
|
||||||
private final Map<Character, Integer> fishingAttempters = Collections.synchronizedMap(new WeakHashMap<>());
|
private final Map<Character, Integer> fishingAttempters = Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
|
private Map<Character, Integer> playerHpDec = Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
|
|
||||||
private ScheduledFuture<?> charactersSchedule;
|
private ScheduledFuture<?> charactersSchedule;
|
||||||
private ScheduledFuture<?> marriagesSchedule;
|
private ScheduledFuture<?> marriagesSchedule;
|
||||||
@@ -160,6 +161,7 @@ public class World {
|
|||||||
private ScheduledFuture<?> fishingSchedule;
|
private ScheduledFuture<?> fishingSchedule;
|
||||||
private ScheduledFuture<?> partySearchSchedule;
|
private ScheduledFuture<?> partySearchSchedule;
|
||||||
private ScheduledFuture<?> timeoutSchedule;
|
private ScheduledFuture<?> timeoutSchedule;
|
||||||
|
private ScheduledFuture<?> hpDecSchedule;
|
||||||
|
|
||||||
public World(int world, int flag, String eventmsg, int exprate, int droprate, int bossdroprate, int mesorate, int questrate, int travelrate, int fishingrate) {
|
public World(int world, int flag, String eventmsg, int exprate, int droprate, int bossdroprate, int mesorate, int questrate, int travelrate, int fishingrate) {
|
||||||
this.id = world;
|
this.id = world;
|
||||||
@@ -194,6 +196,7 @@ public class World {
|
|||||||
fishingSchedule = tman.register(new FishingTask(this), SECONDS.toMillis(10), SECONDS.toMillis(10));
|
fishingSchedule = tman.register(new FishingTask(this), SECONDS.toMillis(10), SECONDS.toMillis(10));
|
||||||
partySearchSchedule = tman.register(new PartySearchTask(this), SECONDS.toMillis(10), SECONDS.toMillis(10));
|
partySearchSchedule = tman.register(new PartySearchTask(this), SECONDS.toMillis(10), SECONDS.toMillis(10));
|
||||||
timeoutSchedule = tman.register(new TimeoutTask(this), SECONDS.toMillis(10), SECONDS.toMillis(10));
|
timeoutSchedule = tman.register(new TimeoutTask(this), SECONDS.toMillis(10), SECONDS.toMillis(10));
|
||||||
|
hpDecSchedule = tman.register(new CharacterHpDecreaseTask(this), YamlConfig.config.server.MAP_DAMAGE_OVERTIME_INTERVAL, YamlConfig.config.server.MAP_DAMAGE_OVERTIME_INTERVAL);
|
||||||
|
|
||||||
if (YamlConfig.config.server.USE_FAMILY_SYSTEM) {
|
if (YamlConfig.config.server.USE_FAMILY_SYSTEM) {
|
||||||
long timeLeft = Server.getTimeLeftForNextDay();
|
long timeLeft = Server.getTimeLeftForNextDay();
|
||||||
@@ -1715,6 +1718,33 @@ public class World {
|
|||||||
r.run();
|
r.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addPlayerHpDecrease(Character chr) {
|
||||||
|
playerHpDec.putIfAbsent(chr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePlayerHpDecrease(Character chr) {
|
||||||
|
playerHpDec.remove(chr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runPlayerHpDecreaseSchedule() {
|
||||||
|
Map<Character, Integer> m = new HashMap<>();
|
||||||
|
m.putAll(playerHpDec);
|
||||||
|
|
||||||
|
for (Entry<Character, Integer> e : m.entrySet()) {
|
||||||
|
Character chr = e.getKey();
|
||||||
|
|
||||||
|
if (!chr.isAwayFromWorld()) {
|
||||||
|
int c = e.getValue();
|
||||||
|
c = (c + 1) % YamlConfig.config.server.MAP_DAMAGE_OVERTIME_COUNT;
|
||||||
|
playerHpDec.replace(chr, c);
|
||||||
|
|
||||||
|
if (c == 0) {
|
||||||
|
chr.doHurtHp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void resetDisabledServerMessages() {
|
public void resetDisabledServerMessages() {
|
||||||
srvMessagesLock.lock();
|
srvMessagesLock.lock();
|
||||||
@@ -2149,6 +2179,11 @@ public class World {
|
|||||||
timeoutSchedule.cancel(false);
|
timeoutSchedule.cancel(false);
|
||||||
timeoutSchedule = null;
|
timeoutSchedule = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(hpDecSchedule != null) {
|
||||||
|
hpDecSchedule.cancel(false);
|
||||||
|
hpDecSchedule = null;
|
||||||
|
}
|
||||||
|
|
||||||
players.disconnectAll();
|
players.disconnectAll();
|
||||||
players = null;
|
players = null;
|
||||||
|
|||||||
@@ -2377,6 +2377,12 @@ public class MapleMap {
|
|||||||
|
|
||||||
chr.setMapId(mapid);
|
chr.setMapId(mapid);
|
||||||
chr.updateActiveEffects();
|
chr.updateActiveEffects();
|
||||||
|
|
||||||
|
if (this.getHPDec() > 0) {
|
||||||
|
getWorldServer().addPlayerHpDecrease(chr);
|
||||||
|
} else {
|
||||||
|
getWorldServer().removePlayerHpDecrease(chr);
|
||||||
|
}
|
||||||
|
|
||||||
MapScriptManager msm = MapScriptManager.getInstance();
|
MapScriptManager msm = MapScriptManager.getInstance();
|
||||||
if (chrSize == 1) {
|
if (chrSize == 1) {
|
||||||
|
|||||||
Reference in New Issue
Block a user