Revamped buff system + skill cd/buff schedule rework
Completely rearranged buff system (system can smartly check for the best statup to take effect for it's duration, or the server can be flagged to act as usual). Refactored scheduling system for buffs expiration and cooldowns to use one single thread per player rather than one per instance.
This commit is contained in:
@@ -21,6 +21,8 @@
|
||||
*/
|
||||
package net.server;
|
||||
|
||||
import net.server.worker.CouponWorker;
|
||||
import net.server.worker.RankingWorker;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
@@ -41,6 +41,8 @@ public final class CancelBuffHandler extends AbstractMaplePacketHandler implemen
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
int sourceid = slea.readInt();
|
||||
if(sourceid < 0) sourceid = -sourceid; //oh my...
|
||||
|
||||
switch (sourceid) {
|
||||
case FPArchMage.BIG_BANG:
|
||||
case ILArchMage.BIG_BANG:
|
||||
|
||||
@@ -32,7 +32,6 @@ import tools.Pair;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleCharacter.CancelCooldownAction;
|
||||
import client.MapleClient;
|
||||
import client.MapleJob;
|
||||
import client.MapleStat;
|
||||
@@ -175,7 +174,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
|
||||
return;
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
|
||||
mc.closePlayerInteractions();
|
||||
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
|
||||
mc.cancelBuffEffects();
|
||||
mc.cancelAllBuffs(true);
|
||||
mc.cancelBuffExpireTask();
|
||||
mc.cancelSkillCooldownTask();
|
||||
mc.cancelExpirationTask();
|
||||
|
||||
c.announce(MaplePacketCreator.openCashShop(c, false));
|
||||
|
||||
@@ -59,6 +59,9 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
|
||||
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
|
||||
chr.cancelAllBuffs(true);
|
||||
chr.cancelBuffExpireTask();
|
||||
chr.cancelSkillCooldownTask();
|
||||
chr.cancelExpirationTask();
|
||||
chr.saveToDB();
|
||||
chr.getMap().removePlayer(c.getPlayer());
|
||||
|
||||
@@ -27,7 +27,6 @@ import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleCharacter.CancelCooldownAction;
|
||||
import client.MapleClient;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
@@ -76,7 +75,7 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
|
||||
return;
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
|
||||
}
|
||||
}
|
||||
applyAttack(attack, player, effect.getAttackCount());
|
||||
|
||||
@@ -32,6 +32,7 @@ import constants.ItemConstants;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.Server;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleMiniGame;
|
||||
@@ -172,6 +173,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
} else {
|
||||
HiredMerchant merchant = new HiredMerchant(chr, itemId, desc);
|
||||
chr.setHiredMerchant(merchant);
|
||||
c.getWorldServer().registerHiredMerchant(merchant);
|
||||
chr.getClient().getChannelServer().addHiredMerchant(chr.getId(), merchant);
|
||||
chr.announce(MaplePacketCreator.getHiredMerchant(chr, merchant, true));
|
||||
}
|
||||
|
||||
@@ -256,6 +256,8 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
c.announce(MaplePacketCreator.enableReport());
|
||||
player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1);
|
||||
player.checkBerserk(player.isHidden());
|
||||
player.buffExpireTask();
|
||||
player.skillCooldownTask();
|
||||
player.expirationTask();
|
||||
if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) {
|
||||
player.createDragon();
|
||||
|
||||
@@ -30,7 +30,6 @@ import tools.Randomizer;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleBuffStat;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleCharacter.CancelCooldownAction;
|
||||
import client.MapleClient;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
@@ -208,7 +207,7 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
|
||||
return;
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000));
|
||||
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleCharacter.CancelCooldownAction;
|
||||
import client.autoban.AutobanFactory;
|
||||
import client.MapleClient;
|
||||
import client.MapleStat;
|
||||
@@ -84,8 +83,7 @@ public final class SpecialMoveHandler extends AbstractMaplePacketHandler {
|
||||
return;
|
||||
} else if (skillid != Corsair.BATTLE_SHIP) {
|
||||
c.announce(MaplePacketCreator.skillCooldown(skillid, effect.getCooldown()));
|
||||
ScheduledFuture<?> timer = TimerManager.getInstance().schedule(new CancelCooldownAction(c.getPlayer(), skillid), effect.getCooldown() * 1000);
|
||||
chr.addCooldown(skillid, System.currentTimeMillis(), effect.getCooldown() * 1000, timer);
|
||||
chr.addCooldown(skillid, System.currentTimeMillis(), effect.getCooldown() * 1000);
|
||||
}
|
||||
}
|
||||
if (skillid == Hero.MONSTER_MAGNET || skillid == Paladin.MONSTER_MAGNET || skillid == DarkKnight.MONSTER_MAGNET) { // Monster Magnet
|
||||
|
||||
39
src/net/server/worker/BaseWorker.java
Normal file
39
src/net/server/worker/BaseWorker.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class BaseWorker implements Runnable {
|
||||
protected World wserv;
|
||||
|
||||
@Override
|
||||
public void run() {}
|
||||
|
||||
public BaseWorker(World world) {
|
||||
wserv = world;
|
||||
}
|
||||
}
|
||||
@@ -20,17 +20,17 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
import client.MapleCharacter;
|
||||
import constants.ServerConstants;
|
||||
import net.server.PlayerStorage;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class CharacterAutosaverWorker implements Runnable {
|
||||
private World wserv;
|
||||
public class CharacterAutosaverWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -45,6 +45,6 @@ public class CharacterAutosaverWorker implements Runnable {
|
||||
}
|
||||
|
||||
public CharacterAutosaverWorker(World world) {
|
||||
wserv = world;
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,10 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import net.server.Server;
|
||||
import tools.FilePrinter;
|
||||
|
||||
/**
|
||||
40
src/net/server/worker/HiredMerchantWorker.java
Normal file
40
src/net/server/worker/HiredMerchantWorker.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
This file is part of the OdinMS Maple Story Server
|
||||
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
|
||||
Matthias Butz <matze@odinms.de>
|
||||
Jan Christian Meyer <vimes@odinms.de>
|
||||
|
||||
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.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class HiredMerchantWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
wserv.runHiredMerchantSchedule();
|
||||
}
|
||||
|
||||
public HiredMerchantWorker(World world) {
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
@@ -20,15 +20,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class MountTirednessWorker implements Runnable {
|
||||
private World wserv;
|
||||
public class MountTirednessWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -36,6 +35,6 @@ public class MountTirednessWorker implements Runnable {
|
||||
}
|
||||
|
||||
public MountTirednessWorker(World world) {
|
||||
wserv = world;
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
@@ -20,15 +20,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.server;
|
||||
package net.server.worker;
|
||||
|
||||
import net.server.world.World;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
*/
|
||||
public class PetFullnessWorker implements Runnable {
|
||||
private World wserv;
|
||||
public class PetFullnessWorker extends BaseWorker implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -36,6 +35,6 @@ public class PetFullnessWorker implements Runnable {
|
||||
}
|
||||
|
||||
public PetFullnessWorker(World world) {
|
||||
wserv = world;
|
||||
super(world);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
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;
|
||||
package net.server.worker;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
@@ -28,6 +28,7 @@ import java.sql.SQLException;
|
||||
import client.MapleJob;
|
||||
import tools.DatabaseConnection;
|
||||
import constants.ServerConstants;
|
||||
import net.server.Server;
|
||||
|
||||
/**
|
||||
* @author Matze
|
||||
@@ -45,9 +45,10 @@ import java.util.HashSet;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import server.TimerManager;
|
||||
import net.server.CharacterAutosaverWorker;
|
||||
import net.server.MountTirednessWorker;
|
||||
import net.server.PetFullnessWorker;
|
||||
import server.maps.HiredMerchant;
|
||||
import net.server.worker.CharacterAutosaverWorker;
|
||||
import net.server.worker.MountTirednessWorker;
|
||||
import net.server.worker.PetFullnessWorker;
|
||||
import net.server.PlayerStorage;
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
@@ -84,6 +85,10 @@ public class World {
|
||||
private ScheduledFuture<?> mountsSchedule;
|
||||
private long mountUpdate;
|
||||
|
||||
private Map<HiredMerchant, Byte> activeMerchants = new LinkedHashMap<>();
|
||||
private ScheduledFuture<?> MerchantsSchedule;
|
||||
private long merchantUpdate;
|
||||
|
||||
private ScheduledFuture<?> charactersSchedule;
|
||||
|
||||
public World(int world, int flag, String eventmsg, int exprate, int droprate, int mesorate, int bossdroprate) {
|
||||
@@ -773,6 +778,48 @@ public class World {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerHiredMerchant(HiredMerchant hm) {
|
||||
synchronized(activeMerchants) {
|
||||
byte initProc;
|
||||
if(System.currentTimeMillis() - merchantUpdate > 5 * 60 * 1000) initProc = 1;
|
||||
else initProc = 0;
|
||||
|
||||
activeMerchants.put(hm, initProc);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterHiredMerchant(HiredMerchant hm) {
|
||||
synchronized(activeMerchants) {
|
||||
activeMerchants.remove(hm);
|
||||
}
|
||||
}
|
||||
|
||||
public void runHiredMerchantSchedule() {
|
||||
Map<HiredMerchant, Byte> deployedMerchants;
|
||||
synchronized(activeMerchants) {
|
||||
merchantUpdate = System.currentTimeMillis();
|
||||
deployedMerchants = Collections.unmodifiableMap(activeMerchants);
|
||||
}
|
||||
|
||||
for(Map.Entry<HiredMerchant, Byte> dm: deployedMerchants.entrySet()) {
|
||||
byte timeOn = dm.getValue();
|
||||
|
||||
if(timeOn <= 144) { // 1440 minutes == 24hrs
|
||||
synchronized(activeMerchants) {
|
||||
activeMerchants.put(dm.getKey(), (byte)(timeOn + 1));
|
||||
}
|
||||
} else {
|
||||
HiredMerchant hm = dm.getKey();
|
||||
hm.forceClose();
|
||||
this.getChannel(hm.getChannel()).removeHiredMerchant(hm.getOwnerId());
|
||||
|
||||
synchronized(activeMerchants) {
|
||||
activeMerchants.remove(dm.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setServerMessage(String msg) {
|
||||
for (Channel ch : channels) {
|
||||
|
||||
Reference in New Issue
Block a user