Password on minigames + Broadcast diseases + Missing reactor scripts

Added script for several uncoded reactors with drop data on DB.
Improved quest status updates on the DB, now using a common "characterid" column.
Fixed several disease status not appearing for other players.
Fixed MapleTV item being taken twice per operation.
Implemented password system for minirooms such as omok/match cards. Passwords as player names will suggest to the system that player is being "invited" to the private game.
This commit is contained in:
ronancpl
2018-05-01 02:26:55 -03:00
parent 61292f5c9b
commit 7d0f1cb311
33 changed files with 806 additions and 81 deletions

View File

@@ -1886,24 +1886,14 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
private static void deleteQuestProgressWhereCharacterId(Connection con, int cid) throws SQLException {
try (PreparedStatement ps = con.prepareStatement("SELECT queststatusid FROM queststatus WHERE characterid = ?")) {
try (PreparedStatement ps = con.prepareStatement("DELETE FROM medalmaps WHERE characterid = ?")) {
ps.setInt(1, cid);
ps.executeUpdate();
}
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int queststatusid = rs.getInt("queststatusid");
try (PreparedStatement ps2 = con.prepareStatement("DELETE FROM medalmaps WHERE queststatusid = ?")) {
ps2.setInt(1, queststatusid);
ps2.executeUpdate();
}
try (PreparedStatement ps2 = con.prepareStatement("DELETE FROM questprogress WHERE queststatusid = ?")) {
ps2.setInt(1, queststatusid);
ps2.executeUpdate();
}
}
}
try (PreparedStatement ps = con.prepareStatement("DELETE FROM questprogress WHERE characterid = ?")) {
ps.setInt(1, cid);
ps.executeUpdate();
}
}
@@ -4309,7 +4299,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
this.setMiniGame(null);
if (game.isOwner(this)) {
this.getMap().broadcastMessage(MaplePacketCreator.removeCharBox(this));
game.broadcastToVisitor(MaplePacketCreator.getMiniGameClose());
game.broadcastToVisitor(MaplePacketCreator.getMiniGameClose(3));
} else {
game.removeVisitor(this);
}
@@ -6663,8 +6653,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
deleteQuestProgressWhereCharacterId(con, id);
ps = con.prepareStatement("INSERT INTO queststatus (`queststatusid`, `characterid`, `quest`, `status`, `time`, `expires`, `forfeited`) VALUES (DEFAULT, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
PreparedStatement psf;
try (PreparedStatement pse = con.prepareStatement("INSERT INTO questprogress VALUES (DEFAULT, ?, ?, ?)")) {
psf = con.prepareStatement("INSERT INTO medalmaps VALUES (DEFAULT, ?, ?)");
try (PreparedStatement pse = con.prepareStatement("INSERT INTO questprogress VALUES (DEFAULT, ?, ?, ?, ?)")) {
psf = con.prepareStatement("INSERT INTO medalmaps VALUES (DEFAULT, ?, ?, ?)");
ps.setInt(1, id);
synchronized (quests) {
@@ -6678,14 +6668,16 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
try (ResultSet rs = ps.getGeneratedKeys()) {
rs.next();
for (int mob : q.getProgress().keySet()) {
pse.setInt(1, rs.getInt(1));
pse.setInt(2, mob);
pse.setString(3, q.getProgress(mob));
pse.setInt(1, id);
pse.setInt(2, rs.getInt(1));
pse.setInt(3, mob);
pse.setString(4, q.getProgress(mob));
pse.addBatch();
}
for (int i = 0; i < q.getMedalMaps().size(); i++) {
psf.setInt(1, rs.getInt(1));
psf.setInt(2, q.getMedalMaps().get(i));
psf.setInt(1, id);
psf.setInt(2, rs.getInt(1));
psf.setInt(3, q.getMedalMaps().get(i));
psf.addBatch();
}
pse.executeBatch();

View File

@@ -1636,7 +1636,7 @@ public class Commands {
break;
}
for (MapleMapObject mmo : player.getMap().getMapObjectsInRange(player.getPosition(), 1000.0, Arrays.asList(MapleMapObjectType.PLAYER))) {
for (MapleMapObject mmo : player.getMap().getMapObjectsInRange(player.getPosition(), 777777.7, Arrays.asList(MapleMapObjectType.PLAYER))) {
MapleCharacter chr = (MapleCharacter) mmo;
if(chr.getId() != player.getId()) {
@@ -2671,6 +2671,14 @@ public class Commands {
TimerManager tMan = TimerManager.getInstance();
player.dropMessage(6, "Total Task: " + tMan.getTaskCount() + " Current Task: " + tMan.getQueuedTasks() + " Active Task: " + tMan.getActiveCount() + " Completed Task: " + tMan.getCompletedTaskCount());
break;
case "set":
for(int i = 0; i < sub.length - 1; i++) {
ServerConstants.DEBUG_VALUES[i] = Integer.parseInt(sub[i + 1]);
}
break;
default:
return false;

View File

@@ -4,6 +4,7 @@ import client.MapleJob;
import constants.skills.Aran;
import server.maps.MapleMap;
import server.maps.FieldLimit;
import server.quest.MapleQuest;
/*
* @author kevintjuh93
@@ -211,7 +212,7 @@ public class GameConstants {
}
public static boolean isMedalQuest(short questid) {
return questid / 100 == 299;
return MapleQuest.getInstance(questid).getMedalRequirement() != -1;
}
public static boolean hasSPTable(MapleJob job) {

View File

@@ -166,7 +166,10 @@ public class ServerConstants {
//Event End Timestamp
public static final long EVENT_END_TIMESTAMP = 1428897600000L;
//Debug Variables
public static int DEBUG_VALUES[] = new int[10]; // Field designed for packet testing purposes
//Properties
static {
Properties p = new Properties();

View File

@@ -93,6 +93,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
CANCEL_EXIT(0x39),
READY(0x3A),
UN_READY(0x3B),
EXPEL(0x3C),
START(0x3D),
GET_RESULT(0x3E),
SKIP(0x3F),
@@ -120,12 +121,15 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
MapleTrade.startTrade(chr);
} else if (createType == 1) { // omok mini game
if (chr.getChalkboard() != null || FieldLimit.CANNOTMINIGAME.check(chr.getMap().getFieldLimit())) {
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(11));
return;
}
String desc = slea.readMapleAsciiString();
slea.readByte(); // 20 6E 4E
int type = slea.readByte(); // 20 6E 4E
MapleMiniGame game = new MapleMiniGame(chr, desc);
int type = slea.readByte();
String pw = slea.available() > 1 ? slea.readMapleAsciiString() : "";
MapleMiniGame game = new MapleMiniGame(chr, desc, pw);
chr.setMiniGame(game);
game.setPieceType(type);
game.setGameType("omok");
@@ -133,13 +137,16 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
chr.getMap().broadcastMessage(MaplePacketCreator.addOmokBox(chr, 1, 0));
game.sendOmok(c, type);
} else if (createType == 2) { // matchcard
if (chr.getChalkboard() != null) {
if (chr.getChalkboard() != null || FieldLimit.CANNOTMINIGAME.check(chr.getMap().getFieldLimit())) {
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(11));
return;
}
String desc = slea.readMapleAsciiString();
slea.readByte(); // 20 6E 4E
int type = slea.readByte(); // 20 6E 4E
MapleMiniGame game = new MapleMiniGame(chr, desc);
int type = slea.readByte();
String pw = slea.available() > 1 ? slea.readMapleAsciiString() : "";
MapleMiniGame game = new MapleMiniGame(chr, desc, pw);
game.setPieceType(type);
if (type == 0) {
game.setMatchesToWin(6);
@@ -155,12 +162,14 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
game.sendMatchCard(c, type);
} else if (createType == 4 || createType == 5) { // shop
if (!chr.getMap().getMapObjectsInRange(chr.getPosition(), 23000, Arrays.asList(MapleMapObjectType.SHOP, MapleMapObjectType.HIRED_MERCHANT)).isEmpty()) {
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(14));
return;
}
String desc = slea.readMapleAsciiString();
slea.skip(3);
int itemId = slea.readInt();
if (chr.getInventory(MapleInventoryType.CASH).countById(itemId) < 1) {
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(6));
return;
}
@@ -194,7 +203,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
if (!chr.getTrade().isFullTrade() && !chr.getTrade().getPartner().isFullTrade()) {
MapleTrade.visitTrade(chr, chr.getTrade().getPartner().getChr());
} else {
c.announce(MaplePacketCreator.enableActions()); //Ill be nice and not dc u
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(2));
return;
}
} else {
@@ -204,20 +213,27 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
MaplePlayerShop shop = (MaplePlayerShop) ob;
shop.visitShop(chr);
} else if (ob instanceof MapleMiniGame) {
slea.skip(1);
String pw = slea.available() > 1 ? slea.readMapleAsciiString() : "";
MapleMiniGame game = (MapleMiniGame) ob;
if (game.hasFreeSlot() && !game.isVisitor(c.getPlayer())) {
game.addVisitor(c.getPlayer());
chr.setMiniGame(game);
switch (game.getGameType()) {
case "omok":
game.sendOmok(c, game.getPieceType());
break;
case "matchcard":
game.sendMatchCard(c, game.getPieceType());
break;
if(game.checkPassword(pw) || game.checkPassword(c.getPlayer().getName())) {
if (game.hasFreeSlot() && !game.isVisitor(c.getPlayer())) {
game.addVisitor(c.getPlayer());
chr.setMiniGame(game);
switch (game.getGameType()) {
case "omok":
game.sendOmok(c, game.getPieceType());
break;
case "matchcard":
game.sendMatchCard(c, game.getPieceType());
break;
}
} else {
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(2));
}
} else {
chr.getClient().announce(MaplePacketCreator.getMiniGameFull());
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(22));
}
} else if (ob instanceof MapleHiredMerchant && chr.getHiredMerchant() == null) {
MapleHiredMerchant merchant = (MapleHiredMerchant) ob;
@@ -227,10 +243,10 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.getHiredMerchant(chr, merchant, false));
} else if (!merchant.isOpen()) {
c.announce(MaplePacketCreator.hiredMerchantMaintenanceMessage());
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(18));
return;
} else if (!merchant.addVisitor(c.getPlayer())) {
chr.dropMessage(1, "This shop has reached it's maximum capacity, please come by later.");
chr.getClient().announce(MaplePacketCreator.getMiniRoomError(2));
return;
} else {
c.announce(MaplePacketCreator.getHiredMerchant(c.getPlayer(), merchant, false));
@@ -374,13 +390,13 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
} else if (mode == Action.SET_MESO.getCode()) {
chr.getTrade().setMeso(slea.readInt());
} else if (mode == Action.SET_ITEMS.getCode()) {
MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
MapleInventoryType ivType = MapleInventoryType.getByType(slea.readByte());
Item item = chr.getInventory(ivType).getItem(slea.readShort());
short quantity = slea.readShort();
byte targetSlot = slea.readByte();
if (quantity < 1 || quantity > item.getQuantity()) {
c.announce(MaplePacketCreator.serverNotice(1, "You don't have enough quantity of the item."));
c.announce(MaplePacketCreator.enableActions());
return;
}
@@ -388,6 +404,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
if ((quantity <= item.getQuantity() && quantity >= 0) || ItemConstants.isRechargable(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)) {
c.announce(MaplePacketCreator.serverNotice(1, "That item is untradeable."));
c.announce(MaplePacketCreator.enableActions());
return;
}
@@ -411,6 +428,8 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
short slot = slea.readShort();
short bundles = slea.readShort();
if (chr.getInventory(ivType).getItem(slot) == null || chr.getItemQuantity(chr.getInventory(ivType).getItem(slot).getItemId(), false) < bundles || chr.getInventory(ivType).getItem(slot).getFlag() == ItemConstants.UNTRADEABLE) {
c.announce(MaplePacketCreator.serverNotice(1, "Could not perform shop operation with that item."));
c.announce(MaplePacketCreator.enableActions());
return;
}
short perBundle = slea.readShort();
@@ -451,7 +470,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
if (shop != null && shop.isOwner(c.getPlayer())) {
int slot = slea.readShort();
if (slot >= shop.getItems().size() || slot < 0) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with a player shop.");
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with a player shop.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to remove item at slot " + slot + "\r\n");
c.disconnect(true, false);
return;
@@ -479,7 +498,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
} else if (mode == Action.MERCHANT_ORGANIZE.getCode()) {
MapleHiredMerchant merchant = chr.getHiredMerchant();
if (!merchant.isOwner(chr)) return;
if (chr.getMerchantMeso() > 0) {
int possible = Integer.MAX_VALUE - chr.getMerchantMeso();
if (possible > 0) {
@@ -508,7 +527,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
int itemid = slea.readByte();
short quantity = slea.readShort();
if (quantity < 1) {
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with a hired merchant and or player shop.");
AutobanFactory.PACKET_EDIT.alert(c.getPlayer(), c.getPlayer().getName() + " tried to packet edit with a hired merchant and or player shop.");
FilePrinter.printError(FilePrinter.EXPLOITS + c.getPlayer().getName() + ".txt", c.getPlayer().getName() + " tried to buy item " + itemid + " with quantity " + quantity + "\r\n");
c.disconnect(true, false);
return;
@@ -528,6 +547,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
int slot = slea.readShort();
MaplePlayerShopItem shopItem = merchant.getItems().get(slot);
if (!MapleInventory.checkSpot(chr, shopItem.getItem())) {
c.announce(MaplePacketCreator.serverNotice(1, "Have a slot available on your inventory to claim back the item."));
c.announce(MaplePacketCreator.enableActions());
return;
}
@@ -568,6 +588,16 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
if (chr.getPlayerShop() != null && chr.getPlayerShop().isOwner(c.getPlayer())) {
chr.getPlayerShop().banPlayer(slea.readMapleAsciiString());
}
} else if (mode == Action.EXPEL.getCode()) {
MapleMiniGame miniGame = chr.getMiniGame();
if(miniGame != null && miniGame.isOwner(chr)) {
MapleCharacter visitor = miniGame.getVisitor();
if(visitor != null) {
visitor.closeMiniGame();
visitor.announce(MaplePacketCreator.getMiniGameClose(5));
}
}
}
}
}

View File

@@ -331,7 +331,6 @@ public final class UseCashItemHandler extends AbstractMaplePacketHandler {
}
if (!MapleTVEffect.isActive()) {
new MapleTVEffect(player, victim, messages, tvType);
remove(c, itemId);
} else {
player.dropMessage(1, "MapleTV is already in use.");
return;

View File

@@ -1034,7 +1034,7 @@ public class World {
activeMerchantsLock.unlock();
}
}
public void setServerMessage(String msg) {
for (Channel ch : channels) {
ch.setServerMessage(msg);

View File

@@ -35,6 +35,7 @@ import tools.MaplePacketCreator;
public class MapleMiniGame extends AbstractMapleMapObject {
private MapleCharacter owner;
private MapleCharacter visitor;
private String password;
private String GameType = null;
private int[] piece = new int[250];
private List<Integer> list4x3 = new ArrayList<>();
@@ -48,11 +49,20 @@ public class MapleMiniGame extends AbstractMapleMapObject {
private int ownerpoints = 0;
private int matchestowin = 0;
public MapleMiniGame(MapleCharacter owner, String description) {
public MapleMiniGame(MapleCharacter owner, String description, String password) {
this.owner = owner;
this.description = description;
this.password = password;
}
public String getPassword() {
return this.password;
}
public boolean checkPassword(String sentPw) {
return this.password.length() == 0 || sentPw.toLowerCase().contentEquals(this.password.toLowerCase());
}
public boolean hasFreeSlot() {
return visitor == null;
}

View File

@@ -1898,15 +1898,19 @@ public class MaplePacketCreator {
} else {
addAnnounceBox(mplew, mps, 1);
}
} else if (chr.getMiniGame() != null && chr.getMiniGame().isOwner(chr)) {
if (chr.getMiniGame().hasFreeSlot()) {
addAnnounceBox(mplew, chr.getMiniGame(), 1, 0, 1, 0);
} else {
addAnnounceBox(mplew, chr.getMiniGame(), 1, 0, 2, 1);
}
} else {
mplew.write(0);
MapleMiniGame miniGame = chr.getMiniGame();
if (miniGame != null && miniGame.isOwner(chr)) {
if (miniGame.hasFreeSlot()) {
spawnAnnounceBox(mplew, miniGame, 1, 0, 1, 0);
} else {
spawnAnnounceBox(mplew, miniGame, 1, 0, 2, 1);
}
} else {
mplew.write(0);
}
}
if (chr.getChalkboard() != null) {
mplew.write(1);
mplew.writeMapleAsciiString(chr.getChalkboard());
@@ -2073,6 +2077,17 @@ public class MaplePacketCreator {
}
private static void addAnnounceBox(final MaplePacketLittleEndianWriter mplew, MapleMiniGame game, int gametype, int type, int ammount, int joinable) {
mplew.write(gametype);
mplew.writeInt(game.getObjectId()); // gameid/shopid
mplew.writeMapleAsciiString(game.getDescription()); // desc
mplew.writeMapleAsciiString(game.getPassword());
mplew.write(type);
mplew.write(ammount);
mplew.write(2);
mplew.write(joinable);
}
private static void spawnAnnounceBox(final MaplePacketLittleEndianWriter mplew, MapleMiniGame game, int gametype, int type, int ammount, int joinable) {
mplew.write(gametype);
mplew.writeInt(game.getObjectId()); // gameid/shopid
mplew.writeMapleAsciiString(game.getDescription()); // desc
@@ -2082,7 +2097,7 @@ public class MaplePacketCreator {
mplew.write(2);
mplew.write(joinable);
}
public static byte[] facialExpression(MapleCharacter from, int expression) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(10);
mplew.writeShort(SendOpcode.FACIAL_EXPRESSION.getValue());
@@ -2768,7 +2783,7 @@ public class MaplePacketCreator {
mplew.writeInt(cid);
writeLongMaskD(mplew, statups);
for (Pair<MapleDisease, Integer> statup : statups) {
mplew.writeShort(statup.getRight().shortValue());
if(statup.getLeft() == MapleDisease.POISON) mplew.writeShort(statup.getRight().shortValue());
mplew.writeShort(skill.getSkillId());
mplew.writeShort(skill.getSkillLevel());
}
@@ -4823,15 +4838,27 @@ public class MaplePacketCreator {
return mplew.getPacket();
}
public static byte[] getMiniGameFull() {
/**
* 1 = Room already closed 2 = Can't enter due full cappacity 3 = Other requests at this minute
* 4 = Can't do while dead 5 = Can't do while middle event 6 = This character unable to do it
* 7, 20 = Not allowed to trade anymore 9 = Can only trade on same map 10 = May not open store near portal
* 11, 14 = Can't start game here 12 = Can't open store at this channel 13 = Can't estabilish miniroom
* 15 = Stores only an the free market 16 = Lists the rooms at FM (?) 17 = You may not enter this store
* 18 = Owner undergoing store maintenance 19 = Unable to enter tournament room 21 = Not enough mesos to enter
* 22 = Incorrect password
*
* @param status
* @return
*/
public static byte[] getMiniRoomError(int status) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(5);
mplew.writeShort(SendOpcode.PLAYER_INTERACTION.getValue());
mplew.write(PlayerInteractionHandler.Action.ROOM.getCode());
mplew.write(0);
mplew.write(2);
mplew.write(status);
return mplew.getPacket();
}
public static byte[] getMiniGameSkipVisitor(MapleMiniGame game) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(4);
mplew.writeShort(SendOpcode.PLAYER_INTERACTION.getValue());
@@ -4918,12 +4945,12 @@ public class MaplePacketCreator {
return getMiniGameResult(game, 1, 0, 0, 1, 1, true);
}
public static byte[] getMiniGameClose() {
public static byte[] getMiniGameClose(int type) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(5);
mplew.writeShort(SendOpcode.PLAYER_INTERACTION.getValue());
mplew.write(PlayerInteractionHandler.Action.EXIT.getCode());
mplew.write(1);
mplew.write(3);
mplew.write(type); /* 2 : CRASH 3 : The room has been closed 4 : You have left the room 5 : You have been expelled */
return mplew.getPacket();
}
@@ -5072,7 +5099,7 @@ public class MaplePacketCreator {
mplew.skip(3);
return mplew.getPacket();
}
public static byte[] addOmokBox(MapleCharacter c, int ammount, int type) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.UPDATE_CHAR_BOX.getValue());