• Unfortunately, we have experienced significant hard drive damage that requires urgent maintenance and rebuilding. The forum will be a state of read only until we install our new drives and rebuild all the configurations needed. Please follow our Facebook page for updates, we will be back up shortly! (The forum could go offline at any given time due to the nature of the failed drives whilst awaiting the upgrades.) When you see an Incapsula error, you know we are in the process of migration.

Multi-World MoopleDEV Bugs

Newbie Spellweaver
Joined
Jan 23, 2011
Messages
36
Reaction score
0
I tried to open 2 world at the same time and i got 2 errors in Bera.
1. Can't use Messenger(cash item) and command "Notice".
PHP:
public final class MapleMessenger {
	
    private int id;
    private List<MapleMessengerCharacter> members = new ArrayList<MapleMessengerCharacter>(3);
    private boolean[] pos = new boolean[3];

    public MapleMessenger(int id, MapleMessengerCharacter chrfor) {
        this.id = id;  
    	for (int i = 0; i < 3; i++){
    		pos[i] = false;
    	}
        addMember(chrfor, chrfor.getPosition());
    }
    
    public int getId() {
        return id;
    }
    
    public Collection<MapleMessengerCharacter> getMembers() {
        return Collections.unmodifiableList(members);
    }
    
    public void addMember(MapleMessengerCharacter member, int position) {
        members.add(member);
        member.setPosition(position);
        pos[position] = true;
    }

    public void removeMember(MapleMessengerCharacter member) {
    	int position = member.getPosition();
        pos[position] = false;
        members.remove(member);
    }

    public int getLowestPosition() {
        for (byte i = 0; i < 3; i++) {
            if (!pos[i]) {
                return i;
            }
        }
        return -1;
    }

    public int getPositionByName(String name) {
        for (MapleMessengerCharacter messengerchar : members) {
            if (messengerchar.getName().equals(name)) {
                return messengerchar.getPosition();
            }
        }
        return -1;
    }
}
PHP:
public final class MessengerHandler extends AbstractMaplePacketHandler {
    public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
        String input;
        byte mode = slea.readByte();
        MapleCharacter player = c.getPlayer();
        World world = c.getWorldServer();
        MapleMessenger messenger = player.getMessenger();
        switch (mode) {
            case 0x00:
                if (messenger == null) {
                    int messengerid = slea.readInt();
                    if (messengerid == 0) {
                        MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, 0);
                        messenger = world.createMessenger(messengerplayer);
                        player.setMessenger(messenger);
                        player.setMessengerPosition(0);
                    } else {
                        messenger = world.getMessenger(messengerid);
                        int position = messenger.getLowestPosition();
                        MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, position);
                        if (messenger.getMembers().size() < 3) {
                            player.setMessenger(messenger);
                            player.setMessengerPosition(position);
                            world.joinMessenger(messenger.getId(), messengerplayer, player.getName(), messengerplayer.getChannel());
                        }
                    }
                }
                break;
            case 0x02:
                if (messenger != null) {
                    MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, player.getMessengerPosition());
                    world.leaveMessenger(messenger.getId(), messengerplayer);
                    player.setMessenger(null);
                    player.setMessengerPosition(4);
                }
                break;
            case 0x03:
                if (messenger.getMembers().size() < 3) {
                    input = slea.readMapleAsciiString();
                    MapleCharacter target = c.getChannelServer().getPlayerStorage().getCharacterByName(input);
                    if (target != null) {
                        if (target.getMessenger() == null) {
                            target.getClient().announce(MaplePacketCreator.messengerInvite(c.getPlayer().getName(), messenger.getId()));
                            c.announce(MaplePacketCreator.messengerNote(input, 4, 1));
                        } else {
                            c.announce(MaplePacketCreator.messengerChat(player.getName() + " : " + input + " is already using Maple Messenger"));
                        }
                    } else {
                        if (world.find(input) > -1) {
                            world.messengerInvite(c.getPlayer().getName(), messenger.getId(), input, c.getChannel());
                        } else {
                            c.announce(MaplePacketCreator.messengerNote(input, 4, 0));
                        }
                    }
                } else {
                    c.announce(MaplePacketCreator.messengerChat(player.getName() + " : You cannot have more than 3 people in the Maple Messenger"));
                }
                break;
            case 0x05:
                String targeted = slea.readMapleAsciiString();
                MapleCharacter target = c.getChannelServer().getPlayerStorage().getCharacterByName(targeted);
                if (target != null) {
                    if (target.getMessenger() != null) {
                        target.getClient().announce(MaplePacketCreator.messengerNote(player.getName(), 5, 0));
                    }
                } else {
                    world.declineChat(targeted, player.getName());
                }
                break;
            case 0x06:
                if (messenger != null) {
                    MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, player.getMessengerPosition());
                    input = slea.readMapleAsciiString();
                    world.messengerChat(messenger, input, messengerplayer.getName());
                }
                break;
        }
    }
}
2. Can't Open Hired Merchant.
PHP:
public class HiredMerchant extends AbstractMapleMapObject {

