Hired Merchant & Player shop fixes + Owl of Minerva
Thanks to BenjixD DietStory's dev team, many bugs found by them have been patched (pirate quests, missing drop data, fly command, etc). Implemented Owl of Minerva. Fixed many issues with Hired Merchant and Player Shops. Fixed an error with the slot checking system. Added Wish Tickets (circa-2006 GMS event) to be dropped on AmoriaPQ.
This commit is contained in:
@@ -71,6 +71,7 @@ import java.util.Calendar;
|
||||
import server.quest.MapleQuest;
|
||||
|
||||
public class Server implements Runnable {
|
||||
private static final Set<Integer> activeFly = new HashSet<>();
|
||||
private static final Map<Integer, Integer> couponRates = new LinkedHashMap<>();
|
||||
private static final List<Integer> activeCoupons = new LinkedList<>();
|
||||
|
||||
@@ -699,6 +700,18 @@ public class Server implements Runnable {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void changeFly(Integer accountid, boolean canFly) {
|
||||
if(canFly) {
|
||||
activeFly.add(accountid);
|
||||
} else {
|
||||
activeFly.remove(accountid);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canFly(Integer accountid) {
|
||||
return activeFly.contains(accountid);
|
||||
}
|
||||
|
||||
public World getWorld(int id) {
|
||||
return worlds.get(id);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ import server.TimerManager;
|
||||
import server.events.gm.MapleEvent;
|
||||
import server.expeditions.MapleExpedition;
|
||||
import server.expeditions.MapleExpeditionType;
|
||||
import server.maps.HiredMerchant;
|
||||
import server.maps.MapleHiredMerchant;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleMapFactory;
|
||||
import tools.MaplePacketCreator;
|
||||
@@ -73,7 +73,7 @@ public final class Channel {
|
||||
private String ip, serverMessage;
|
||||
private MapleMapFactory mapFactory;
|
||||
private EventScriptManager eventSM;
|
||||
private Map<Integer, HiredMerchant> hiredMerchants = new HashMap<>();
|
||||
private Map<Integer, MapleHiredMerchant> hiredMerchants = new HashMap<>();
|
||||
private final Map<Integer, Integer> storedVars = new HashMap<>();
|
||||
private ReentrantReadWriteLock merchant_lock = new ReentrantReadWriteLock(true);
|
||||
private ReadLock merchRlock = merchant_lock.readLock();
|
||||
@@ -152,7 +152,7 @@ public final class Channel {
|
||||
public void closeAllMerchants() {
|
||||
merchWlock.lock();
|
||||
try {
|
||||
final Iterator<HiredMerchant> hmit = hiredMerchants.values().iterator();
|
||||
final Iterator<MapleHiredMerchant> hmit = hiredMerchants.values().iterator();
|
||||
while (hmit.hasNext()) {
|
||||
hmit.next().forceClose();
|
||||
hmit.remove();
|
||||
@@ -246,7 +246,7 @@ public final class Channel {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, HiredMerchant> getHiredMerchants() {
|
||||
public Map<Integer, MapleHiredMerchant> getHiredMerchants() {
|
||||
merchRlock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableMap(hiredMerchants);
|
||||
@@ -255,7 +255,7 @@ public final class Channel {
|
||||
}
|
||||
}
|
||||
|
||||
public void addHiredMerchant(int chrid, HiredMerchant hm) {
|
||||
public void addHiredMerchant(int chrid, MapleHiredMerchant hm) {
|
||||
merchWlock.lock();
|
||||
try {
|
||||
hiredMerchants.put(chrid, hm);
|
||||
|
||||
@@ -75,7 +75,7 @@ public class FredrickHandler extends AbstractMaplePacketHandler {
|
||||
Item item = items.get(i).getLeft();
|
||||
MapleInventoryManipulator.addFromDrop(c, item, false);
|
||||
String itemName = MapleItemInformationProvider.getInstance().getName(item.getItemId());
|
||||
FilePrinter.printError(FilePrinter.FREDRICK + chr.getName() + ".txt", chr.getName() + " gained " + item.getQuantity() + " " + itemName + " (" + item.getItemId() + ")\r\n");
|
||||
FilePrinter.print(FilePrinter.FREDRICK + chr.getName() + ".txt", chr.getName() + " gained " + item.getQuantity() + " " + itemName + " (" + item.getItemId() + ")\r\n");
|
||||
}
|
||||
c.announce(MaplePacketCreator.fredrickMessage((byte) 0x1E));
|
||||
|
||||
@@ -97,12 +97,7 @@ public class FredrickHandler extends AbstractMaplePacketHandler {
|
||||
if (chr.getMeso() + chr.getMerchantMeso() < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!MapleInventory.checkSpots(chr, items)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return MapleInventory.checkSpotsAndOwnership(chr, items);
|
||||
}
|
||||
|
||||
private static boolean deleteItems(MapleCharacter chr) {
|
||||
|
||||
@@ -26,7 +26,7 @@ import client.MapleCharacter;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import client.MapleClient;
|
||||
import constants.ServerConstants;
|
||||
import constants.GameConstants;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import tools.MaplePacketCreator;
|
||||
@@ -39,7 +39,7 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
public final class HiredMerchantRequest extends AbstractMaplePacketHandler {
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
if (chr.getMap().getMapObjectsInRange(chr.getPosition(), 23000, Arrays.asList(MapleMapObjectType.HIRED_MERCHANT)).isEmpty() && ((ServerConstants.USE_MERCHANT_ANYWHERE && chr.getMapId() != 910000000) || (chr.getMapId() > 910000000 && chr.getMapId() < 910000023))) {
|
||||
if (chr.getMap().getMapObjectsInRange(chr.getPosition(), 23000, Arrays.asList(MapleMapObjectType.HIRED_MERCHANT)).isEmpty() && (GameConstants.isFreeMarketRoom(chr.getMapId()))) {
|
||||
if (!chr.hasMerchant()) {
|
||||
try {
|
||||
if (ItemFactory.MERCHANT.loadItems(chr.getId(), false).isEmpty() && chr.getMerchantMeso() == 0) {
|
||||
|
||||
@@ -27,7 +27,7 @@ import net.SendOpcode;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import tools.data.output.MaplePacketLittleEndianWriter;
|
||||
|
||||
public final class NPCAnimation extends AbstractMaplePacketHandler {
|
||||
public final class NPCAnimationHandler extends AbstractMaplePacketHandler {
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
|
||||
int length = (int) slea.available();
|
||||
106
src/net/server/channel/handlers/OwlWarpHandler.java
Normal file
106
src/net/server/channel/handlers/OwlWarpHandler.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
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.channel.handlers;
|
||||
|
||||
import constants.GameConstants;
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import server.MaplePlayerShop;
|
||||
import server.maps.MapleHiredMerchant;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/*
|
||||
* @author Ronan
|
||||
*/
|
||||
public final class OwlWarpHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
int ownerid = slea.readInt();
|
||||
int mapid = slea.readInt();
|
||||
|
||||
MapleHiredMerchant hm = c.getWorldServer().getHiredMerchant(ownerid); // if both hired merchant and player shop is on the same map
|
||||
MaplePlayerShop ps;
|
||||
if(hm == null || hm.getMapId() != mapid || !hm.hasItem(c.getPlayer().getOwlSearch())) {
|
||||
ps = c.getWorldServer().getPlayerShop(ownerid);
|
||||
if(ps == null || ps.getMapId() != mapid || !ps.hasItem(c.getPlayer().getOwlSearch())) {
|
||||
if(hm == null && ps == null) c.announce(MaplePacketCreator.getOwlMessage(1));
|
||||
else c.announce(MaplePacketCreator.getOwlMessage(3));
|
||||
return;
|
||||
}
|
||||
|
||||
if(ps.isOpen()) {
|
||||
if(GameConstants.isFreeMarketRoom(mapid)) {
|
||||
if(ps.getChannel() == c.getChannel()) {
|
||||
c.getPlayer().changeMap(mapid);
|
||||
|
||||
if(ps.isOpen()) { //change map has a delay, must double check
|
||||
if(!ps.visitShop(c.getPlayer())) {
|
||||
if(!ps.isBanned(c.getPlayer().getName())) c.announce(MaplePacketCreator.getOwlMessage(2));
|
||||
else c.announce(MaplePacketCreator.getOwlMessage(17));
|
||||
}
|
||||
} else {
|
||||
//c.announce(MaplePacketCreator.serverNotice(1, "That merchant has either been closed or is under maintenance."));
|
||||
c.announce(MaplePacketCreator.getOwlMessage(18));
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "That shop is currently located in another channel. Current location: Channel " + hm.getChannel() + ", '" + hm.getMap().getMapName() + "'."));
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "That shop is currently located outside of the FM area. Current location: Channel " + hm.getChannel() + ", '" + hm.getMap().getMapName() + "'."));
|
||||
}
|
||||
} else {
|
||||
//c.announce(MaplePacketCreator.serverNotice(1, "That merchant has either been closed or is under maintenance."));
|
||||
c.announce(MaplePacketCreator.getOwlMessage(18));
|
||||
}
|
||||
} else {
|
||||
if(hm.isOpen()) {
|
||||
if(GameConstants.isFreeMarketRoom(mapid)) {
|
||||
if(hm.getChannel() == c.getChannel()) {
|
||||
c.getPlayer().changeMap(mapid);
|
||||
|
||||
if(hm.isOpen()) { //change map has a delay, must double check
|
||||
if(hm.addVisitor(c.getPlayer())) {
|
||||
c.announce(MaplePacketCreator.getHiredMerchant(c.getPlayer(), hm, false));
|
||||
c.getPlayer().setHiredMerchant(hm);
|
||||
} else {
|
||||
//c.announce(MaplePacketCreator.serverNotice(1, hm.getOwner() + "'s merchant is full. Wait awhile before trying again."));
|
||||
c.announce(MaplePacketCreator.getOwlMessage(2));
|
||||
}
|
||||
} else {
|
||||
//c.announce(MaplePacketCreator.serverNotice(1, "That merchant has either been closed or is under maintenance."));
|
||||
c.announce(MaplePacketCreator.getOwlMessage(18));
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "That merchant is currently located in another channel. Current location: Channel " + hm.getChannel() + ", '" + hm.getMap().getMapName() + "'."));
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.serverNotice(1, "That merchant is currently located outside of the FM area. Current location: Channel " + hm.getChannel() + ", '" + hm.getMap().getMapName() + "'."));
|
||||
}
|
||||
} else {
|
||||
//c.announce(MaplePacketCreator.serverNotice(1, "That merchant has either been closed or is under maintenance."));
|
||||
c.announce(MaplePacketCreator.getOwlMessage(18));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,20 +33,19 @@ import constants.ServerConstants;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.Server;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MapleMiniGame;
|
||||
import server.MaplePlayerShop;
|
||||
import server.MaplePlayerShopItem;
|
||||
import server.MapleTrade;
|
||||
import constants.GameConstants;
|
||||
import server.maps.FieldLimit;
|
||||
import server.maps.HiredMerchant;
|
||||
import server.maps.MapleHiredMerchant;
|
||||
import server.maps.MapleMapObject;
|
||||
import server.maps.MapleMapObjectType;
|
||||
import tools.FilePrinter;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/**
|
||||
@@ -114,6 +113,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
byte mode = slea.readByte();
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
|
||||
if (mode == Action.CREATE.getCode()) {
|
||||
byte createType = slea.readByte();
|
||||
if (createType == 3) {// trade
|
||||
@@ -164,15 +164,16 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chr.getMapId() > 910000000 && chr.getMapId() < 910000023 || itemId > 5030000 && itemId < 5030012 || itemId > 5140000 && itemId < 5140006) {
|
||||
if (GameConstants.isFreeMarketRoom(chr.getMapId()) || itemId > 5030000 && itemId < 5030012 || itemId > 5140000 && itemId < 5140006) {
|
||||
if (createType == 4) {
|
||||
MaplePlayerShop shop = new MaplePlayerShop(c.getPlayer(), desc);
|
||||
chr.setPlayerShop(shop);
|
||||
chr.getMap().addMapObject(shop);
|
||||
shop.sendShop(c);
|
||||
c.announce(MaplePacketCreator.getPlayerShopRemoveVisitor(1));
|
||||
c.getWorldServer().registerPlayerShop(shop);
|
||||
//c.announce(MaplePacketCreator.getPlayerShopRemoveVisitor(1));
|
||||
} else {
|
||||
HiredMerchant merchant = new HiredMerchant(chr, itemId, desc);
|
||||
MapleHiredMerchant merchant = new MapleHiredMerchant(chr, itemId, desc);
|
||||
chr.setHiredMerchant(merchant);
|
||||
c.getWorldServer().registerHiredMerchant(merchant);
|
||||
chr.getClient().getChannelServer().addHiredMerchant(chr.getId(), merchant);
|
||||
@@ -201,15 +202,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
MapleMapObject ob = chr.getMap().getMapObject(oid);
|
||||
if (ob instanceof MaplePlayerShop) {
|
||||
MaplePlayerShop shop = (MaplePlayerShop) ob;
|
||||
if (shop.isBanned(chr.getName())) {
|
||||
chr.dropMessage(1, "You have been banned from this store.");
|
||||
return;
|
||||
}
|
||||
if (shop.hasFreeSlot() && !shop.isVisitor(c.getPlayer())) {
|
||||
shop.addVisitor(c.getPlayer());
|
||||
chr.setPlayerShop(shop);
|
||||
shop.sendShop(c);
|
||||
}
|
||||
shop.visitShop(chr);
|
||||
} else if (ob instanceof MapleMiniGame) {
|
||||
MapleMiniGame game = (MapleMiniGame) ob;
|
||||
if (game.hasFreeSlot() && !game.isVisitor(c.getPlayer())) {
|
||||
@@ -226,14 +219,15 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
} else {
|
||||
chr.getClient().announce(MaplePacketCreator.getMiniGameFull());
|
||||
}
|
||||
} else if (ob instanceof HiredMerchant && chr.getHiredMerchant() == null) {
|
||||
HiredMerchant merchant = (HiredMerchant) ob;
|
||||
} else if (ob instanceof MapleHiredMerchant && chr.getHiredMerchant() == null) {
|
||||
MapleHiredMerchant merchant = (MapleHiredMerchant) ob;
|
||||
if (merchant.isOwner(c.getPlayer())) {
|
||||
merchant.setOpen(false);
|
||||
merchant.removeAllVisitors("");
|
||||
merchant.removeAllVisitors();
|
||||
|
||||
c.announce(MaplePacketCreator.getHiredMerchant(chr, merchant, false));
|
||||
} else if (!merchant.isOpen()) {
|
||||
chr.dropMessage(1, "This shop is in maintenance, please come by later.");
|
||||
c.announce(MaplePacketCreator.hiredMerchantMaintenanceMessage());
|
||||
return;
|
||||
} else if (merchant.getFreeSlotThreadsafe() == -1) {
|
||||
chr.dropMessage(1, "This shop has reached it's maximum capacity, please come by later.");
|
||||
@@ -246,7 +240,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
}
|
||||
} else if (mode == Action.CHAT.getCode()) { // chat lol
|
||||
HiredMerchant merchant = chr.getHiredMerchant();
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (chr.getTrade() != null) {
|
||||
chr.getTrade().chat(slea.readMapleAsciiString());
|
||||
} else if (chr.getPlayerShop() != null) { //mini game
|
||||
@@ -272,10 +266,18 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
} else if (mode == Action.OPEN.getCode()) {
|
||||
MaplePlayerShop shop = chr.getPlayerShop();
|
||||
HiredMerchant merchant = chr.getHiredMerchant();
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (shop != null && shop.isOwner(c.getPlayer())) {
|
||||
slea.readByte();//01
|
||||
|
||||
if(ServerConstants.USE_ERASE_PERMIT_ON_OPENSHOP) {
|
||||
try {
|
||||
MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, 5140000, 1, true, false);
|
||||
} catch(RuntimeException re) {} // fella does not have a player shop permit...
|
||||
}
|
||||
|
||||
chr.getMap().broadcastMessage(MaplePacketCreator.addCharBox(c.getPlayer(), 4));
|
||||
shop.setOpen(true);
|
||||
} else if (merchant != null && merchant.isOwner(c.getPlayer())) {
|
||||
chr.setHasMerchant(true);
|
||||
merchant.setOpen(true);
|
||||
@@ -430,7 +432,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
sellItem.setQuantity(perBundle);
|
||||
MaplePlayerShopItem item = new MaplePlayerShopItem(sellItem, bundles, price);
|
||||
MaplePlayerShop shop = chr.getPlayerShop();
|
||||
HiredMerchant merchant = chr.getHiredMerchant();
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (shop != null && shop.isOwner(c.getPlayer())) {
|
||||
if (ivItem != null && ivItem.getQuantity() >= bundles * perBundle) {
|
||||
shop.addItem(item);
|
||||
@@ -476,7 +478,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
c.announce(MaplePacketCreator.updateHiredMerchant(chr.getHiredMerchant(), chr));
|
||||
}*/
|
||||
} else if (mode == Action.MERCHANT_ORGANIZE.getCode()) {
|
||||
HiredMerchant merchant = chr.getHiredMerchant();
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (!merchant.isOwner(chr)) return;
|
||||
|
||||
if (chr.getMerchantMeso() > 0) {
|
||||
@@ -513,19 +515,16 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
return;
|
||||
}
|
||||
MaplePlayerShop shop = chr.getPlayerShop();
|
||||
HiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (merchant != null && merchant.getOwner().equals(chr.getName())) {
|
||||
return;
|
||||
}
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (shop != null && shop.isVisitor(c.getPlayer())) {
|
||||
shop.buy(c, item, quantity);
|
||||
shop.broadcast(MaplePacketCreator.getPlayerShopItemUpdate(shop));
|
||||
} else if (merchant != null) {
|
||||
} else if (merchant != null && !merchant.isOwner(chr)) {
|
||||
merchant.buy(c, item, quantity);
|
||||
merchant.broadcastToVisitorsThreadsafe(MaplePacketCreator.updateHiredMerchant(merchant, c.getPlayer()));
|
||||
}
|
||||
} else if (mode == Action.TAKE_ITEM_BACK.getCode()) {
|
||||
HiredMerchant merchant = chr.getHiredMerchant();
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (merchant != null && merchant.isOwner(c.getPlayer())) {
|
||||
int slot = slea.readShort();
|
||||
MaplePlayerShopItem item = merchant.getItems().get(slot);
|
||||
@@ -542,7 +541,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
c.announce(MaplePacketCreator.updateHiredMerchant(merchant, c.getPlayer()));
|
||||
}
|
||||
} else if (mode == Action.CLOSE_MERCHANT.getCode()) {
|
||||
HiredMerchant merchant = chr.getHiredMerchant();
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (merchant != null && merchant.isOwner(c.getPlayer())) {
|
||||
c.announce(MaplePacketCreator.hiredMerchantOwnerLeave());
|
||||
c.announce(MaplePacketCreator.leaveHiredMerchant(0x00, 0x03));
|
||||
@@ -550,18 +549,23 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
chr.setHasMerchant(false);
|
||||
}
|
||||
} else if (mode == Action.MAINTENANCE_OFF.getCode()) {
|
||||
HiredMerchant merchant = chr.getHiredMerchant();
|
||||
if (merchant.getItems().isEmpty() && merchant.isOwner(c.getPlayer())) {
|
||||
merchant.closeShop(c, false);
|
||||
chr.setHasMerchant(false);
|
||||
}
|
||||
if (merchant != null && merchant.isOwner(c.getPlayer())) {
|
||||
merchant.clearMessages();
|
||||
merchant.setOpen(true);
|
||||
MapleHiredMerchant merchant = chr.getHiredMerchant();
|
||||
if(merchant != null) {
|
||||
if (merchant.getItems().isEmpty() && merchant.isOwner(c.getPlayer())) {
|
||||
merchant.closeShop(c, false);
|
||||
chr.setHasMerchant(false);
|
||||
}
|
||||
if (merchant.isOwner(c.getPlayer())) {
|
||||
merchant.clearMessages();
|
||||
merchant.setOpen(true);
|
||||
}
|
||||
}
|
||||
|
||||
chr.setHiredMerchant(null);
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
} else if (mode == Action.BAN_PLAYER.getCode()) {
|
||||
slea.skip(1);
|
||||
|
||||
if (chr.getPlayerShop() != null && chr.getPlayerShop().isOwner(c.getPlayer())) {
|
||||
chr.getPlayerShop().banPlayer(slea.readMapleAsciiString());
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
*/
|
||||
if (player.isGM()){
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.earnTitleMessage("GM " + player.getName() + " has logged in"));
|
||||
Server.getInstance().broadcastGMMessage(MaplePacketCreator.earnTitleMessage((player.gmLevel() < 6 ? "GM " : "Admin ") + player.getName() + " has logged in"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,9 +25,7 @@ package net.server.channel.handlers;
|
||||
import client.MapleCharacter;
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import net.server.channel.Channel;
|
||||
import net.server.Server;
|
||||
import server.maps.HiredMerchant;
|
||||
import server.maps.MapleHiredMerchant;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
@@ -38,30 +36,27 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
public class RemoteStoreHandler extends AbstractMaplePacketHandler {
|
||||
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
HiredMerchant hm = getMerchant(c);
|
||||
MapleHiredMerchant hm = getMerchant(c);
|
||||
if (chr.hasMerchant() && hm != null) {
|
||||
if (hm.getChannel() == chr.getClient().getChannel()) {
|
||||
hm.setOpen(false);
|
||||
hm.removeAllVisitors("");
|
||||
hm.removeAllVisitors();
|
||||
chr.setHiredMerchant(hm);
|
||||
|
||||
chr.announce(MaplePacketCreator.getHiredMerchant(chr, hm, false));
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.remoteChannelChange((byte) (hm.getChannel() - 1)));
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
chr.dropMessage(1, "You don't have a Merchant open");
|
||||
chr.dropMessage(1, "You don't have a Merchant open.");
|
||||
}
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
}
|
||||
|
||||
public HiredMerchant getMerchant(MapleClient c) {
|
||||
private MapleHiredMerchant getMerchant(MapleClient c) {
|
||||
if (c.getPlayer().hasMerchant()) {
|
||||
for (Channel cserv : Server.getInstance().getChannelsFromWorld(c.getWorld())) {
|
||||
if (cserv.getHiredMerchants().get(c.getPlayer().getId()) != null) {
|
||||
return cserv.getHiredMerchants().get(c.getPlayer().getId());
|
||||
}
|
||||
}
|
||||
return c.getWorldServer().getHiredMerchant(c.getPlayer().getId());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -45,9 +45,11 @@ import net.server.Server;
|
||||
import scripting.npc.NPCScriptManager;
|
||||
import server.MapleInventoryManipulator;
|
||||
import server.MapleItemInformationProvider;
|
||||
import server.MaplePlayerShopItem;
|
||||
import server.MapleShop;
|
||||
import server.MapleShopFactory;
|
||||
import server.TimerManager;
|
||||
import server.maps.AbstractMapleMapObject;
|
||||
import server.maps.MapleMap;
|
||||
import server.maps.MapleTVEffect;
|
||||
import tools.MaplePacketCreator;
|
||||
@@ -436,6 +438,16 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
|
||||
player.gainMeso(ii.getMeso(itemId), true, false, true);
|
||||
remove(c, itemId);
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
} else if (itemType == 523) {
|
||||
int itemid = slea.readInt();
|
||||
|
||||
player.setOwlSearch(itemid);
|
||||
List<Pair<MaplePlayerShopItem, AbstractMapleMapObject>> hmsAvailable = c.getWorldServer().getAvailableItemBundles(itemid);
|
||||
if(!hmsAvailable.isEmpty()) remove(c, itemId);
|
||||
|
||||
c.announce(MaplePacketCreator.owlOfMinerva(c, itemid, hmsAvailable));
|
||||
c.announce(MaplePacketCreator.enableActions());
|
||||
|
||||
} else if (itemType == 524) {
|
||||
for (byte i = 0; i < 3; i++) {
|
||||
MaplePet pet = player.getPet(i);
|
||||
|
||||
35
src/net/server/channel/handlers/UseOwlOfMinervaHandler.java
Normal file
35
src/net/server/channel/handlers/UseOwlOfMinervaHandler.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
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.channel.handlers;
|
||||
|
||||
import client.MapleClient;
|
||||
import net.AbstractMaplePacketHandler;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
public final class UseOwlOfMinervaHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
c.announce(MaplePacketCreator.getOwlOpen());
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
*
|
||||
* @author AngelSL
|
||||
*/
|
||||
public final class UseSummonBag extends AbstractMaplePacketHandler {
|
||||
public final class UseSummonBagHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
@@ -46,7 +46,7 @@ public class RankingWorker implements Runnable {
|
||||
}
|
||||
|
||||
private void updateRanking(int job, int world) throws SQLException {
|
||||
String sqlCharSelect = "SELECT c.id, " + (job != -1 ? "c.jobRank, c.jobRankMove" : "c.rank, c.rankMove") + ", a.lastlogin AS lastlogin, a.loggedin FROM characters AS c LEFT JOIN accounts AS a ON c.accountid = a.id WHERE c.world = ? ";
|
||||
String sqlCharSelect = "SELECT c.id, " + (job != -1 ? "c.jobRank, c.jobRankMove" : "c.rank, c.rankMove") + ", a.lastlogin AS lastlogin, a.loggedin FROM characters AS c LEFT JOIN accounts AS a ON c.accountid = a.id WHERE c.gm < 2 AND c.world = ? ";
|
||||
if (job != -1) {
|
||||
sqlCharSelect += "AND c.job DIV 100 = ? ";
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
@@ -45,7 +46,8 @@ import java.util.HashSet;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import server.TimerManager;
|
||||
import server.maps.HiredMerchant;
|
||||
import server.maps.MapleHiredMerchant;
|
||||
import server.MaplePlayerShop;
|
||||
import net.server.worker.CharacterAutosaverWorker;
|
||||
import net.server.worker.MountTirednessWorker;
|
||||
import net.server.worker.PetFullnessWorker;
|
||||
@@ -56,8 +58,11 @@ import net.server.channel.CharacterIdChannelPair;
|
||||
import net.server.guild.MapleGuild;
|
||||
import net.server.guild.MapleGuildCharacter;
|
||||
import net.server.guild.MapleGuildSummary;
|
||||
import server.MaplePlayerShopItem;
|
||||
import server.maps.AbstractMapleMapObject;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
import tools.Pair;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -85,9 +90,11 @@ public class World {
|
||||
private ScheduledFuture<?> mountsSchedule;
|
||||
private long mountUpdate;
|
||||
|
||||
private Map<HiredMerchant, Byte> activeMerchants = new LinkedHashMap<>();
|
||||
private Map<Integer, Pair<MapleHiredMerchant, Byte>> activeMerchants = new LinkedHashMap<>();
|
||||
private long merchantUpdate;
|
||||
|
||||
private Map<Integer, MaplePlayerShop> activePlayerShops = new LinkedHashMap<>();
|
||||
|
||||
private ScheduledFuture<?> charactersSchedule;
|
||||
|
||||
public World(int world, int flag, String eventmsg, int exprate, int droprate, int mesorate, int bossdroprate) {
|
||||
@@ -778,47 +785,96 @@ public class World {
|
||||
}
|
||||
}
|
||||
|
||||
public void registerHiredMerchant(HiredMerchant hm) {
|
||||
public void registerPlayerShop(MaplePlayerShop ps) {
|
||||
synchronized(activePlayerShops) {
|
||||
activePlayerShops.put(ps.getOwner().getId(), ps);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterPlayerShop(MaplePlayerShop ps) {
|
||||
synchronized(activePlayerShops) {
|
||||
activePlayerShops.remove(ps.getOwner().getId());
|
||||
}
|
||||
}
|
||||
|
||||
public List<MaplePlayerShop> getActivePlayerShops() {
|
||||
List<MaplePlayerShop> psList = new ArrayList<>();
|
||||
synchronized(activePlayerShops) {
|
||||
for(MaplePlayerShop mps : activePlayerShops.values()) {
|
||||
psList.add(mps);
|
||||
}
|
||||
|
||||
return psList;
|
||||
}
|
||||
}
|
||||
|
||||
public MaplePlayerShop getPlayerShop(int ownerid) {
|
||||
synchronized(activePlayerShops) {
|
||||
return activePlayerShops.get(ownerid);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerHiredMerchant(MapleHiredMerchant hm) {
|
||||
synchronized(activeMerchants) {
|
||||
byte initProc;
|
||||
if(System.currentTimeMillis() - merchantUpdate > 5 * 60 * 1000) initProc = 1;
|
||||
else initProc = 0;
|
||||
|
||||
activeMerchants.put(hm, initProc);
|
||||
activeMerchants.put(hm.getOwnerId(), new Pair<>(hm, initProc));
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterHiredMerchant(HiredMerchant hm) {
|
||||
public void unregisterHiredMerchant(MapleHiredMerchant hm) {
|
||||
synchronized(activeMerchants) {
|
||||
activeMerchants.remove(hm);
|
||||
activeMerchants.remove(hm.getOwnerId());
|
||||
}
|
||||
}
|
||||
|
||||
public void runHiredMerchantSchedule() {
|
||||
Map<HiredMerchant, Byte> deployedMerchants;
|
||||
Map<Integer, Pair<MapleHiredMerchant, Byte>> deployedMerchants;
|
||||
synchronized(activeMerchants) {
|
||||
merchantUpdate = System.currentTimeMillis();
|
||||
deployedMerchants = Collections.unmodifiableMap(activeMerchants);
|
||||
}
|
||||
deployedMerchants = new LinkedHashMap<>(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());
|
||||
for(Map.Entry<Integer, Pair<MapleHiredMerchant, Byte>> dm: deployedMerchants.entrySet()) {
|
||||
byte timeOn = dm.getValue().getRight();
|
||||
MapleHiredMerchant hm = dm.getValue().getLeft();
|
||||
|
||||
synchronized(activeMerchants) {
|
||||
if(timeOn <= 144) { // 1440 minutes == 24hrs
|
||||
activeMerchants.put(hm.getOwnerId(), new Pair<>(dm.getValue().getLeft(), (byte)(timeOn + 1)));
|
||||
} else {
|
||||
hm.forceClose();
|
||||
this.getChannel(hm.getChannel()).removeHiredMerchant(hm.getOwnerId());
|
||||
|
||||
activeMerchants.remove(dm.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<MapleHiredMerchant> getActiveMerchants() {
|
||||
List<MapleHiredMerchant> hmList = new ArrayList<>();
|
||||
synchronized(activeMerchants) {
|
||||
for(Pair<MapleHiredMerchant, Byte> hmp : activeMerchants.values()) {
|
||||
MapleHiredMerchant hm = hmp.getLeft();
|
||||
if(hm.isOpen()) {
|
||||
hmList.add(hm);
|
||||
}
|
||||
}
|
||||
|
||||
return hmList;
|
||||
}
|
||||
}
|
||||
|
||||
public MapleHiredMerchant getHiredMerchant(int ownerid) {
|
||||
synchronized(activeMerchants) {
|
||||
if(activeMerchants.containsKey(ownerid)) {
|
||||
return activeMerchants.get(ownerid).getLeft();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setServerMessage(String msg) {
|
||||
for (Channel ch : channels) {
|
||||
@@ -832,6 +888,36 @@ public class World {
|
||||
}
|
||||
}
|
||||
|
||||
public List<Pair<MaplePlayerShopItem, AbstractMapleMapObject>> getAvailableItemBundles(int itemid) {
|
||||
List<Pair<MaplePlayerShopItem, AbstractMapleMapObject>> hmsAvailable = new ArrayList<>();
|
||||
|
||||
for (MapleHiredMerchant hm : getActiveMerchants()) {
|
||||
List<MaplePlayerShopItem> itemBundles = hm.sendAvailableBundles(itemid);
|
||||
|
||||
for(MaplePlayerShopItem mpsi : itemBundles) {
|
||||
hmsAvailable.add(new Pair<>(mpsi, (AbstractMapleMapObject) hm));
|
||||
}
|
||||
}
|
||||
|
||||
for (MaplePlayerShop ps : getActivePlayerShops()) {
|
||||
List<MaplePlayerShopItem> itemBundles = ps.sendAvailableBundles(itemid);
|
||||
|
||||
for(MaplePlayerShopItem mpsi : itemBundles) {
|
||||
hmsAvailable.add(new Pair<>(mpsi, (AbstractMapleMapObject) ps));
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(hmsAvailable, new Comparator<Pair<MaplePlayerShopItem, AbstractMapleMapObject>>() {
|
||||
@Override
|
||||
public int compare(Pair<MaplePlayerShopItem, AbstractMapleMapObject> p1, Pair<MaplePlayerShopItem, AbstractMapleMapObject> p2) {
|
||||
return p1.getLeft().getPrice() - p2.getLeft().getPrice();
|
||||
}
|
||||
});
|
||||
|
||||
hmsAvailable.subList(0, Math.min(hmsAvailable.size(), 200)); //truncates the list to have up to 200 elements
|
||||
return hmsAvailable;
|
||||
}
|
||||
|
||||
public final void shutdown() {
|
||||
for (Channel ch : getChannels()) {
|
||||
ch.shutdown();
|
||||
|
||||
Reference in New Issue
Block a user