GMS-like Wedding + Scissors of Karma + Maple Life + Buyback

Properly developed the Marriage feature in the source.
Added TRAVEL_RATE server flag, a modifier for the travel frequency rate.
Corrected stance for players in 3rd party view when entering a map to work similarly as GMS.
Fixed mobs spamming skills incoherently.
Added code support for old GMS-like PQ NPCs, where party leaders just need to click once to start a new PQ.
Implemented podium system for the Hall of Fame PlayerNPCs.
Improved character load-out system, now using way less queries to the DB in the process.
Fixed birthday field for accounts not being read correctly.
Further implemented the incomplete yet-existing Scissors of Karma mechanic.
Fixed Duey not propagating item flags when packaging an item.
Added a custom buyback system.
Refactored the character creation system, now offering support for Maple Life.
Fixed some issues with the PlayerNPC positioning system.
Added server flag allowing AP assignment for novices (beginners under level 11).
Fixed Strategy Time (GPQ) announcement being sent twice to guilds in certain cases.
Tweaked mount EXP system now awarding it accordingly with the amount of tiredness healed.
Removed the randomness aspect of closeness gain when feeding the pet, now acting accordingly with amount of fullness gained.
Fixed an exploit with Arwen script.
Fixed travel-back from Florina forcefully sending players to Lith Harbor in certain situations.
Thoroughly reviewed job skill questlines for Explorers and Aran.
Localhost edit: removed MTS block in certain maps (useful for the buyback system).
Localhost edit: removed party blocks for novices.
Localhost edit: removed AP assigning block for novices.
Localhost edit: removed speed cap.
Localhost edit: removed Maker block popping up when inputting ATK gems on non-weapons.
This commit is contained in:
ronancpl
2018-06-05 02:40:53 -03:00
230 changed files with 11509 additions and 3590 deletions
@@ -25,7 +25,6 @@ import java.util.Arrays;
import java.util.List;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.life.MapleLifeFactory;
import server.life.MapleMonster;
@@ -39,6 +38,7 @@ import client.MapleCharacter;
import client.MapleClient;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import client.inventory.manipulator.MapleInventoryManipulator;
public final class AdminCommandHandler extends AbstractMaplePacketHandler {
@@ -37,7 +37,7 @@ import net.AbstractMaplePacketHandler;
import server.CashShop;
import server.CashShop.CashItem;
import server.CashShop.CashItemFactory;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.FilePrinter;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -72,6 +72,11 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
}
if (action == 0x03) { // Item
if(ItemConstants.isMapleLife(cItem.getItemId()) && chr.getLevel() < 30) {
c.announce(MaplePacketCreator.enableActions());
return;
}
Item item = cItem.toItem();
cs.addToInventory(item);
c.announce(MaplePacketCreator.showBoughtCashItem(item, c.getAccID()));
@@ -165,6 +170,9 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
return;
}
if (chr.getStorage().gainSlots(4)) {
FilePrinter.print(FilePrinter.STORAGE + c.getAccountName() + ".txt", c.getPlayer().getName() + " bought 4 slots to their account storage.\r\n");
chr.setUsedStorage();
c.announce(MaplePacketCreator.showBoughtStorageSlots(chr.getStorage().getSlots()));
cs.gainCash(cash, -4000);
c.announce(MaplePacketCreator.showCash(chr));
@@ -196,6 +204,10 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.showBoughtCharacterSlot(c.getCharacterSlots()));
cs.gainCash(cash, -cItem.getPrice());
c.announce(MaplePacketCreator.showCash(chr));
} else {
chr.dropMessage(1, "You have already used up all 12 extra character slots.");
c.announce(MaplePacketCreator.enableActions());
return;
}
} else if (action == 0x0D) { // Take from Cash Inventory
Item item = cs.findByCashId(slea.readInt());
@@ -208,15 +220,11 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.takeFromCashInventory(item));
if(item instanceof Equip) {
Equip equip = (Equip) item;
if(equip.getRingId() >= 0) {
MapleRing ring = MapleRing.loadFromDb(equip.getRingId());
if (ring.getItemId() > 1112012) {
chr.addFriendshipRing(ring);
} else {
chr.addCrushRing(ring);
}
}
Equip equip = (Equip) item;
if(equip.getRingId() >= 0) {
MapleRing ring = MapleRing.loadFromDb(equip.getRingId());
chr.addPlayerRing(ring);
}
}
}
} else if (action == 0x0E) { // Put into Cash Inventory
@@ -236,8 +244,8 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
mi.removeSlot(item.getPosition());
c.announce(MaplePacketCreator.putIntoCashInventory(item, c.getAccID()));
} else if (action == 0x1D) { //crush ring (action 28)
slea.readInt();//Birthday
// if (checkBirthday(c, birthday)) { //We're using a default birthday, so why restrict rings to only people who know of it?
int birthday = slea.readInt();
if (checkBirthday(c, birthday)) {
int toCharge = slea.readInt();
int SN = slea.readInt();
String recipientName = slea.readMapleAsciiString();
@@ -271,9 +279,10 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
partner.showNote();
}
}
/* } else {
chr.dropMessage("The birthday you entered was incorrect.");
}*/
} else {
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
c.announce(MaplePacketCreator.enableActions());
}
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
} else if (action == 0x20) { // everything is 1 meso...
@@ -288,8 +297,8 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
}
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
} else if (action == 0x23) { //Friendship :3
slea.readInt(); //Birthday
// if (checkBirthday(c, birthday)) {
int birthday = slea.readInt();
if (checkBirthday(c, birthday)) {
int payment = slea.readByte();
slea.skip(3); //0s
int snID = slea.readInt();
@@ -320,17 +329,18 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
partner.showNote();
}
}
/* } else {
chr.dropMessage("The birthday you entered was incorrect.");
} */
} else {
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
c.announce(MaplePacketCreator.enableActions());
}
c.announce(MaplePacketCreator.showCash(c.getPlayer()));
} else {
System.out.println(slea);
System.out.println("Unhandled action: " + action + "\n" + slea);
}
}
private static boolean checkBirthday(MapleClient c, int idate) {
public static boolean checkBirthday(MapleClient c, int idate) {
int year = idate / 10000;
int month = (idate - year * 10000) / 100;
int day = idate - year * 10000 - month * 100;
@@ -339,7 +349,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
cal.set(year, month - 1, day);
return c.checkBirthDate(cal);
}
public static boolean canBuy(CashItem item, int cash) {
return item != null && item.isOnSale() && item.getPrice() <= cash;
}
@@ -25,7 +25,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MaplePortal;
import server.MapleTrade;
import server.maps.MapleMap;
@@ -27,7 +27,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.DatabaseConnection;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -61,6 +61,7 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(mc.getId(), mc.getAllDiseases());
mc.setAwayFromWorld(true);
mc.notifyMapTransferToPartner(-1);
mc.cancelAllBuffs(true);
mc.cancelAllDebuffs();
mc.cancelBuffExpireTask();
@@ -21,10 +21,6 @@
*/
package net.server.channel.handlers;
import client.*;
import client.inventory.Equip;
import client.inventory.Item;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -33,118 +29,138 @@ import java.util.ArrayList;
import java.util.List;
import constants.ServerConstants;
import client.MapleCharacter;
import client.MapleClient;
import client.inventory.Equip;
import client.inventory.Item;
import client.processor.BuybackProcessor;
import net.AbstractMaplePacketHandler;
import net.server.Server;
import server.MTSItemInfo;
import server.maps.FieldLimit;
import server.maps.MapleMiniDungeonInfo;
import tools.DatabaseConnection;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
public final class EnterMTSHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
if (!ServerConstants.USE_MTS){
c.announce(MaplePacketCreator.enableActions());
return;
}
if(MapleMiniDungeonInfo.isDungeonMap(c.getPlayer().getMapId())) {
c.announce(MaplePacketCreator.serverNotice(5, "Changing channels or entering Cash Shop or MTS are disabled when inside a Mini-Dungeon."));
c.announce(MaplePacketCreator.enableActions());
return;
}
MapleCharacter chr = c.getPlayer();
if (!chr.isAlive()) {
if(!chr.isAlive() && ServerConstants.USE_BUYBACK_SYSTEM) {
BuybackProcessor.processBuyback(c);
c.announce(MaplePacketCreator.enableActions());
return;
}
if (chr.getLevel() < 10) {
c.announce(MaplePacketCreator.blockedMessage2(5));
c.announce(MaplePacketCreator.enableActions());
return;
}
chr.unregisterChairBuff();
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(chr.getId(), chr.getAllDiseases());
chr.setAwayFromWorld(true);
chr.cancelAllBuffs(true);
chr.cancelAllDebuffs();
chr.cancelBuffExpireTask();
chr.cancelDiseaseExpireTask();
chr.cancelSkillCooldownTask();
chr.cancelExpirationTask();
chr.forfeitExpirableQuests();
chr.cancelQuestExpirationTask();
chr.saveToDB();
chr.getMap().removePlayer(c.getPlayer());
try {
c.announce(MaplePacketCreator.openCashShop(c, true));
} catch (Exception ex) {
ex.printStackTrace();
}
chr.getCashShop().open(true);// xD
c.announce(MaplePacketCreator.enableCSUse());
c.announce(MaplePacketCreator.MTSWantedListingOver(0, 0));
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
List<MTSItemInfo> items = new ArrayList<>();
int pages = 0;
try {
Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT * FROM mts_items WHERE tab = 1 AND transfer = 0 ORDER BY id DESC LIMIT 16, 16");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
if (rs.getInt("type") != 1) {
Item i = new Item(rs.getInt("itemid"), (short) 0, (short) rs.getInt("quantity"));
i.setOwner(rs.getString("owner"));
items.add(new MTSItemInfo(i, rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
} else {
Equip equip = new Equip(rs.getInt("itemid"), (byte) rs.getInt("position"), -1);
equip.setOwner(rs.getString("owner"));
equip.setQuantity((short) 1);
equip.setAcc((short) rs.getInt("acc"));
equip.setAvoid((short) rs.getInt("avoid"));
equip.setDex((short) rs.getInt("dex"));
equip.setHands((short) rs.getInt("hands"));
equip.setHp((short) rs.getInt("hp"));
equip.setInt((short) rs.getInt("int"));
equip.setJump((short) rs.getInt("jump"));
equip.setVicious((short) rs.getInt("vicious"));
equip.setFlag((byte) rs.getInt("flag"));
equip.setLuk((short) rs.getInt("luk"));
equip.setMatk((short) rs.getInt("matk"));
equip.setMdef((short) rs.getInt("mdef"));
equip.setMp((short) rs.getInt("mp"));
equip.setSpeed((short) rs.getInt("speed"));
equip.setStr((short) rs.getInt("str"));
equip.setWatk((short) rs.getInt("watk"));
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
} else {
if (!ServerConstants.USE_MTS) {
c.announce(MaplePacketCreator.enableActions());
return;
}
if(MapleMiniDungeonInfo.isDungeonMap(c.getPlayer().getMapId())) {
c.announce(MaplePacketCreator.serverNotice(5, "Changing channels or entering Cash Shop or MTS are disabled when inside a Mini-Dungeon."));
c.announce(MaplePacketCreator.enableActions());
return;
}
rs.close();
ps.close();
ps = con.prepareStatement("SELECT COUNT(*) FROM mts_items");
rs = ps.executeQuery();
if (rs.next()) {
pages = (int) Math.ceil(rs.getInt(1) / 16);
if (FieldLimit.CANNOTMIGRATE.check(chr.getMap().getFieldLimit())) {
chr.dropMessage(1, "You can't do it here in this map.");
c.announce(MaplePacketCreator.enableActions());
return;
}
rs.close();
ps.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
if (!chr.isAlive()) {
c.announce(MaplePacketCreator.enableActions());
return;
}
if (chr.getLevel() < 10) {
c.announce(MaplePacketCreator.blockedMessage2(5));
c.announce(MaplePacketCreator.enableActions());
return;
}
chr.unregisterChairBuff();
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(chr.getId(), chr.getAllDiseases());
chr.setAwayFromWorld(true);
chr.notifyMapTransferToPartner(-1);
chr.cancelAllBuffs(true);
chr.cancelAllDebuffs();
chr.cancelBuffExpireTask();
chr.cancelDiseaseExpireTask();
chr.cancelSkillCooldownTask();
chr.cancelExpirationTask();
chr.forfeitExpirableQuests();
chr.cancelQuestExpirationTask();
chr.saveToDB();
chr.getMap().removePlayer(c.getPlayer());
try {
c.announce(MaplePacketCreator.openCashShop(c, true));
} catch (Exception ex) {
ex.printStackTrace();
}
chr.getCashShop().open(true);// xD
c.announce(MaplePacketCreator.enableCSUse());
c.announce(MaplePacketCreator.MTSWantedListingOver(0, 0));
c.announce(MaplePacketCreator.showMTSCash(c.getPlayer()));
List<MTSItemInfo> items = new ArrayList<>();
int pages = 0;
try {
Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT * FROM mts_items WHERE tab = 1 AND transfer = 0 ORDER BY id DESC LIMIT 16, 16");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
if (rs.getInt("type") != 1) {
Item i = new Item(rs.getInt("itemid"), (short) 0, (short) rs.getInt("quantity"));
i.setOwner(rs.getString("owner"));
items.add(new MTSItemInfo(i, rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
} else {
Equip equip = new Equip(rs.getInt("itemid"), (byte) rs.getInt("position"), -1);
equip.setOwner(rs.getString("owner"));
equip.setQuantity((short) 1);
equip.setAcc((short) rs.getInt("acc"));
equip.setAvoid((short) rs.getInt("avoid"));
equip.setDex((short) rs.getInt("dex"));
equip.setHands((short) rs.getInt("hands"));
equip.setHp((short) rs.getInt("hp"));
equip.setInt((short) rs.getInt("int"));
equip.setJump((short) rs.getInt("jump"));
equip.setVicious((short) rs.getInt("vicious"));
equip.setFlag((byte) rs.getInt("flag"));
equip.setLuk((short) rs.getInt("luk"));
equip.setMatk((short) rs.getInt("matk"));
equip.setMdef((short) rs.getInt("mdef"));
equip.setMp((short) rs.getInt("mp"));
equip.setSpeed((short) rs.getInt("speed"));
equip.setStr((short) rs.getInt("str"));
equip.setWatk((short) rs.getInt("watk"));
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
}
rs.close();
ps.close();
ps = con.prepareStatement("SELECT COUNT(*) FROM mts_items");
rs = ps.executeQuery();
if (rs.next()) {
pages = (int) Math.ceil(rs.getInt(1) / 16);
}
rs.close();
ps.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
c.announce(MaplePacketCreator.sendMTS(items, 1, 0, 0, pages));
c.announce(MaplePacketCreator.transferInventory(getTransfer(chr.getId())));
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(chr.getId())));
}
c.announce(MaplePacketCreator.sendMTS(items, 1, 0, 0, pages));
c.announce(MaplePacketCreator.transferInventory(getTransfer(chr.getId())));
c.announce(MaplePacketCreator.notYetSoldInv(getNotYetSold(chr.getId())));
}
private List<MTSItemInfo> getNotYetSold(int cid) {
@@ -33,6 +33,7 @@ import tools.data.input.SeekableLittleEndianAccessor;
* @author Jay Estrella
*/
public final class FamilyAddHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
if (!ServerConstants.USE_FAMILY_SYSTEM){
return;
@@ -21,17 +21,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.server.channel.handlers;
import tools.FilePrinter;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
import client.MapleCharacter;
import client.MapleClient;
import client.autoban.AutobanFactory;
import client.command.Commands;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import net.AbstractMaplePacketHandler;
import tools.FilePrinter;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
public final class GeneralChatHandler extends AbstractMaplePacketHandler {
private static boolean isCommandIssue(char heading, MapleCharacter chr) {
if(chr.gmLevel() > 1 && heading == '!') {
return true;
@@ -59,7 +60,7 @@ public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
String[] sp = s.split(" ");
sp[0] = sp[0].toLowerCase().substring(1);
if(Commands.executeHeavenMSPlayerCommand(c, sp, heading)) {
if(Commands.executeHeavenMsPlayerCommand(c, sp, heading)) {
String command = "";
for (String used : sp) {
command += used + " ";
@@ -85,4 +86,3 @@ public final class GeneralChatHandler extends net.AbstractMaplePacketHandler {
}
}
}
@@ -22,8 +22,9 @@
package net.server.channel.handlers;
import net.server.guild.MapleGuildResponse;
import net.server.guild.MapleGuildCharacter;
import net.server.guild.MapleGuild;
import constants.GameConstants;
import constants.ServerConstants;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -107,8 +108,8 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
c.getPlayer().dropMessage(1, "You cannot create a new Guild while in one.");
return;
}
if (mc.getMeso() < MapleGuild.CREATE_GUILD_COST) {
c.getPlayer().dropMessage(1, "You do not have enough mesos to create a Guild.");
if (mc.getMeso() < ServerConstants.CREATE_GUILD_COST) {
c.getPlayer().dropMessage(1, "You do not have " + GameConstants.numberWithCommas(ServerConstants.CREATE_GUILD_COST) + " mesos to create a Guild.");
return;
}
String guildName = slea.readMapleAsciiString();
@@ -122,7 +123,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.genericGuildMessage((byte) 0x1c));
return;
}
mc.gainMeso(-MapleGuild.CREATE_GUILD_COST, true, false, true);
mc.gainMeso(-ServerConstants.CREATE_GUILD_COST, true, false, true);
mc.getMGC().setGuildId(gid);
Server.getInstance().getGuild(mc.getGuildId(), mc.getWorld(), mc); // initialize guild structure
@@ -254,8 +255,8 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
System.out.println("[hax] " + mc.getName() + " tried to change guild emblem without being the guild leader.");
return;
}
if (mc.getMeso() < MapleGuild.CHANGE_EMBLEM_COST) {
c.announce(MaplePacketCreator.serverNotice(1, "You do not have enough mesos to change the Guild emblem."));
if (mc.getMeso() < ServerConstants.CHANGE_EMBLEM_COST) {
c.announce(MaplePacketCreator.serverNotice(1, "You do not have " + GameConstants.numberWithCommas(ServerConstants.CHANGE_EMBLEM_COST) + " mesos to change the Guild emblem."));
return;
}
short bg = slea.readShort();
@@ -269,7 +270,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
Server.getInstance().allianceMessage(alliance.getId(), MaplePacketCreator.getGuildAlliances(alliance, c.getWorld()), -1, -1);
}
mc.gainMeso(-MapleGuild.CHANGE_EMBLEM_COST, true, false, true);
mc.gainMeso(-ServerConstants.CHANGE_EMBLEM_COST, true, false, true);
respawnPlayer(mc);
break;
case 0x10:
@@ -23,7 +23,7 @@ package net.server.channel.handlers;
import constants.ServerConstants;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
import client.MapleCharacter;
@@ -24,7 +24,7 @@ package net.server.channel.handlers;
import client.MapleClient;
import client.inventory.MapleInventoryType;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -28,7 +28,7 @@ import constants.ItemConstants;
import java.util.List;
import net.AbstractMaplePacketHandler;
import net.server.Server;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MapleItemInformationProvider.RewardItem;
import tools.MaplePacketCreator;
@@ -33,7 +33,7 @@ import net.AbstractMaplePacketHandler;
import net.server.Server;
import net.server.channel.Channel;
import server.MTSItemInfo;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import tools.DatabaseConnection;
import tools.MaplePacketCreator;
@@ -50,6 +50,8 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
// TODO add karma-to-untradeable flag on sold items here
if (!c.getPlayer().getCashShop().isOpened()) {
return;
}
@@ -21,29 +21,9 @@
*/
package net.server.channel.handlers;
import java.util.LinkedList;
import java.util.List;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import constants.ItemConstants;
import client.MapleClient;
import client.inventory.Equip;
import client.inventory.Item;
import client.inventory.MapleInventoryType;
import constants.EquipType;
import constants.ServerConstants;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import client.processor.MakerProcessor;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MakerItemFactory;
import server.MakerItemFactory.MakerItemCreateEntry;
import tools.FilePrinter;
import tools.Pair;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
/**
@@ -51,423 +31,9 @@ import tools.data.input.SeekableLittleEndianAccessor;
* @author Jay Estrella, Ronan
*/
public final class MakerSkillHandler extends AbstractMaplePacketHandler {
private static MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
int type = slea.readInt();
int toCreate = slea.readInt();
int toDisassemble = -1, pos = -1;
boolean makerSucceeded = true;
MakerItemCreateEntry recipe;
Map<Integer, Short> reagentids = new LinkedHashMap<>();
int stimulantid = -1;
if(type == 3) { // building monster crystal
int fromLeftover = toCreate;
toCreate = ii.getMakerCrystalFromLeftover(toCreate);
if(toCreate == -1) {
c.announce(MaplePacketCreator.serverNotice(1, ii.getName(toCreate) + " is unavailable for Monster Crystal conversion."));
return;
}
recipe = MakerItemFactory.generateLeftoverCrystalEntry(fromLeftover);
} else if(type == 4) { // disassembling
slea.readInt(); // 1... probably inventory type
pos = slea.readInt();
Item it = c.getPlayer().getInventory(MapleInventoryType.EQUIP).getItem((short) pos);
if(it != null && it.getItemId() == toCreate) {
Pair<Integer, Integer> p;
if((p = generateDisassemblyInfo(toCreate)) != null) {
recipe = MakerItemFactory.generateDisassemblyCrystalEntry(p.getLeft(), p.getRight());
toDisassemble = toCreate;
toCreate = ii.getMakerCrystalFromEquip(toCreate);
} else {
c.announce(MaplePacketCreator.serverNotice(1, ii.getName(toCreate) + " is unavailable for Monster Crystal disassembly."));
return;
}
} else {
c.announce(MaplePacketCreator.serverNotice(1, "An unknown error occurred when trying to apply that item for disassembly."));
return;
}
} else {
if(ItemConstants.isEquipment(toCreate)) { // only equips uses stimulant and reagents
if(slea.readByte() != 0) { // stimulant
stimulantid = getMakerStimulant(toCreate);
if(!c.getAbstractPlayerInteraction().haveItem(stimulantid)) {
stimulantid = -1;
}
}
int reagents = Math.min(slea.readInt(), getMakerReagentSlots(toCreate));
for(int i = 0; i < reagents; i++) { // crystals
int reagentid = slea.readInt();
if(ItemConstants.isMakerReagent(reagentid)) {
Short rs = reagentids.get(reagentid);
if(rs == null) {
reagentids.put(reagentid, (short) 1);
} else {
reagentids.put(reagentid, (short) (rs + 1));
}
}
}
List<Pair<Integer, Short>> toUpdate = new LinkedList<>();
for(Entry<Integer, Short> r : reagentids.entrySet()) {
int qty = c.getAbstractPlayerInteraction().getItemQuantity(r.getKey());
if(qty < r.getValue()) {
toUpdate.add(new Pair<>(r.getKey(), (short) qty));
}
}
// remove those not present on player inventory
if(!toUpdate.isEmpty()) {
for(Pair<Integer, Short> rp : toUpdate) {
if(rp.getRight() > 0) {
reagentids.put(rp.getLeft(), rp.getRight());
} else {
reagentids.remove(rp.getLeft());
}
}
}
if(!reagentids.isEmpty()) removeOddMakerReagents(toCreate, reagentids);
}
recipe = MakerItemFactory.getItemCreateEntry(toCreate, stimulantid, reagentids);
}
short createStatus = getCreateStatus(c, recipe);
switch(createStatus) {
case -1:// non-available for Maker itemid has been tried to forge
FilePrinter.printError(FilePrinter.EXPLOITS, "Player " + c.getPlayer().getName() + " tried to craft itemid " + toCreate + " using the Maker skill.");
c.announce(MaplePacketCreator.serverNotice(1, "The requested item could not be crafted on this operation."));
break;
case 1: // no items
c.announce(MaplePacketCreator.serverNotice(1, "You don't have all required items in your inventory to make " + recipe.getRewardAmount() + " " + ii.getName(toCreate) + "."));
break;
case 2: // no meso
NumberFormat nf = new DecimalFormat("#,###,###,###");
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough mesos (" + nf.format(recipe.getCost()) + ") to complete this operation."));
break;
case 3: // no req level
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough level to complete this operation."));
break;
case 4: // no req skill level
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough Maker level to complete this operation."));
break;
default:
if (MapleInventoryManipulator.checkSpace(c, toCreate, (short) recipe.getRewardAmount(), "")) {
for (Pair<Integer, Integer> p : recipe.getReqItems()) {
c.getAbstractPlayerInteraction().gainItem(p.getLeft(), (short) -p.getRight());
}
if(toDisassemble != -1) {
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.EQUIP, (short) pos, (short) 1, false);
c.announce(MaplePacketCreator.getShowItemGain(toDisassemble, (short) -1, true));
}
int cost = recipe.getCost();
if(stimulantid == -1 && reagentids.isEmpty()) {
if(cost > 0) c.getPlayer().gainMeso(-cost);
c.getPlayer().setCS(true);
c.getAbstractPlayerInteraction().gainItem(toCreate, (short) recipe.getRewardAmount());
c.getPlayer().setCS(false);
} else {
if(stimulantid != -1) c.getAbstractPlayerInteraction().gainItem(stimulantid, (short) -1);
if(!reagentids.isEmpty()) {
for(Entry<Integer, Short> r : reagentids.entrySet()) {
c.getAbstractPlayerInteraction().gainItem(r.getKey(), (short) (-1 * r.getValue()));
}
}
if(cost > 0) c.getPlayer().gainMeso(-cost);
makerSucceeded = addBoostedMakerItem(c, toCreate, stimulantid, reagentids);
}
if(makerSucceeded) c.announce(MaplePacketCreator.serverNotice(1, "You have successfully created " + recipe.getRewardAmount() + " " + ii.getName(toCreate) + "."));
else c.getPlayer().dropMessage(5, "The Maker skill lights up, but the skill winds up as if nothing happened.");
c.announce(MaplePacketCreator.showMakerEffect(makerSucceeded));
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), MaplePacketCreator.showForeignMakerEffect(c.getPlayer().getId(), makerSucceeded), false);
if(toCreate == 4260003 && c.getPlayer().getQuestStatus(6033) == 1) {
c.getAbstractPlayerInteraction().setQuestProgress(6033, 1);
}
} else {
c.announce(MaplePacketCreator.serverNotice(1, "Your inventory is full."));
}
}
}
// checks and prevents hackers from PE'ing Maker operations with invalid operations
private static void removeOddMakerReagents(int toCreate, Map<Integer, Short> reagentids) {
Map<Integer, Integer> reagentType = new LinkedHashMap<>();
List<Integer> toRemove = new LinkedList<>();
boolean isWeapon = ItemConstants.isWeapon(toCreate);
for(Entry<Integer, Short> r : reagentids.entrySet()) {
int curRid = r.getKey();
int type = r.getKey() / 100;
if(type < 42502 && !isWeapon) { // only weapons should gain w.att/m.att from these.
toRemove.add(curRid);
} else {
Integer tableRid = reagentType.get(type);
if(tableRid != null) {
if(tableRid < curRid) {
toRemove.add(tableRid);
reagentType.put(type, curRid);
} else {
toRemove.add(curRid);
}
} else {
reagentType.put(type, curRid);
}
}
}
// removing less effective gems of repeated type
for(Integer i : toRemove) {
reagentids.remove(i);
}
// only quantity 1 of each gem will be accepted by the Maker skill
for(Integer i : reagentids.keySet()) {
reagentids.put(i, (short) 1);
}
}
private static int getMakerReagentSlots(int itemId) {
try {
int eqpLevel = ii.getEquipStats(itemId).get("reqLevel");
if(eqpLevel < 78) {
return 1;
} else if(eqpLevel >= 78 && eqpLevel < 108) {
return 2;
} else {
return 3;
}
} catch(NullPointerException npe) {
return 0;
}
}
private static int getMakerStimulant(int itemId) {
EquipType et = EquipType.getEquipTypeById(itemId);
switch(et) {
case GLOVES:
return 4130000;
case SHOES:
return 4130001;
case SWORD:
return 4130002;
case AXE:
return 4130003;
case MACE:
return 4130004;
case SWORD_2H:
return 4130005;
case AXE_2H:
return 4130006;
case MACE_2H:
return 4130007;
case SPEAR:
return 4130008;
case POLEARM:
return 4130009;
case WAND:
return 4130010;
case STAFF:
return 4130011;
case BOW:
return 4130012;
case CROSSBOW:
return 4130013;
case DAGGER:
return 4130014;
case CLAW:
return 4130015;
case KNUCKLER:
return 4130016;
case PISTOL:
return 4130017;
case CAP:
return 4130018;
case COAT:
return 4130019;
case PANTS:
return 4130020;
case LONGCOAT:
return 4130021;
case SHIELD:
return 4130022;
default:
return -1;
}
}
private static Pair<Integer, Integer> generateDisassemblyInfo(int itemId) {
int recvFee = ii.getMakerDisassembledFee(itemId);
if(recvFee > -1) {
int recvQty = ii.getMakerDisassembledQuantity(itemId);
if(recvQty > 0) {
return new Pair<>(recvFee, recvQty);
}
}
return null;
}
private static short getCreateStatus(MapleClient c, MakerItemCreateEntry recipe) {
if(recipe == null) {
return -1;
}
if(!hasItems(c, recipe)) {
return 1;
}
if(c.getPlayer().getMeso() < recipe.getCost()) {
return 2;
}
if(c.getPlayer().getLevel() < recipe.getReqLevel()) {
return 3;
}
if(c.getPlayer().getSkillLevel((c.getPlayer().getJob().getId() / 1000) * 10000000 + 1007) < recipe.getReqSkillLevel()) {
return 4;
}
return 0;
}
private static boolean hasItems(MapleClient c, MakerItemCreateEntry recipe) {
for (Pair<Integer, Integer> p : recipe.getReqItems()) {
int itemId = p.getLeft();
if (c.getPlayer().getInventory(ItemConstants.getInventoryType(itemId)).countById(itemId) < p.getRight()) {
return false;
}
}
return true;
}
private static boolean addBoostedMakerItem(MapleClient c, int itemid, int stimulantid, Map<Integer, Short> reagentids) {
if(stimulantid != -1 && !ii.rollSuccessChance(90.0)) {
return false;
}
Item item = ii.getEquipById(itemid);
if(item == null) return false;
Equip eqp = (Equip)item;
if(ItemConstants.isAccessory(item.getItemId()) && eqp.getUpgradeSlots() <= 0) eqp.setUpgradeSlots(3);
if(ServerConstants.USE_ENHANCED_CRAFTING == true) {
if(!(c.getPlayer().isGM() && ServerConstants.USE_PERFECT_GM_SCROLL)) {
eqp.setUpgradeSlots((byte)(eqp.getUpgradeSlots() + 1));
}
item = MapleItemInformationProvider.getInstance().scrollEquipWithId(eqp, 2049100, true, 2049100, c.getPlayer().isGM());
}
if(!reagentids.isEmpty()) {
Map<String, Integer> stats = new LinkedHashMap<>();
List<Short> randOption = new LinkedList<>();
List<Short> randStat = new LinkedList<>();
for(Entry<Integer, Short> r : reagentids.entrySet()) {
Pair<String, Integer> reagentBuff = ii.getMakerReagentStatUpgrade(r.getKey());
if(reagentBuff != null) {
String s = reagentBuff.getLeft();
if(s.substring(0, 4).contains("rand")) {
if(s.substring(4).equals("Stat")) {
randStat.add((short) (reagentBuff.getRight() * r.getValue()));
} else {
randOption.add((short) (reagentBuff.getRight() * r.getValue()));
}
} else {
String stat = s.substring(3);
if(!stat.equals("ReqLevel")) { // improve req level... really?
switch (stat) {
case "MaxHP":
stat = "MHP";
break;
case "MaxMP":
stat = "MMP";
break;
}
Integer d = stats.get(stat);
if(d == null) {
stats.put(stat, reagentBuff.getRight() * r.getValue());
} else {
stats.put(stat, d + (reagentBuff.getRight() * r.getValue()));
}
}
}
}
}
ii.improveEquipStats(eqp, stats);
for(Short sh : randStat) {
ii.scrollOptionEquipWithChaos(eqp, sh, false);
}
for(Short sh : randOption) {
ii.scrollOptionEquipWithChaos(eqp, sh, true);
}
}
if(stimulantid != -1) {
eqp = ii.randomizeUpgradeStats(eqp);
}
MapleInventoryManipulator.addFromDrop(c, item, false, -1);
c.announce(MaplePacketCreator.getShowItemGain(itemid, (short) 1, true));
return true;
MakerProcessor.makerAction(slea, c);
}
}
@@ -27,8 +27,8 @@ import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import server.life.MapleMonster;
import server.life.MobAttackInfo;
import server.life.MobAttackInfoFactory;
//import server.life.MobAttackInfo;
//import server.life.MobAttackInfoFactory;
import server.life.MobSkill;
import server.life.MobSkillFactory;
import server.maps.MapleMapObject;
@@ -95,11 +95,19 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
toUse = null;
} else if (monster.canUseSkill(toUse)) {
toUse.applyEffect(c.getPlayer(), monster, true, banishPlayers);
//System.out.println("Applied: " + nextCastSkill + " Level: " + nextCastSkillLevel);
}
} else {
toUse = null;
}
} else {
MobAttackInfo mobAttack = MobAttackInfoFactory.getMobAttackInfo(monster, attackId);
//System.out.println("Attacked");
long curtime = System.currentTimeMillis();
if(curtime >= monster.getNextBasicSkillTime()) { // dont use the special attack too often, chase the player f3
//MobAttackInfo mobAttack = MobAttackInfoFactory.getMobAttackInfo(monster, attackId);
//monster.setNextBasicSkillTime(curtime);
toUse = null; // paliative measure for suspicious mob movement
} else {
toUse = null;
}
}
}
@@ -33,6 +33,7 @@ import client.MapleClient;
import java.sql.Connection;
public final class NoteActionHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
int action = slea.readByte();
if (action == 0 && c.getPlayer().getCashShop().getAvailableNotes() > 0) {
@@ -28,7 +28,7 @@ import client.inventory.Item;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MapleStatEffect;
import tools.Pair;
@@ -27,9 +27,8 @@ import client.inventory.MapleInventoryType;
import client.inventory.MaplePet;
import client.autoban.AutobanManager;
import client.inventory.Item;
import tools.Randomizer;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -71,8 +70,13 @@ public final class PetFoodHandler extends AbstractMaplePacketHandler {
return;
}
// 50% chance to get +1 closeness
pet.gainClosenessFullness(chr, (Randomizer.nextInt(101) <= 50) ? 1 : 0, 30, 1);
c.lockClient();
try {
pet.gainClosenessFullness(chr, (pet.getFullness() <= 75) ? 1 : 0, 30, 1); // 25+ "emptyness" to get +1 closeness
} finally {
c.unlockClient();
}
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, pos, (short) 1, false);
}
}
@@ -26,13 +26,14 @@ import client.MapleClient;
import client.autoban.AutobanFactory;
import client.inventory.Item;
import client.inventory.MapleInventoryType;
import client.inventory.manipulator.MapleInventoryManipulator;
import client.inventory.manipulator.MapleKarmaManipulator;
import constants.ItemConstants;
import constants.ServerConstants;
import java.util.Arrays;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MapleTrade;
import constants.GameConstants;
@@ -407,7 +408,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
if (chr.getTrade() != null) {
if ((quantity <= item.getQuantity() && quantity >= 0) || ItemConstants.isRechargeable(item.getItemId())) {
if (ii.isDropRestricted(item.getItemId())) { // ensure that undroppable items do not make it to the trade window
if (!((item.getFlag() & ItemConstants.KARMA) == ItemConstants.KARMA)) {
if (!MapleKarmaManipulator.hasKarmaFlag(item)) {
c.announce(MaplePacketCreator.serverNotice(1, "That item is untradeable."));
c.announce(MaplePacketCreator.enableActions());
return;
@@ -58,6 +58,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import server.life.MobSkill;
import tools.packets.Wedding;
public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
@@ -137,7 +138,9 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.getCharInfo(player));
if (!player.isHidden()) {
player.toggleHide(true);
if(player.isGM() && ServerConstants.USE_AUTOHIDE_GM) {
player.toggleHide(true);
}
}
player.sendKeymap();
player.sendMacros();
@@ -277,6 +280,16 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
player.updateCouponRates();
player.receivePartyMemberHP();
if(player.getPartnerId() > 0) {
int partnerId = player.getPartnerId();
final MapleCharacter partner = c.getWorldServer().getPlayerStorage().getCharacterById(partnerId);
if(partner != null && !partner.isAwayFromWorld()) {
player.announce(Wedding.OnNotifyWeddingPartnerTransfer(partnerId, partner.getMapId()));
partner.announce(Wedding.OnNotifyWeddingPartnerTransfer(player.getId(), player.getMapId()));
}
}
}
private static void showDueyNotification(MapleClient c, MapleCharacter player) {
@@ -286,13 +299,13 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
ResultSet rs = null;
try {
con = DatabaseConnection.getConnection();
ps = con.prepareStatement("SELECT Mesos FROM dueypackages WHERE RecieverId = ? and Checked = 1");
ps = con.prepareStatement("SELECT Mesos FROM dueypackages WHERE ReceiverId = ? and Checked = 1");
ps.setInt(1, player.getId());
rs = ps.executeQuery();
if (rs.next()) {
try {
Connection con2 = DatabaseConnection.getConnection();
pss = con2.prepareStatement("UPDATE dueypackages SET Checked = 0 where RecieverId = ?");
pss = con2.prepareStatement("UPDATE dueypackages SET Checked = 0 where ReceiverId = ?");
pss.setInt(1, player.getId());
pss.executeUpdate();
pss.close();
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.server.channel.handlers;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MapleStatEffect;
import tools.MaplePacketCreator;
@@ -25,86 +25,490 @@ package net.server.channel.handlers;
//import java.sql.PreparedStatement;
import client.MapleClient;
import client.MapleCharacter;
import client.inventory.MapleInventoryType;
import client.processor.DueyProcessor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
//import tools.DatabaseConnection;
import net.AbstractMaplePacketHandler;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.DatabaseConnection;
import tools.data.input.SeekableLittleEndianAccessor;
//import scripting.npc.NPCScriptManager;
import tools.Pair;
import tools.MaplePacketCreator;
import tools.packets.Wedding;
import net.server.world.World;
import net.server.channel.Channel;
import server.MapleItemInformationProvider;
import client.MapleRing;
import client.inventory.Equip;
import client.inventory.Item;
/**
* @author Jvlaple
* @author Ronan (major overhaul on Ring handling mechanics)
*/
public final class RingActionHandler extends AbstractMaplePacketHandler {
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
byte mode = slea.readByte();
MapleCharacter player = c.getPlayer();
switch (mode) {
case 0: //Send
String partnerName = slea.readMapleAsciiString();
MapleCharacter partner = c.getChannelServer().getPlayerStorage().getCharacterByName(partnerName);
if (partnerName.equalsIgnoreCase(player.getName())) {
c.getPlayer().dropMessage(1, "You cannot put your own name in it.");
return;
} else if (partner == null) {
c.getPlayer().dropMessage(1, partnerName + " was not found on this channel. If you are both logged in, please make sure you are in the same channel.");
return;
} else if (partner.getGender() == player.getGender()) {
c.getPlayer().dropMessage(1, "Your partner is the same gender as you.");
return;
} //else if (player.isMarried() && partner.isMarried())
// NPCScriptManager.getInstance().start(partner.getClient(), 9201002, "marriagequestion", player);
break;
case 1: //Cancel send
c.getPlayer().dropMessage(1, "You've cancelled the request.");
boolean accepted = slea.readByte() > 0;
String proposerName = slea.readMapleAsciiString();
if (accepted) {
c.announce(MaplePacketCreator.sendEngagementRequest(proposerName));
}
break;
case 2:
slea.readByte(); //type
case 3: //Drop Ring
/*
if (player.getPartner() != null) {
try {
Connection con = DatabaseConnection.getConnection();
int pid = 0;
if (player.getGender() == 0)
pid = player.getId();
else
pid = player.getPartner().getId();//we have an engagements SQL?
PreparedStatement ps = con.prepareStatement("DELETE FROM engagements WHERE husbandid = ?");
ps.setInt(1, pid);
ps.executeUpdate();
ps.close();
ps = con.prepareStatement("UPDATE characters SET marriagequest = 0 WHERE id = ?, and WHERE id = ?");
ps.setInt(1, player.getId());
ps.setInt(2, player.getPartner().getId());
ps.executeUpdate();
ps.close();
con.close();
} catch (Exception ex) {
ex.printStackTrace();
}
c.getPlayer().dropMessage(1, "Your engagement has been broken up.");
break;
}*/
break;
case 9: // groom's wishlist
int amount = slea.readShort();
if (amount > 10) {
amount = 10;
}
String[] items = new String[10];
for (int i = 0; i < amount; i++) {
items[i] = slea.readMapleAsciiString();
}
c.announce(MaplePacketCreator.sendGroomWishlist()); //WTF<
break;
default:
System.out.println("NEW RING ACTION " + mode);
break;
private static int getBoxId(int useItemId) {
return useItemId == 2240000 ? 4031357 : (useItemId == 2240001 ? 4031359 : (useItemId == 2240002 ? 4031361 : (useItemId == 2240003 ? 4031363 : (1112300 + (useItemId - 2240004)))));
}
public static void sendEngageProposal(final MapleClient c, final String name, final int itemid) {
final int newBoxId = getBoxId(itemid);
final MapleCharacter target = c.getChannelServer().getPlayerStorage().getCharacterByName(name);
final MapleCharacter source = c.getPlayer();
// TODO: get the correct packet bytes for these popups
if (source.isMarried()) {
source.dropMessage(1, "You're already married!");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (source.getPartnerId() > 0) {
source.dropMessage(1, "You're already engaged!");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (source.getMarriageItemId() > 0) {
source.dropMessage(1, "You're already engaging someone!");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (target == null) {
source.dropMessage(1, "Unable to find " + name + " on this channel.");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (target == source) {
source.dropMessage(1, "You can't engage yourself.");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if(target.getLevel() < 50) {
source.dropMessage(1, "You can only propose to someone level 50 or higher.");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if(source.getLevel() < 50) {
source.dropMessage(1, "You can only propose being level 50 or higher.");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (!target.getMap().equals(source.getMap())) {
source.dropMessage(1, "Make sure your partner is on the same map!");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (!source.haveItem(itemid) || itemid < 2240000 || itemid > 2240015) {
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (target.isMarried()) {
source.dropMessage(1, "The player is already married!");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (target.getPartnerId() > 0 || target.getMarriageItemId() > 0) {
source.dropMessage(1, "The player is already engaged!");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (target.getGender() != 1) {
source.dropMessage(1, "You may only propose to a girl!");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (!MapleInventoryManipulator.checkSpace(c, newBoxId, 1, "")) {
source.dropMessage(5, "You don't have a ETC slot available right now!");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
} else if (!MapleInventoryManipulator.checkSpace(target.getClient(), newBoxId + 1, 1, "")) {
source.dropMessage(5, "The girl you proposed doesn't have a ETC slot available right now.");
source.announce(Wedding.OnMarriageResult((byte) 0));
return;
}
source.setMarriageItemId(itemid);
target.announce(Wedding.OnMarriageRequest(source.getName(), source.getId()));
}
private static void eraseEngagementOffline(int characterId) {
try {
Connection con = DatabaseConnection.getConnection();
eraseEngagementOffline(characterId, con);
con.close();
} catch(SQLException sqle) {
sqle.printStackTrace();
}
}
private static void eraseEngagementOffline(int characterId, Connection con) throws SQLException {
PreparedStatement ps = con.prepareStatement("UPDATE characters SET marriageItemId=-1, partnerId=-1 WHERE id=?");
ps.setInt(1, characterId);
ps.executeUpdate();
ps.close();
}
private static void breakEngagementOffline(int characterId) {
try {
Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT marriageItemId FROM characters WHERE id=?");
ps.setInt(1, characterId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
int marriageItemId = rs.getInt("marriageItemId");
if (marriageItemId > 0) {
PreparedStatement ps2 = con.prepareStatement("UPDATE inventoryitems SET expiration=0 WHERE itemid=? AND characterid=?");
ps2.setInt(1, marriageItemId);
ps2.setInt(2, characterId);
ps2.executeUpdate();
ps2.close();
}
}
rs.close();
ps.close();
eraseEngagementOffline(characterId, con);
con.close();
} catch (SQLException ex) {
System.out.println("Error updating offline breakup " + ex.getMessage());
}
}
private synchronized static void breakMarriage(MapleCharacter chr) {
int partnerid = chr.getPartnerId();
if(partnerid <= 0) return;
chr.getClient().getWorldServer().deleteRelationship(chr.getId(), partnerid);
MapleRing.removeRing(chr.getMarriageRing());
MapleCharacter partner = chr.getClient().getWorldServer().getPlayerStorage().getCharacterById(partnerid);
if(partner == null) {
eraseEngagementOffline(partnerid);
} else {
partner.dropMessage(5, chr.getName() + " has decided to break up the marriage.");
//partner.announce(Wedding.OnMarriageResult((byte) 0)); ok, how to gracefully unengage someone without the need to cc?
partner.announce(Wedding.OnNotifyWeddingPartnerTransfer(0, 0));
resetRingId(partner);
partner.setPartnerId(-1);
partner.setMarriageItemId(-1);
partner.addMarriageRing(null);
}
chr.dropMessage(5, "You have successfully break the marriage with " + MapleCharacter.getNameById(partnerid) + ".");
//chr.announce(Wedding.OnMarriageResult((byte) 0));
chr.announce(Wedding.OnNotifyWeddingPartnerTransfer(0, 0));
resetRingId(chr);
chr.setPartnerId(-1);
chr.setMarriageItemId(-1);
chr.addMarriageRing(null);
}
private static void resetRingId(MapleCharacter player) {
int ringitemid = player.getMarriageRing().getItemId();
Item it = player.getInventory(MapleInventoryType.EQUIP).findById(ringitemid);
if(it == null) {
it = player.getInventory(MapleInventoryType.EQUIPPED).findById(ringitemid);
}
if(it != null) {
Equip eqp = (Equip) it;
eqp.setRingId(-1);
}
}
private synchronized static void breakEngagement(MapleCharacter chr) {
int partnerid = chr.getPartnerId();
int marriageitemid = chr.getMarriageItemId();
chr.getClient().getWorldServer().deleteRelationship(chr.getId(), partnerid);
MapleCharacter partner = chr.getClient().getWorldServer().getPlayerStorage().getCharacterById(partnerid);
if(partner == null) {
breakEngagementOffline(partnerid);
} else {
partner.dropMessage(5, chr.getName() + " has decided to break up the engagement.");
int partnerMarriageitemid = marriageitemid + ((chr.getGender() == 0) ? 1 : -1);
if(partner.haveItem(partnerMarriageitemid)) {
MapleInventoryManipulator.removeById(partner.getClient(), MapleInventoryType.ETC, partnerMarriageitemid, (short) 1, false, false);
}
//partner.announce(Wedding.OnMarriageResult((byte) 0)); ok, how to gracefully unengage someone without the need to cc?
partner.announce(Wedding.OnNotifyWeddingPartnerTransfer(0, 0));
partner.setPartnerId(-1);
partner.setMarriageItemId(-1);
}
if(chr.haveItem(marriageitemid)) {
MapleInventoryManipulator.removeById(chr.getClient(), MapleInventoryType.ETC, marriageitemid, (short) 1, false, false);
}
chr.dropMessage(5, "You have successfully break the engagement with " + MapleCharacter.getNameById(partnerid) + ".");
//chr.announce(Wedding.OnMarriageResult((byte) 0));
chr.announce(Wedding.OnNotifyWeddingPartnerTransfer(0, 0));
chr.setPartnerId(-1);
chr.setMarriageItemId(-1);
}
public static void breakMarriageRing(MapleCharacter chr, final int wItemId) {
final MapleInventoryType type = MapleInventoryType.getByType((byte) (wItemId / 1000000));
final Item wItem = chr.getInventory(type).findById(wItemId);
final boolean weddingToken = (wItem != null && type == MapleInventoryType.ETC && wItemId / 10000 == 403);
final boolean weddingRing = (wItem != null && wItemId / 10 == 111280);
if (weddingRing) {
if(chr.getPartnerId() > 0) {
breakMarriage(chr);
}
chr.getMap().disappearingItemDrop(chr, chr, wItem, chr.getPosition());
} else if (weddingToken) {
if (chr.getPartnerId() > 0) {
breakEngagement(chr);
}
chr.getMap().disappearingItemDrop(chr, chr, wItem, chr.getPosition());
}
}
public static void giveMarriageRings(MapleCharacter player, MapleCharacter partner, int marriageRingId) {
int ringid = MapleRing.createRing(marriageRingId, player, partner);
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
Item ringObj = ii.getEquipById(marriageRingId);
Equip ringEqp = (Equip) ringObj;
ringEqp.setRingId(ringid);
player.addMarriageRing(MapleRing.loadFromDb(ringid));
MapleInventoryManipulator.addFromDrop(player.getClient(), ringEqp, false, -1);
player.broadcastMarriageMessage();
ringObj = ii.getEquipById(marriageRingId);
ringEqp = (Equip) ringObj;
ringEqp.setRingId(ringid + 1);
partner.addMarriageRing(MapleRing.loadFromDb(ringid + 1));
MapleInventoryManipulator.addFromDrop(partner.getClient(), ringEqp, false, -1);
partner.broadcastMarriageMessage();
}
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
byte mode = slea.readByte();
String name;
byte slot;
switch(mode) {
case 0: // Send Proposal
sendEngageProposal(c, slea.readMapleAsciiString(), slea.readInt());
break;
case 1: // Cancel Proposal
if(c.getPlayer().getMarriageItemId() / 1000000 != 4) {
c.getPlayer().setMarriageItemId(-1);
}
break;
case 2: // Accept/Deny Proposal
final boolean accepted = slea.readByte() > 0;
name = slea.readMapleAsciiString();
final int id = slea.readInt();
final MapleCharacter source = c.getWorldServer().getPlayerStorage().getCharacterByName(name);
final MapleCharacter target = c.getPlayer();
if (source == null) {
target.announce(MaplePacketCreator.enableActions());
return;
}
final int itemid = source.getMarriageItemId();
if (target.getPartnerId() > 0 || source.getId() != id || itemid <= 0 || !source.haveItem(itemid) || source.getPartnerId() > 0 || !source.isAlive() || !target.isAlive()) {
target.announce(MaplePacketCreator.enableActions());
return;
}
if (accepted) {
final int newItemId = getBoxId(itemid);
if (!MapleInventoryManipulator.checkSpace(c, newItemId, 1, "") || !MapleInventoryManipulator.checkSpace(source.getClient(), newItemId, 1, "")) {
target.announce(MaplePacketCreator.enableActions());
return;
}
try {
MapleInventoryManipulator.removeById(source.getClient(), MapleInventoryType.USE, itemid, 1, false, false);
int marriageId = c.getWorldServer().createRelationship(source.getId(), target.getId());
source.setPartnerId(target.getId()); // engage them (new marriageitemid, partnerid for both)
target.setPartnerId(source.getId());
source.setMarriageItemId(newItemId);
target.setMarriageItemId(newItemId + 1);
MapleInventoryManipulator.addById(source.getClient(), newItemId, (short) 1);
MapleInventoryManipulator.addById(c, (newItemId + 1), (short) 1);
source.announce(Wedding.OnMarriageResult(marriageId, source, false));
target.announce(Wedding.OnMarriageResult(marriageId, source, false));
source.announce(Wedding.OnNotifyWeddingPartnerTransfer(target.getId(), target.getMapId()));
target.announce(Wedding.OnNotifyWeddingPartnerTransfer(source.getId(), source.getMapId()));
} catch (Exception e) {
System.out.println("Error with engagement " + e.getMessage());
}
} else {
source.dropMessage(1, "She has politely declined your engagement request.");
source.announce(Wedding.OnMarriageResult((byte) 0));
source.setMarriageItemId(-1);
}
break;
case 3: // Break Engagement
breakMarriageRing(c.getPlayer(), slea.readInt());
break;
case 5: // Invite %s to Wedding
name = slea.readMapleAsciiString();
int marriageId = slea.readInt();
slot = slea.readByte(); // this is an int
int itemId;
try {
itemId = c.getPlayer().getInventory(MapleInventoryType.ETC).getItem(slot).getItemId();
} catch(NullPointerException npe) {
c.announce(MaplePacketCreator.enableActions());
return;
}
if((itemId != 4031377 && itemId != 4031395) || !c.getPlayer().haveItem(itemId)) {
c.announce(MaplePacketCreator.enableActions());
return;
}
String groom = c.getPlayer().getName(), bride = MapleCharacter.getNameById(c.getPlayer().getPartnerId());
int guest = MapleCharacter.getIdByName(name);
if (groom == null || bride == null || groom.equals("") || bride.equals("") || guest <= 0) {
c.getPlayer().dropMessage(5, "Unable to find " + name + "!");
return;
}
try {
World wserv = c.getWorldServer();
Pair<Boolean, Boolean> registration = wserv.getMarriageQueuedLocation(marriageId);
if(registration != null) {
if(wserv.addMarriageGuest(marriageId, guest)) {
boolean cathedral = registration.getLeft();
int newItemId = cathedral ? 4031407 : 4031406;
Channel cserv = c.getChannelServer();
int resStatus = cserv.getWeddingReservationStatus(marriageId, cathedral);
if(resStatus > 0) {
long expiration = cserv.getWeddingTicketExpireTime(resStatus + 1);
MapleCharacter guestChr = c.getWorldServer().getPlayerStorage().getCharacterById(guest);
if(guestChr != null && MapleInventoryManipulator.checkSpace(guestChr.getClient(), newItemId, 1, "") && MapleInventoryManipulator.addById(guestChr.getClient(), newItemId, (short) 1, expiration)) {
guestChr.dropMessage(6, "[WEDDING] You've been invited to " + groom + " and " + bride + "'s Wedding!");
} else {
c.getPlayer().sendNote(name, "You've been invited to " + groom + " and " + bride + "'s Wedding! Receive your invitation from Duey!", (byte) 0);
Item weddingTicket = new Item(newItemId, (short) 0, (short) 1);
weddingTicket.setExpiration(expiration);
DueyProcessor.addItemToDB(weddingTicket, 1, 0, groom, guest);
}
} else {
c.getPlayer().dropMessage(5, "Wedding is already under way. You cannot invite any more guests for the event.");
}
} else {
c.getPlayer().dropMessage(5, "'" + name + "' is already invited for your marriage.");
}
} else {
c.getPlayer().dropMessage(5, "Invitation was not sent to '" + name + "'. Either the time for your marriage reservation already came or it was not found.");
}
} catch (SQLException ex) {
ex.printStackTrace();
return;
}
c.getAbstractPlayerInteraction().gainItem(itemId, (short) -1);
break;
case 6: // Open Wedding Invitation
slot = (byte) slea.readInt();
int invitationid = slea.readInt();
if(invitationid == 4031406 || invitationid == 4031407) {
Item item = c.getPlayer().getInventory(MapleInventoryType.ETC).getItem(slot);
if(item == null || item.getItemId() != invitationid) {
c.announce(MaplePacketCreator.enableActions());
return;
}
// collision case: most soon-to-come wedding will show up
Pair<Integer, Integer> coupleId = c.getWorldServer().getWeddingCoupleForGuest(c.getPlayer().getId(), invitationid == 4031407);
if (coupleId != null) {
int groomId = coupleId.getLeft(), brideId = coupleId.getRight();
c.announce(Wedding.sendWeddingInvitation(MapleCharacter.getNameById(groomId), MapleCharacter.getNameById(brideId)));
}
}
break;
case 9: // Groom and Bride's Wishlist
short size = slea.readShort();
List<String> itemnames = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
itemnames.add(slea.readMapleAsciiString());
}
//System.out.println("G&B WISHLIST: " + itemnames);
/*
if (c.getPlayer().getMarriageItemId() > -1) {
switch(c.getPlayer().getMarriageItemId()) {
case 10: // Premium Cathedral
c.getAbstractPlayerInteraction().gainItem(4031375, (short)1);
c.getAbstractPlayerInteraction().gainItem(4031395, (short)15);
break;
case 11: // Normal Cathedral
c.getAbstractPlayerInteraction().gainItem(4031480, (short)1);
c.getAbstractPlayerInteraction().gainItem(4031395, (short)15);
break;
case 20: // Premium Chapel
c.getAbstractPlayerInteraction().gainItem(4031376, (short)1);
c.getAbstractPlayerInteraction().gainItem(4031377, (short)15);
break;
case 21: // Normal Chapel
c.getAbstractPlayerInteraction().gainItem(4031481, (short)1);
c.getAbstractPlayerInteraction().gainItem(4031377, (short)15);
break;
default: {
System.out.println("Invalid Wedding Type for player " + c.getPlayer().getName() + "!");
break;
}
}
//c.getPlayer().setMarriageItemId(-1); ?????
}
if (c.getPlayer().getWishlist() == null) {
c.getPlayer().registerWishlist(itemnames);
}
if (c.getPlayer().getWedding() != null) {
if (c.getPlayer().getGender() == 0 ? c.getPlayer().getWedding().isExistantGroom(c.getPlayer().getId()) : c.getPlayer().getWedding().isExistantBride(c.getPlayer().getId())) {
c.getPlayer().getWedding().registerWishlist(c.getPlayer().getGender() == 1, itemnames);
}
}
*/
break;
default:
System.out.println("Unhandled RING_ACTION Mode: " + slea.toString());
break;
}
c.getSession().write(MaplePacketCreator.enableActions());
}
}
@@ -34,7 +34,7 @@ import constants.ItemConstants;
import java.util.ArrayList;
import java.util.List;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -107,11 +107,19 @@ public final class ScrollHandler extends AbstractMaplePacketHandler {
}
final List<ModifyInventory> mods = new ArrayList<>();
if (scrollSuccess == Equip.ScrollResult.CURSE) {
mods.add(new ModifyInventory(3, toScroll));
if (dst < 0) {
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).removeItem(toScroll.getPosition());
if(!ItemConstants.isWeddingRing(toScroll.getItemId())) {
mods.add(new ModifyInventory(3, toScroll));
if (dst < 0) {
c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).removeItem(toScroll.getPosition());
} else {
c.getPlayer().getInventory(MapleInventoryType.EQUIP).removeItem(toScroll.getPosition());
}
} else {
c.getPlayer().getInventory(MapleInventoryType.EQUIP).removeItem(toScroll.getPosition());
scrolled = toScroll;
scrollSuccess = Equip.ScrollResult.FAIL;
mods.add(new ModifyInventory(3, scrolled));
mods.add(new ModifyInventory(0, scrolled));
}
} else {
mods.add(new ModifyInventory(3, scrolled));
@@ -29,7 +29,7 @@ import client.inventory.Item;
import client.inventory.MapleInventoryType;
import java.util.Map;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import tools.MaplePacketCreator;
import tools.Randomizer;
@@ -32,7 +32,7 @@ import net.AbstractMaplePacketHandler;
import provider.MapleDataProvider;
import provider.MapleDataProviderFactory;
import provider.MapleDataTool;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -21,36 +21,29 @@
*/
package net.server.channel.handlers;
//import client.MapleCharacter;
import client.MapleCharacter;
import client.MapleClient;
//import client.command.CommandProcessor;
import net.AbstractMaplePacketHandler;
//import tools.MaplePacketCreator;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
public final class SpouseChatHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
System.out.println(slea.toString());
// slea.readMapleAsciiString();//recipient
// String msg = slea.readMapleAsciiString();
// if (!CommandProcessor.processCommand(c, msg))
// if (c.getPlayer().isMarried()) {
// MapleCharacter wife = c.getChannelServer().getPlayerStorage().getCharacterById(c.getPlayer().getPartnerId());
// if (wife != null) {
// wife.getClient().announce(MaplePacketCreator.sendSpouseChat(c.getPlayer(), msg));
// c.announce(MaplePacketCreator.sendSpouseChat(c.getPlayer(), msg));
// } else
// try {
// if (c.getChannelServer().getWorldInterface().isConnected(wife.getName())) {
// c.getChannelServer().getWorldInterface().sendSpouseChat(c.getPlayer().getName(), wife.getName(), msg);
// c.announce(MaplePacketCreator.sendSpouseChat(c.getPlayer(), msg));
// } else
// c.getPlayer().message("You are either not married or your spouse is currently offline.");
// } catch (Exception e) {
// e.printStackTrace();
// c.getPlayer().message("You are either not married or your spouse is currently offline.");
// c.getChannelServer().reconnectWorld();
// }
// }
slea.readMapleAsciiString();//recipient
String msg = slea.readMapleAsciiString();
int partnerId = c.getPlayer().getPartnerId();
if (partnerId > 0) { // yay marriage
MapleCharacter spouse = c.getWorldServer().getPlayerStorage().getCharacterById(partnerId);
if (spouse != null) {
spouse.announce(MaplePacketCreator.OnCoupleMessage(c.getPlayer().getName(), msg, true));
c.announce(MaplePacketCreator.OnCoupleMessage(c.getPlayer().getName(), msg, true));
} else {
c.getPlayer().dropMessage(5, "Your spouse is currently offline.");
}
} else {
c.getPlayer().dropMessage(5, "You don't have a spouse.");
}
}
}
@@ -21,20 +21,9 @@
*/
package net.server.channel.handlers;
import client.MapleCharacter;
import client.MapleClient;
import client.autoban.AutobanFactory;
import client.inventory.Item;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import constants.ItemConstants;
import constants.ServerConstants;
import client.processor.StorageProcessor;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MapleStorage;
import tools.FilePrinter;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
/**
@@ -44,122 +33,6 @@ import tools.data.input.SeekableLittleEndianAccessor;
public final class StorageHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
MapleCharacter chr = c.getPlayer();
byte mode = slea.readByte();
final MapleStorage storage = chr.getStorage();
if (chr.getLevel() < 15){
chr.dropMessage(1, "You may only use the storage once you have reached level 15.");
c.announce(MaplePacketCreator.enableActions());
return;
}
if (mode == 4) { // take out
byte type = slea.readByte();
byte slot = slea.readByte();
if (slot < 0 || slot > storage.getSlots()) { // removal starts at zero
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with storage.");
FilePrinter.print(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to work with storage slot " + slot + "\r\n");
c.disconnect(true, false);
return;
}
slot = storage.getSlot(MapleInventoryType.getByType(type), slot);
Item item = storage.getItem(slot);
if (item != null) {
if (MapleItemInformationProvider.getInstance().isPickupRestricted(item.getItemId()) && chr.haveItemWithId(item.getItemId(), true)) {
c.announce(MaplePacketCreator.getStorageError((byte) 0x0C));
return;
}
if (chr.getMap().getId() == 910000000) {
if (chr.getMeso() < 1000) {
c.announce(MaplePacketCreator.getStorageError((byte) 0x0B));
return;
} else {
chr.gainMeso(-1000, false);
}
}
if (MapleInventoryManipulator.checkSpace(c, item.getItemId(), item.getQuantity(), item.getOwner())) {
item = storage.takeOut(slot);//actually the same but idc
String itemName = MapleItemInformationProvider.getInstance().getName(item.getItemId());
FilePrinter.print(FilePrinter.STORAGE + c.getAccountName() + ".txt", c.getPlayer().getName() + " took out " + item.getQuantity() + " " + itemName + " (" + item.getItemId() + ")\r\n");
if ((item.getFlag() & ItemConstants.KARMA) == ItemConstants.KARMA) {
item.setFlag((byte) (item.getFlag() ^ ItemConstants.KARMA)); //items with scissors of karma used on them are reset once traded
}
MapleInventoryManipulator.addFromDrop(c, item, false);
storage.sendTakenOut(c, item.getInventoryType());
} else {
c.announce(MaplePacketCreator.getStorageError((byte) 0x0A));
}
}
} else if (mode == 5) { // store
short slot = slea.readShort();
int itemId = slea.readInt();
short quantity = slea.readShort();
MapleInventoryType slotType = ItemConstants.getInventoryType(itemId);
MapleInventory Inv = chr.getInventory(slotType);
if (slot < 1 || slot > Inv.getSlotLimit()) { //player inv starts at one
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with storage.");
FilePrinter.print(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to store item at slot " + slot + "\r\n");
c.disconnect(true, false);
return;
}
if (quantity < 1 || chr.getItemQuantity(itemId, false) < quantity) {
c.announce(MaplePacketCreator.enableActions());
return;
}
if (storage.isFull()) {
c.announce(MaplePacketCreator.getStorageError((byte) 0x11));
return;
}
short meso = (short) (chr.getMap().getId() == 910000000 ? -500 : -100);
if (chr.getMeso() < meso) {
c.announce(MaplePacketCreator.getStorageError((byte) 0x0B));
} else {
MapleInventoryType invType = ItemConstants.getInventoryType(itemId);
Item item = chr.getInventory(invType).getItem(slot).copy();
if (item.getItemId() == itemId && (item.getQuantity() >= quantity || ItemConstants.isRechargeable(itemId))) {
if (ItemConstants.isRechargeable(itemId)) {
quantity = item.getQuantity();
}
chr.gainMeso(meso, false, true, false);
MapleInventoryManipulator.removeFromSlot(c, invType, slot, quantity, false);
item.setQuantity(quantity);
storage.store(item);
storage.sendStored(c, ItemConstants.getInventoryType(itemId));
String itemName = MapleItemInformationProvider.getInstance().getName(item.getItemId());
FilePrinter.print(FilePrinter.STORAGE + c.getAccountName() + ".txt", c.getPlayer().getName() + " stored " + item.getQuantity() + " " + itemName + " (" + item.getItemId() + ")\r\n");
}
}
} else if (mode == 6) { // arrange items
if(ServerConstants.USE_STORAGE_ITEM_SORT) storage.arrangeItems(c);
c.announce(MaplePacketCreator.enableActions());
} else if (mode == 7) { // meso
int meso = slea.readInt();
int storageMesos = storage.getMeso();
int playerMesos = chr.getMeso();
if ((meso > 0 && storageMesos >= meso) || (meso < 0 && playerMesos >= -meso)) {
if (meso < 0 && (storageMesos - meso) < 0) {
meso = -2147483648 + storageMesos;
if (meso < playerMesos) {
c.announce(MaplePacketCreator.enableActions());
return;
}
} else if (meso > 0 && (playerMesos + meso) < 0) {
meso = 2147483647 - playerMesos;
if (meso > storageMesos) {
c.announce(MaplePacketCreator.enableActions());
return;
}
}
storage.setMeso(storageMesos - meso);
chr.gainMeso(meso, false, true, false);
FilePrinter.print(FilePrinter.STORAGE + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + (meso > 0 ? " took out " : " stored ") + Math.abs(meso) + " mesos\r\n");
} else {
c.announce(MaplePacketCreator.enableActions());
return;
}
storage.sendMeso(c);
} else if (mode == 8) {// close
storage.close();
}
StorageProcessor.storageAction(slea, c);
}
}
@@ -42,7 +42,7 @@ import java.util.ArrayList;
import java.util.List;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleStatEffect;
import server.life.MapleLifeFactory.loseItem;
import server.life.MapleMonster;
@@ -0,0 +1,46 @@
/*
This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
Copyleft (L) 2016 - 2018 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.channel.handlers;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
/**
*
* @author Ronan
*/
public final class TransferNameHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
slea.readInt(); //cid
int birthday = slea.readInt();
if (!CashOperationHandler.checkBirthday(c, birthday)) {
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
c.announce(MaplePacketCreator.enableActions());
return;
}
c.announce(MaplePacketCreator.sendNameTransferRules(4));
}
}
@@ -0,0 +1,40 @@
/*
This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
Copyleft (L) 2016 - 2018 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.channel.handlers;
import client.MapleCharacter;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
/**
*
* @author Ronan
*/
public final class TransferNameResultHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
String name = slea.readMapleAsciiString();
c.announce(MaplePacketCreator.sendNameTransferCheck(MapleCharacter.canCreateChar(name)));
}
}
@@ -0,0 +1,46 @@
/*
This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
Copyleft (L) 2016 - 2018 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.channel.handlers;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
/**
*
* @author Ronan
*/
public final class TransferWorldHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
slea.readInt(); //cid
int birthday = slea.readInt();
if (!CashOperationHandler.checkBirthday(c, birthday)) {
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xC4));
c.announce(MaplePacketCreator.enableActions());
return;
}
c.announce(MaplePacketCreator.sendWorldTransferRules(9));
}
}
@@ -27,12 +27,15 @@ import client.MapleJob;
import client.MapleStat;
import client.Skill;
import client.SkillFactory;
import client.creator.veteran.*;
import client.inventory.Equip;
import client.inventory.Equip.ScrollResult;
import client.inventory.Item;
import client.inventory.MapleInventoryType;
import client.inventory.MaplePet;
import client.inventory.ModifyInventory;
import client.inventory.manipulator.MapleInventoryManipulator;
import client.inventory.manipulator.MapleKarmaManipulator;
import constants.GameConstants;
import constants.ItemConstants;
import constants.ServerConstants;
@@ -45,7 +48,6 @@ import java.util.List;
import net.AbstractMaplePacketHandler;
import net.server.Server;
import scripting.npc.NPCScriptManager;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MapleShop;
import server.MapleShopFactory;
@@ -64,12 +66,15 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
final MapleCharacter player = c.getPlayer();
if (System.currentTimeMillis() - player.getLastUsedCashItem() < 3000) {
long timeNow = System.currentTimeMillis();
if (timeNow - player.getLastUsedCashItem() < 3000) {
player.dropMessage(1, "You have used a cash item recently. Wait a moment, then try again.");
c.announce(MaplePacketCreator.enableActions());
return;
}
player.setLastUsedCashItem(System.currentTimeMillis());
player.setLastUsedCashItem(timeNow);
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
slea.readShort();
int itemId = slea.readInt();
@@ -389,7 +394,7 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
if (item == null) //hack
{
return;
} else if (((item.getFlag() & ItemConstants.UNTRADEABLE) == ItemConstants.UNTRADEABLE) || ii.isDropRestricted(item.getItemId())) {
} else if (((item.getFlag() & ItemConstants.UNTRADEABLE) == ItemConstants.UNTRADEABLE) || (ii.isDropRestricted(item.getItemId()) && !MapleKarmaManipulator.hasKarmaFlag(item))) {
player.dropMessage(1, "You cannot trade this item.");
c.announce(MaplePacketCreator.enableActions());
return;
@@ -511,6 +516,56 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
}
}, 1000 * 10);
remove(c, itemId);
} else if (itemType == 543) {
if(itemId == 5432000 && !c.gainCharacterSlot()) {
player.dropMessage(1, "You have already used up all 12 extra character slots.");
c.announce(MaplePacketCreator.enableActions());
return;
}
String name = slea.readMapleAsciiString();
int face = slea.readInt();
int hair = slea.readInt();
int haircolor = slea.readInt();
int skin = slea.readInt();
int gender = slea.readInt();
int jobid = slea.readInt();
int improveSp = slea.readInt();
int createStatus;
switch(jobid) {
case 0:
createStatus = WarriorCreator.createCharacter(c, name, face, hair + haircolor, skin, gender, improveSp);
break;
case 1:
createStatus = MagicianCreator.createCharacter(c, name, face, hair + haircolor, skin, gender, improveSp);
break;
case 2:
createStatus = BowmanCreator.createCharacter(c, name, face, hair + haircolor, skin, gender, improveSp);
break;
case 3:
createStatus = ThiefCreator.createCharacter(c, name, face, hair + haircolor, skin, gender, improveSp);
break;
default:
createStatus = PirateCreator.createCharacter(c, name, face, hair + haircolor, skin, gender, improveSp);
}
if(createStatus == 0) {
c.announce(MaplePacketCreator.sendMapleLifeError(0)); // success!
player.showHint("#bSuccess#k on creation of the new character through the Maple Life card.");
remove(c, itemId);
} else {
if(createStatus == -1) { // check name
c.announce(MaplePacketCreator.sendMapleLifeNameError());
} else {
c.announce(MaplePacketCreator.sendMapleLifeError(-1 * createStatus));
}
}
} else if (itemType == 545) { // MiuMiu's travel store
if (player.getShop() == null) {
MapleShop shop = MapleShopFactory.getInstance().getShop(1338);
@@ -527,14 +582,18 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
MapleInventoryType type = MapleInventoryType.getByType((byte) slea.readInt());
short slot = (short) slea.readInt();
Item item = c.getPlayer().getInventory(type).getItem(slot);
if (item == null || item.getQuantity() <= 0 || (item.getFlag() & ItemConstants.KARMA) > 0 && ii.isKarmaAble(item.getItemId())) {
if (item == null || item.getQuantity() <= 0 || MapleKarmaManipulator.hasKarmaFlag(item) || !ii.isKarmaAble(item.getItemId())) {
c.announce(MaplePacketCreator.enableActions());
return;
}
if (!type.equals(MapleInventoryType.USE)) {
item.setFlag((byte) ItemConstants.KARMA);
if(MapleKarmaManipulator.hasUsedKarmaFlag(item)) {
c.getPlayer().dropMessage(6, "Scissors of Karma was already used on this item.");
c.announce(MaplePacketCreator.enableActions());
return;
}
MapleKarmaManipulator.setKarmaFlag(item);
c.getPlayer().forceUpdateItem(item);
remove(c, itemId);
c.announce(MaplePacketCreator.enableActions());
@@ -27,7 +27,7 @@ import client.inventory.MapleInventoryType;
import client.autoban.AutobanManager;
import constants.ItemConstants;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.life.MapleMonster;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -29,7 +29,7 @@ import client.inventory.MapleInventoryType;
import constants.ItemConstants;
import constants.ServerConstants;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -1,8 +1,6 @@
/*
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 file is part of the HeavenMS MapleStory Server
Copyleft (L) 2016 - 2018 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
@@ -21,6 +19,7 @@
*/
package net.server.channel.handlers;
import client.MapleCharacter;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import tools.MaplePacketCreator;
@@ -28,10 +27,28 @@ import tools.data.input.SeekableLittleEndianAccessor;
/**
*
* @author Jay Estrella
* @author RonanLana
*/
public class UseMapleLifeHandler extends AbstractMaplePacketHandler {
@Override
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
c.announce(MaplePacketCreator.charNameResponse(slea.readMapleAsciiString(), false));
MapleCharacter player = c.getPlayer();
long timeNow = System.currentTimeMillis();
if(timeNow - player.getLastUsedCashItem() < 3000) {
player.dropMessage(5, "Please wait a moment before trying again.");
c.announce(MaplePacketCreator.sendMapleLifeError(3));
c.announce(MaplePacketCreator.enableActions());
return;
}
player.setLastUsedCashItem(timeNow);
String name = slea.readMapleAsciiString();
if(MapleCharacter.canCreateChar(name)) {
c.announce(MaplePacketCreator.sendMapleLifeCharacterInfo());
} else {
c.announce(MaplePacketCreator.sendMapleLifeNameError());
}
c.announce(MaplePacketCreator.enableActions());
}
}
@@ -22,30 +22,51 @@
package net.server.channel.handlers;
import client.MapleClient;
import client.MapleCharacter;
import client.MapleMount;
import client.inventory.Item;
import client.inventory.MapleInventoryType;
import constants.ExpTable;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
/**
* @author PurpleMadness
* @author Ronan
*/
public final class UseMountFoodHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
slea.skip(6);
slea.skip(4);
short pos = slea.readShort();
int itemid = slea.readInt();
if (c.getPlayer().getInventory(MapleInventoryType.USE).findById(itemid) != null) {
if (c.getPlayer().getMount() != null && c.getPlayer().getMount().getTiredness() > 0) {
c.getPlayer().getMount().setTiredness(Math.max(c.getPlayer().getMount().getTiredness() - 30, 0));
c.getPlayer().getMount().setExp(2 * c.getPlayer().getMount().getLevel() + 6 + c.getPlayer().getMount().getExp());
int level = c.getPlayer().getMount().getLevel();
boolean levelup = c.getPlayer().getMount().getExp() >= ExpTable.getMountExpNeededForLevel(level) && level < 31;
MapleCharacter chr = c.getPlayer();
MapleMount mount = chr.getMount();
Item item = chr.getInventory(MapleInventoryType.USE).getItem(pos);
if (item != null && item.getItemId() == itemid && mount != null) {
float healedFactor;
c.lockClient();
try {
int curTiredness = mount.getTiredness();
int healedTiredness = Math.min(curTiredness, 30);
healedFactor = (float) healedTiredness / 30;
mount.setTiredness(curTiredness - healedTiredness);
} finally {
c.unlockClient();
}
if (healedFactor > 0.0f) {
mount.setExp(mount.getExp() + (int) Math.ceil(healedFactor * (2 * mount.getLevel() + 6)));
int level = mount.getLevel();
boolean levelup = mount.getExp() >= ExpTable.getMountExpNeededForLevel(level) && level < 31;
if (levelup) {
c.getPlayer().getMount().setLevel(level + 1);
mount.setLevel(level + 1);
}
c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.updateMount(c.getPlayer().getId(), c.getPlayer().getMount(), levelup));
chr.getMap().broadcastMessage(MaplePacketCreator.updateMount(chr.getId(), mount, levelup));
MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, itemid, 1, true, false);
}
}
@@ -25,7 +25,7 @@ import client.MapleClient;
import client.inventory.Item;
import client.inventory.MapleInventoryType;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -26,7 +26,7 @@ import client.inventory.Item;
import client.inventory.MapleInventoryType;
import tools.Randomizer;
import net.AbstractMaplePacketHandler;
import server.MapleInventoryManipulator;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.life.MapleLifeFactory;
import tools.MaplePacketCreator;
@@ -1,39 +1,93 @@
/*
* To change this template, choose Tools | Templates
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package net.server.channel.handlers;
import client.MapleCharacter;
import client.MapleClient;
import client.inventory.Item;
import client.inventory.MapleInventoryType;
import client.MapleCharacter;
import client.MapleClient;
import constants.ItemConstants;
import tools.DatabaseConnection;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import net.AbstractMaplePacketHandler;
import client.inventory.manipulator.MapleInventoryManipulator;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.packets.Wedding;
/**
*
* @author Kevin
* @author Eric
*/
public class WeddingHandler extends AbstractMaplePacketHandler {
@Override
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
//System.out.println("Wedding Packet: " + slea);
MapleCharacter chr = c.getPlayer();
byte operation = slea.readByte();
switch (operation) {
case 0x06://Add an item to the Wedding Registry
short slot = slea.readShort();
int itemid = slea.readInt();
short quantity = slea.readShort();
MapleInventoryType type = ItemConstants.getInventoryType(itemid);
Item item = chr.getInventory(type).getItem(slot);
if (itemid == item.getItemId() && quantity <= item.getQuantity()) {
c.announce(MaplePacketCreator.addItemToWeddingRegistry(chr, item));
public final class WeddingHandler extends AbstractMaplePacketHandler {
/*
public static final void OnWeddingProgress(byte action, MapleClient c) {
// -- Pelvis Bebop:
// 0x00: "We are gathered here today..."
// 0x01: "Very well! I pronounce you..."
// 0x02: "You two truly are a sight to..."
// 0x03: Wedding Ceremony Ended, initialize the Wedding Effect upon the two married characters
// -- High Priest John: (Unknown action bytes)
// 0x00: " "
// 0x01: " "
// 0x02: "Do you wish to bless this couple?..."
// 0x03: Wedding Ceremony Ended, initialize the Wedding Effect upon the two married characters
if (c.getPlayer().getWedding() != null) {
if (c.getPlayer().getGender() == 0 ? c.getPlayer().getWedding().isExistantGroom(c.getPlayer().getId()) : c.getPlayer().getWedding().isExistantBride(c.getPlayer().getId())) {
c.getPlayer().getMap().broadcastMessage(Wedding.OnWeddingProgress(action == 2, c.getPlayer().getId(), c.getPlayer().getPartnerId(), (byte)(action+1)));
c.getPlayer().getWedding().incrementStage();
c.getPlayer().getPartner().getWedding().incrementStage(); // pls don't b a bitch and throw npe ):<
if (action == 2) {
c.getPlayer().setMarried(true);
c.getChannelServer().getPlayerStorage().getCharacterById(c.getPlayer().getPartnerId()).setMarried(true);
}
}
}
c.announce(MaplePacketCreator.enableActions());
}
public static final void OnWeddingGiftResult(SeekableLittleEndianAccessor slea, MapleClient c) {
System.out.println("New WEDDING_GIFT_RESULT: " + slea.toString());
byte mode = slea.readByte();
switch(mode) {
case 0x06: // "SEND ITEM"
short slot = slea.readShort(); // isn't this a byte? o.O
int itemId = slea.readInt();
short quantity = slea.readShort();
if (c.getPlayer().getInventory(ItemConstants.getInventoryType(itemId)).getItem((byte)slot).getItemId() == itemId && c.getPlayer().getInventory(InventoryConstants.getInventoryType(itemId)).getItem((byte)slot).getQuantity() >= quantity) {
if (c.getPlayer().getWedding() == null) {
c.getPlayer().startWedding(); // TODO
}
List<String> itemnames = new ArrayList<>();
Item item = c.getPlayer().getInventory(ItemConstants.getInventoryType(itemId)).getItem((byte)slot);
boolean bride = false;
c.getPlayer().getWedding().registerWishlistItem(item, bride);
c.announce(Wedding.OnWeddingGiftResult((byte)11, itemnames, c.getPlayer().getWedding().getWishlistItems(bride))); // todo: remove item from inventory if success
}
case 0x08: // "EXIT"
if (slea.available() != 0) {
System.out.println("WEDDING_GIFT_RESULT: " + slea.toString());
}
c.announce(MaplePacketCreator.enableActions());
break;
default: {
System.out.println("Unknown Mode Found: " + mode + " : " + slea.toString());
}
}
}
}
*/
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
c.announce(MaplePacketCreator.enableActions());
}
}
@@ -0,0 +1,53 @@
/*
This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
Copyleft (L) 2016 - 2018 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.channel.handlers;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import scripting.event.EventInstanceManager;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.packets.Wedding;
/**
*
* @author Ronan
*/
public final class WeddingTalkHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
byte action = slea.readByte();
if(action == 1) {
EventInstanceManager eim = c.getPlayer().getEventInstance();
if(eim != null && !(c.getPlayer().getId() == eim.getIntProperty("groomId") || c.getPlayer().getId() == eim.getIntProperty("brideId"))) {
c.announce(Wedding.OnWeddingProgress(false, 0, 0, (byte) 2));
} else {
c.announce(Wedding.OnWeddingProgress(true, 0, 0, (byte) 3));
}
} else {
c.announce(Wedding.OnWeddingProgress(true, 0, 0, (byte) 3));
}
c.announce(MaplePacketCreator.enableActions());
}
}
@@ -0,0 +1,47 @@
/*
This file is part of the HeavenMS (MapleSolaxiaV2) MapleStory Server
Copyleft (L) 2016 - 2018 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.channel.handlers;
import client.MapleClient;
import net.AbstractMaplePacketHandler;
import scripting.event.EventInstanceManager;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.packets.Wedding;
/**
*
* @author Ronan
*/
public final class WeddingTalkMoreHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
EventInstanceManager eim = c.getPlayer().getEventInstance();
if(eim != null && !(c.getPlayer().getId() == eim.getIntProperty("groomId") || c.getPlayer().getId() == eim.getIntProperty("brideId"))) {
eim.gridInsert(c.getPlayer(), 1);
c.getPlayer().dropMessage(5, "High Priest John: Your blessings have been added to their love. What a noble act for a lovely couple!");
}
c.announce(Wedding.OnWeddingProgress(true, 0, 0, (byte) 3));
c.announce(MaplePacketCreator.enableActions());
}
}