    private int ownerId, itemId, mesos = 0;
    private int channel, world;
    private long start;
    private String ownerName = "";
    private String description = "";
    private MapleCharacter[] visitors = new MapleCharacter[3];
    private List<MaplePlayerShopItem> items = new LinkedList<>();
    private List<Pair<String, Byte>> messages = new LinkedList<>();
    private List<SoldItem> sold = new LinkedList<>();
    private boolean open;
    public ScheduledFuture<?> schedule = null;
    private MapleMap map;

    public HiredMerchant(final MapleCharacter owner, int itemId, String desc) {
        this.setPosition(owner.getPosition());
        this.start = System.currentTimeMillis();
        this.ownerId = owner.getId();
        this.channel = owner.getClient().getChannel();
        this.world = owner.getWorld();
        this.itemId = itemId;
        this.ownerName = owner.getName();
        this.description = desc;
        this.map = owner.getMap();
        this.schedule = TimerManager.getInstance().schedule(new Runnable() {

            @Override
            public void run() {
                HiredMerchant.this.forceClose();
				Server.getInstance().getChannel(world, channel).removeHiredMerchant(ownerId);
            }
        }, 1000 * 60 * 60 * 24);
    }

    public void broadcastToVisitors(final byte[] packet) {
        for (MapleCharacter visitor : visitors) {
            if (visitor != null) {
                visitor.getClient().announce(packet);
            }
        }
    }

    public void addVisitor(MapleCharacter visitor) {
        int i = this.getFreeSlot();
        if (i > -1) {
            visitors[i] = visitor;
            broadcastToVisitors(MaplePacketCreator.hiredMerchantVisitorAdd(visitor, i + 1));
        }
    }

    public void removeVisitor(MapleCharacter visitor) {
        int slot = getVisitorSlot(visitor);
        if (slot < 0){ //Not found
        	return;
        }
        if (visitors[slot] != null && visitors[slot].getId() == visitor.getId()) {
            visitors[slot] = null;
            if (slot != -1) {
                broadcastToVisitors(MaplePacketCreator.hiredMerchantVisitorLeave(slot + 1));
            }
        }
    }

    public int getVisitorSlot(MapleCharacter visitor) {
        for (int i = 0; i < 3; i++) {
            if (visitors[i] != null && visitors[i].getId() == visitor.getId()){
                return i;
            }
        }
        return -1; //Actually 0 because of the +1's.
    }

    public void removeAllVisitors(String message) {
        for (int i = 0; i < 3; i++) {
            if (visitors[i] != null) {
                visitors[i].setHiredMerchant(null);
                visitors[i].getClient().announce(MaplePacketCreator.leaveHiredMerchant(i + 1, 0x11));
                if (message.length() > 0) {
                    visitors[i].dropMessage(1, message);
                }
                visitors[i] = null;
            }
        }
    }

    public void buy(MapleClient c, int item, short quantity) {
        MaplePlayerShopItem pItem = items.get(item);
        synchronized (items) {
            Item newItem = pItem.getItem().copy();
            newItem.setQuantity((short) ((pItem.getItem().getQuantity() * quantity)));
            if ((newItem.getFlag() & ItemConstants.KARMA) == ItemConstants.KARMA) {
                newItem.setFlag((byte) (newItem.getFlag() ^ ItemConstants.KARMA));
            }
            if (newItem.getType() == 2 && (newItem.getFlag() & ItemConstants.SPIKES) == ItemConstants.SPIKES) {
                newItem.setFlag((byte) (newItem.getFlag() ^ ItemConstants.SPIKES));
            }
            if (quantity < 1 || pItem.getBundles() < 1 || !pItem.isExist() || pItem.getBundles() < quantity) {
                c.announce(MaplePacketCreator.enableActions());
                return;
            } else if (newItem.getType() == 1 && newItem.getQuantity() > 1) {
                c.announce(MaplePacketCreator.enableActions());
                return;
            } else if (!pItem.isExist()) {
                c.announce(MaplePacketCreator.enableActions());
                return;
            }
            int price = pItem.getPrice() * quantity;
            if (c.getPlayer().getMeso() >= price) {
                if (MapleInventoryManipulator.addFromDrop(c, newItem, true)) {
                    c.getPlayer().gainMeso(-price, false);
                    sold.add(new SoldItem(c.getPlayer().getName(), pItem.getItem().getItemId(), quantity, price));
                    pItem.setBundles((short) (pItem.getBundles() - quantity));
                    if (pItem.getBundles() < 1) {
                        pItem.setDoesExist(false);
                    }
                    MapleCharacter owner = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterByName(ownerName);
                    if (owner != null) {
                        owner.addMerchantMesos(price);
                    } else {
                        try {
                            try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE characters SET MerchantMesos = MerchantMesos + " + price + " WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
                                ps.setInt(1, ownerId);
                                ps.executeUpdate();
                            }
                        } catch (Exception e) {
                        }
                    }
                } else {
                    c.getPlayer().dropMessage(1, "Your inventory is full. Please clean a slot before buying this item.");
                }
            } else {
                c.getPlayer().dropMessage(1, "You do not have enough mesos.");
            }
            try {
                this.saveItems(false);
            } catch (Exception e) {
            }
        }
    }

    public void forceClose() {
        if (schedule != null) {
            schedule.cancel(false);
        }
        try {
            saveItems(true);
            items.clear();
        } catch (SQLException ex) {
        }
        //Server.getInstance().getChannel(world, channel).removeHiredMerchant(ownerId);
        map.broadcastMessage(MaplePacketCreator.destroyHiredMerchant(getOwnerId()));

        map.removeMapObject(this);
		
		MapleCharacter player = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterById(ownerId);
			if(player != null) {
				player.setHasMerchant(false);
			} else {
				try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
					ps.setInt(1, ownerId);
					ps.executeUpdate();
				} catch (SQLException ex) {
					ex.printStackTrace();
				}
			}

        map = null;
        schedule = null;
    }

	public void closeShop(MapleClient c, boolean timeout) {
        map.removeMapObject(this);
        map.broadcastMessage(MaplePacketCreator.destroyHiredMerchant(ownerId));
        c.getChannelServer().removeHiredMerchant(ownerId);
        try {
			MapleCharacter player = c.getWorldServer().getPlayerStorage().getCharacterById(ownerId);
			if(player != null) {
				player.setHasMerchant(false);
			} else {
				try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) {
					ps.setInt(1, ownerId);
					ps.executeUpdate();
				}
			}
            if (check(c.getPlayer(), getItems()) && !timeout) {
                for (MaplePlayerShopItem mpsi : getItems()) {
                    if (mpsi.isExist() && (mpsi.getItem().getType() == MapleInventoryType.EQUIP.getType())) {
                        MapleInventoryManipulator.addFromDrop(c, mpsi.getItem(), false);
                    } else if (mpsi.isExist()) {
                        MapleInventoryManipulator.addById(c, mpsi.getItem().getItemId(), (short) (mpsi.getBundles() * mpsi.getItem().getQuantity()), null, -1, mpsi.getItem().getFlag(), mpsi.getItem().getExpiration());
                    }
                }
                items.clear();
            }
            try {
                this.saveItems(timeout);
            } catch (Exception e) {
            }
            items.clear();

        } catch (Exception e) {
        }
        schedule.cancel(false);
    }

    public String getOwner() {
        return ownerName;
    }
    
    public void clearItems() {
        items.clear();
    }

    public int getOwnerId() {
        return ownerId;
    }

    public String getDescription() {
        return description;
    }

    public MapleCharacter[] getVisitors() {
        return visitors;
    }

    public List<MaplePlayerShopItem> getItems() {
        return Collections.unmodifiableList(items);
    }

    public void addItem(MaplePlayerShopItem item) {
        items.add(item);
        try {
            this.saveItems(false);
        } catch (SQLException ex) {
        }
    }

    public void removeFromSlot(int slot) {
        items.remove(slot);
        try {
            this.saveItems(false);
        } catch (SQLException ex) {
        }
    }
    
    
    public int getFreeSlot() {
        for (int i = 0; i < 3; i++) {
            if (visitors[i] == null) {
                return i;
            }
        }
        return -1;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public boolean isOpen() {
        return open;
    }

    public void setOpen(boolean set) {
        this.open = set;
    }

    public int getItemId() {
        return itemId;
    }

    public boolean isOwner(MapleCharacter chr) {
        return chr.getId() == ownerId;
    }

    public void saveItems(boolean shutdown) throws SQLException {
        List<Pair<Item, MapleInventoryType>> itemsWithType = new ArrayList<>();

        for (MaplePlayerShopItem pItems : items) {
            Item newItem = pItems.getItem();
            if (shutdown) {
                newItem.setQuantity((short) (pItems.getItem().getQuantity() * pItems.getBundles()));
            } else {
                newItem.setQuantity(pItems.getItem().getQuantity());
            }
            if (pItems.getBundles() > 0) {
                itemsWithType.add(new Pair<>(newItem, MapleInventoryType.getByType(newItem.getType())));
            }
        }
		
        ItemFactory.MERCHANT.saveItems(itemsWithType, this.ownerId, DatabaseConnection.getConnection());
    }

    private static boolean check(MapleCharacter chr, List<MaplePlayerShopItem> items) {
        byte eq = 0, use = 0, setup = 0, etc = 0, cash = 0;
        List<MapleInventoryType> li = new LinkedList<>();
        for (MaplePlayerShopItem item : items) {
            final MapleInventoryType invtype = MapleItemInformationProvider.getInstance().getInventoryType(item.getItem().getItemId());
            if (!li.contains(invtype)) {
                li.add(invtype);
            }
            if (invtype == MapleInventoryType.EQUIP) {
                eq++;
            } else if (invtype == MapleInventoryType.USE) {
                use++;
            } else if (invtype == MapleInventoryType.SETUP) {
                setup++;
            } else if (invtype == MapleInventoryType.ETC) {
                etc++;
            } else if (invtype == MapleInventoryType.CASH) {
                cash++;
            }
        }
        for (MapleInventoryType mit : li) {
            if (mit == MapleInventoryType.EQUIP) {
                if (chr.getInventory(MapleInventoryType.EQUIP).getNumFreeSlot() <= eq) {
                    return false;
                }
            } else if (mit == MapleInventoryType.USE) {
                if (chr.getInventory(MapleInventoryType.USE).getNumFreeSlot() <= use) {
                    return false;
                }
            } else if (mit == MapleInventoryType.SETUP) {
                if (chr.getInventory(MapleInventoryType.SETUP).getNumFreeSlot() <= setup) {
                    return false;
                }
            } else if (mit == MapleInventoryType.ETC) {
                if (chr.getInventory(MapleInventoryType.ETC).getNumFreeSlot() <= etc) {
                    return false;
                }
            } else if (mit == MapleInventoryType.CASH) {
                if (chr.getInventory(MapleInventoryType.CASH).getNumFreeSlot() <= cash) {
                    return false;
                }
            }
        }
        return true;
    }

    public int getChannel() {
        return channel;
    }

    public int getTimeLeft() {
        return (int) ((System.currentTimeMillis() - start) / 1000);
    }

    public List<Pair<String, Byte>> getMessages() {
        return messages;
    }

    public int getMapId() {
        return map.getId();
    }

    public List<SoldItem> getSold() {
        return sold;
    }

    public int getMesos() {
        return mesos;
    }

    @Override
    public void sendDestroyData(MapleClient client) {
    }

    @Override
    public MapleMapObjectType getType() {
        return MapleMapObjectType.HIRED_MERCHANT;
    }

    @Override
    public void sendSpawnData(MapleClient client) {
        client.announce(MaplePacketCreator.spawnHiredMerchant(this));
    }

    public class SoldItem {

        int itemid, mesos;
        short quantity;
        String buyer;

        public SoldItem(String buyer, int itemid, short quantity, int mesos) {
            this.buyer = buyer;
            this.itemid = itemid;
            this.quantity = quantity;
            this.mesos = mesos;
        }

        public String getBuyer() {
            return buyer;
        }

        public int getItemId() {
            return itemid;
        }

        public short getQuantity() {
            return quantity;
        }

        public int getMesos() {
            return mesos;
        }
    }
}
Please Help.
 
Last edited:
Newbie Spellweaver
Joined
Jan 23, 2011
Messages
36
Reaction score
0
Fixed. For people having this error like me. This is a solution for you :)
Go to Server.java
add
PHP:
        for (Channel ch1 : getChannelsFromWorld(1)) {
            ch1.broadcastPacket(packet);
        }
after
PHP:
        for (Channel ch : getChannelsFromWorld(0)) {
            ch.broadcastPacket(packet);
        }
*if you have 2 worlds.
 
Upvote 0
Custom Title Activated
Loyal Member
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
Fixed. For people having this error like me. This is a solution for you :)
Go to Server.java
add
PHP:
        for (Channel ch1 : getChannelsFromWorld(1)) {
            ch1.broadcastPacket(packet);
        }
after
PHP:
        for (Channel ch : getChannelsFromWorld(0)) {
            ch.broadcastPacket(packet);
        }
*if you have 2 worlds.

Is that seriously in Moople? dafuq? no way.

Yeah no, you changed something in your source. Just checked Rev120.

It SHOULD be this:
PHP:
public void broadcastMessage(int world, final byte[] packet) {
        for (Channel ch : getChannelsFromWorld(world)) {
            ch.broadcastPacket(packet);
        }
    }

the 'world' integer should be the user's world. you get that from anywhere from PlayerStorage to the MapleClient object being handed in handlers. Just call getWorld() from the player and put that there and that's how it works. You should never hardcode worlds like that, and you should never double iterate like that either when you don't have to.
 
Upvote 0
Newbie Spellweaver
Joined
Jan 23, 2011
Messages
36
Reaction score
0
Thanks Eric
By the way, How to fix Channel Crashed by Bowman's Damages on BigFoots(9400575)? It appears often but still happening on my server. I seriously have no clue on this...:$:
 
Upvote 0
Back
Top