New Year cards + Info on PlayerShops/HiredMerchants
New Year is coming soon! Figured out implementation for the New Year cards. Opcodes and packet structures are thanks to Eric. New Year effect crashes/dc's the player in some cases. Added informative notes to shop owners when transactioning an item/bundle.
This commit is contained in:
@@ -116,6 +116,7 @@ import client.inventory.MaplePet;
|
||||
import client.inventory.MapleWeaponType;
|
||||
import client.inventory.ModifyInventory;
|
||||
import client.inventory.PetDataFactory;
|
||||
import client.newyear.NewYearCardRecord;
|
||||
import constants.ExpTable;
|
||||
import constants.GameConstants;
|
||||
import constants.ItemConstants;
|
||||
@@ -238,6 +239,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private MonsterBook monsterbook;
|
||||
private MapleRing marriageRing;
|
||||
private CashShop cashshop;
|
||||
private Set<NewYearCardRecord> newyears = new LinkedHashSet<>();
|
||||
private SavedLocation savedLocations[];
|
||||
private SkillMacro[] skillMacros = new SkillMacro[5];
|
||||
private List<Integer> lastmonthfameids;
|
||||
@@ -830,7 +832,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
announce(MaplePacketCreator.getGMEffect(0x10, (byte) 0));
|
||||
List<MapleBuffStat> dsstat = Collections.singletonList(MapleBuffStat.DARKSIGHT);
|
||||
getMap().broadcastGMMessage(this, MaplePacketCreator.cancelForeignBuff(id, dsstat), false);
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.spawnPlayerMapobject(this), false);
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.spawnPlayerMapObject(this), false);
|
||||
|
||||
for(MapleSummon ms: this.getSummonsValues()) {
|
||||
getMap().broadcastNONGMMessage(this, MaplePacketCreator.spawnSummon(ms, false), false);
|
||||
@@ -843,7 +845,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
if (!login) {
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.removePlayerFromMap(getId()), false);
|
||||
}
|
||||
getMap().broadcastGMMessage(this, MaplePacketCreator.spawnPlayerMapobject(this), false);
|
||||
getMap().broadcastGMMessage(this, MaplePacketCreator.spawnPlayerMapObject(this), false);
|
||||
List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<MapleBuffStat, Integer>(MapleBuffStat.DARKSIGHT, 0));
|
||||
getMap().broadcastGMMessage(this, MaplePacketCreator.giveForeignBuff(id, dsstat), false);
|
||||
for (MapleMonster mon : this.getControlledMonsters()) {
|
||||
@@ -1074,7 +1076,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
guildUpdate();
|
||||
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.removePlayerFromMap(this.getId()), false);
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.spawnPlayerMapobject(this), false);
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.spawnPlayerMapObject(this), false);
|
||||
getMap().broadcastMessage(this, MaplePacketCreator.showForeignEffect(getId(), 8), false);
|
||||
|
||||
if (GameConstants.hasSPTable(newJob) && newJob.getId() != 2001) {
|
||||
@@ -5338,6 +5340,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
}
|
||||
|
||||
NewYearCardRecord.loadPlayerNewYearCards(ret);
|
||||
|
||||
PreparedStatement ps2, ps3;
|
||||
ResultSet rs2, rs3;
|
||||
|
||||
@@ -7571,7 +7575,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
@Override
|
||||
public void sendSpawnData(MapleClient client) {
|
||||
if (!this.isHidden() || client.getPlayer().gmLevel() > 1) {
|
||||
client.announce(MaplePacketCreator.spawnPlayerMapobject(this));
|
||||
client.announce(MaplePacketCreator.spawnPlayerMapObject(this));
|
||||
}
|
||||
|
||||
if (this.isHidden()) {
|
||||
@@ -7600,6 +7604,40 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
public CashShop getCashShop() {
|
||||
return cashshop;
|
||||
}
|
||||
|
||||
public Set<NewYearCardRecord> getNewYearRecords() {
|
||||
return newyears;
|
||||
}
|
||||
|
||||
public Set<NewYearCardRecord> getReceivedNewYearRecords() {
|
||||
Set<NewYearCardRecord> received = new LinkedHashSet<>();
|
||||
|
||||
for(NewYearCardRecord nyc : newyears) {
|
||||
if(nyc.isReceiverCardReceived()) {
|
||||
received.add(nyc);
|
||||
}
|
||||
}
|
||||
|
||||
return received;
|
||||
}
|
||||
|
||||
public NewYearCardRecord getNewYearRecord(int cardid) {
|
||||
for(NewYearCardRecord nyc : newyears) {
|
||||
if(nyc.getId() == cardid) {
|
||||
return nyc;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addNewYearRecord(NewYearCardRecord newyear) {
|
||||
newyears.add(newyear);
|
||||
}
|
||||
|
||||
public void removeNewYearRecord(NewYearCardRecord newyear) {
|
||||
newyears.remove(newyear);
|
||||
}
|
||||
|
||||
public void portalDelay(long delay) {
|
||||
this.portaldelay = System.currentTimeMillis() + delay;
|
||||
|
||||
377
src/client/newyear/NewYearCardRecord.java
Normal file
377
src/client/newyear/NewYearCardRecord.java
Normal file
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* This file is part of the HeavenMS (MapleSolaxiaV2) Maple Story Server
|
||||
*
|
||||
* Copyright (C) 2017 RonanLana
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package client.newyear;
|
||||
|
||||
import client.MapleCharacter;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import net.server.Server;
|
||||
import server.TimerManager;
|
||||
import tools.DatabaseConnection;
|
||||
import tools.MaplePacketCreator;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan (credits to Eric for showing the New Year opcodes and handler layout)
|
||||
*/
|
||||
public class NewYearCardRecord {
|
||||
private int id;
|
||||
|
||||
private int senderId;
|
||||
private String senderName;
|
||||
private boolean senderDiscardCard;
|
||||
|
||||
private int receiverId;
|
||||
private String receiverName;
|
||||
private boolean receiverDiscardCard;
|
||||
private boolean receiverReceivedCard;
|
||||
|
||||
private String stringContent;
|
||||
private long dateSent = 0;
|
||||
private long dateReceived = 0;
|
||||
|
||||
private ScheduledFuture<?> sendTask = null;
|
||||
|
||||
public NewYearCardRecord(int senderid, String sender, int receiverid, String receiver, String message) {
|
||||
this.id = -1;
|
||||
|
||||
this.senderId = senderid;
|
||||
this.senderName = sender;
|
||||
this.senderDiscardCard = false;
|
||||
|
||||
this.receiverId = receiverid;
|
||||
this.receiverName = receiver;
|
||||
this.receiverDiscardCard = false;
|
||||
this.receiverReceivedCard = false;
|
||||
|
||||
this.stringContent = message;
|
||||
|
||||
this.dateSent = System.currentTimeMillis();
|
||||
this.dateReceived = 0;
|
||||
}
|
||||
|
||||
private void setExtraNewYearCardRecord(int id, boolean senderDiscardCard, boolean receiverDiscardCard, boolean receiverReceivedCard, long dateSent, long dateReceived) {
|
||||
this.id = id;
|
||||
this.senderDiscardCard = senderDiscardCard;
|
||||
this.receiverDiscardCard = receiverDiscardCard;
|
||||
this.receiverReceivedCard = receiverReceivedCard;
|
||||
|
||||
this.dateSent = dateSent;
|
||||
this.dateReceived = dateReceived;
|
||||
}
|
||||
|
||||
public void setId(int cardid) {
|
||||
this.id = cardid;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public int getSenderId() {
|
||||
return senderId;
|
||||
}
|
||||
|
||||
public String getSenderName() {
|
||||
return senderName;
|
||||
}
|
||||
|
||||
public boolean isSenderCardDiscarded() {
|
||||
return senderDiscardCard;
|
||||
}
|
||||
|
||||
public int getReceiverId() {
|
||||
return receiverId;
|
||||
}
|
||||
|
||||
public String getReceiverName() {
|
||||
return receiverName;
|
||||
}
|
||||
|
||||
public boolean isReceiverCardDiscarded() {
|
||||
return receiverDiscardCard;
|
||||
}
|
||||
|
||||
public boolean isReceiverCardReceived() {
|
||||
return receiverReceivedCard;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return stringContent;
|
||||
}
|
||||
|
||||
public long getDateSent() {
|
||||
return dateSent;
|
||||
}
|
||||
|
||||
public long getDateReceived() {
|
||||
return dateReceived;
|
||||
}
|
||||
|
||||
public static void saveNewYearCard(NewYearCardRecord newyear) {
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("INSERT INTO newyear VALUES (DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")) {
|
||||
ps.setInt(1, newyear.senderId);
|
||||
ps.setString(2, newyear.senderName);
|
||||
ps.setInt(3, newyear.receiverId);
|
||||
ps.setString(4, newyear.receiverName);
|
||||
|
||||
ps.setString(5, newyear.stringContent);
|
||||
|
||||
ps.setBoolean(6, newyear.senderDiscardCard);
|
||||
ps.setBoolean(7, newyear.receiverDiscardCard);
|
||||
ps.setBoolean(8, newyear.receiverReceivedCard);
|
||||
|
||||
ps.setLong(9, newyear.dateSent);
|
||||
ps.setLong(10, newyear.dateReceived);
|
||||
|
||||
ps.executeUpdate();
|
||||
try (ResultSet rs = ps.getGeneratedKeys()) {
|
||||
rs.next();
|
||||
newyear.id = rs.getInt(1);
|
||||
}
|
||||
}
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateNewYearCard(NewYearCardRecord newyear) {
|
||||
newyear.receiverReceivedCard = true;
|
||||
newyear.dateReceived = System.currentTimeMillis();
|
||||
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE newyear SET received=1, timereceived=? WHERE id=?")) {
|
||||
ps.setLong(1, newyear.dateReceived);
|
||||
ps.setInt(2, newyear.id);
|
||||
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static NewYearCardRecord loadNewYearCard(int cardid) {
|
||||
NewYearCardRecord nyc = Server.getInstance().getNewYearCard(cardid);
|
||||
if(nyc != null) return nyc;
|
||||
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM newyear WHERE id = ?")) {
|
||||
ps.setInt(1, cardid);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
NewYearCardRecord newyear = new NewYearCardRecord(rs.getInt("senderid"), rs.getString("sendername"), rs.getInt("receiverid"), rs.getString("receivername"), rs.getString("message"));
|
||||
newyear.setExtraNewYearCardRecord(rs.getInt("id"), rs.getBoolean("senderdiscard"), rs.getBoolean("receiverdiscard"), rs.getBoolean("received"), rs.getLong("timesent"), rs.getLong("timereceived"));
|
||||
|
||||
Server.getInstance().setNewYearCard(newyear);
|
||||
return newyear;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void loadPlayerNewYearCards(MapleCharacter chr) {
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM newyear WHERE senderid = ? OR receiverid = ?")) {
|
||||
ps.setInt(1, chr.getId());
|
||||
ps.setInt(2, chr.getId());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
NewYearCardRecord newyear = new NewYearCardRecord(rs.getInt("senderid"), rs.getString("sendername"), rs.getInt("receiverid"), rs.getString("receivername"), rs.getString("message"));
|
||||
newyear.setExtraNewYearCardRecord(rs.getInt("id"), rs.getBoolean("senderdiscard"), rs.getBoolean("receiverdiscard"), rs.getBoolean("received"), rs.getLong("timesent"), rs.getLong("timereceived"));
|
||||
|
||||
chr.addNewYearRecord(newyear);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void printNewYearRecords(MapleCharacter chr) {
|
||||
chr.dropMessage(5, "New Years: " + chr.getNewYearRecords().size());
|
||||
|
||||
for(NewYearCardRecord nyc : chr.getNewYearRecords()) {
|
||||
chr.dropMessage(5, "-------------------------------");
|
||||
|
||||
chr.dropMessage(5, "Id: " + nyc.id);
|
||||
|
||||
chr.dropMessage(5, "Sender id: " + nyc.senderId);
|
||||
chr.dropMessage(5, "Sender name: " + nyc.senderName);
|
||||
chr.dropMessage(5, "Sender discard: " + nyc.senderDiscardCard);
|
||||
|
||||
chr.dropMessage(5, "Receiver id: " + nyc.receiverId);
|
||||
chr.dropMessage(5, "Receiver name: " + nyc.receiverName);
|
||||
chr.dropMessage(5, "Receiver discard: " + nyc.receiverDiscardCard);
|
||||
chr.dropMessage(5, "Received: " + nyc.receiverReceivedCard);
|
||||
|
||||
chr.dropMessage(5, "Message: " + nyc.stringContent);
|
||||
chr.dropMessage(5, "Date sent: " + nyc.dateSent);
|
||||
chr.dropMessage(5, "Date recv: " + nyc.dateReceived);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getCharacterWorld(int receiverid) {
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT world FROM characters WHERE id = ?")) {
|
||||
ps.setInt(1, receiverid);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return rs.getInt("world");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void startNewYearCardTask() {
|
||||
if(sendTask != null) return;
|
||||
|
||||
sendTask = TimerManager.getInstance().register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int world = getCharacterWorld(receiverId);
|
||||
if(world == -1) {
|
||||
sendTask.cancel(false);
|
||||
sendTask = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
MapleCharacter target = Server.getInstance().getWorld(world).getPlayerStorage().getCharacterById(receiverId);
|
||||
if(target != null && target.isLoggedin() && !target.isAwayFromWorld()) {
|
||||
target.announce(MaplePacketCreator.onNewYearCardRes(target, NewYearCardRecord.this, 0xC, 0));
|
||||
}
|
||||
}
|
||||
}, 1000 * 60 * 60); //1 Hour
|
||||
}
|
||||
|
||||
public void stopNewYearCardTask() {
|
||||
if(sendTask != null) {
|
||||
sendTask.cancel(false);
|
||||
sendTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteNewYearCard(int id) {
|
||||
Server.getInstance().removeNewYearCard(id);
|
||||
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("DELETE FROM newyear WHERE id = ?")) {
|
||||
ps.setInt(1, id);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeAllNewYearCard(boolean send, MapleCharacter chr) {
|
||||
int cid = chr.getId();
|
||||
|
||||
/* not truly needed since it's going to be hard removed from the DB
|
||||
String actor = (send ? "sender" : "receiver");
|
||||
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("UPDATE newyear SET " + actor + "id = 1, received = 0 WHERE " + actor + "id = ?")) {
|
||||
ps.setInt(1, cid);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
*/
|
||||
|
||||
Set<NewYearCardRecord> set = new HashSet<>(chr.getNewYearRecords());
|
||||
for(NewYearCardRecord nyc : set) {
|
||||
if(send) {
|
||||
if(nyc.senderId == cid) {
|
||||
nyc.senderDiscardCard = true;
|
||||
nyc.receiverReceivedCard = false;
|
||||
|
||||
chr.removeNewYearRecord(nyc);
|
||||
deleteNewYearCard(nyc.id);
|
||||
|
||||
chr.getMap().broadcastMessage(MaplePacketCreator.onNewYearCardRes(chr, nyc, 0xE, 0));
|
||||
|
||||
MapleCharacter other = chr.getClient().getWorldServer().getPlayerStorage().getCharacterById(nyc.getReceiverId());
|
||||
if(other != null && other.isLoggedin() && !other.isAwayFromWorld()) {
|
||||
other.removeNewYearRecord(nyc);
|
||||
other.getMap().broadcastMessage(MaplePacketCreator.onNewYearCardRes(other, nyc, 0xE, 0));
|
||||
|
||||
other.dropMessage(6, "[NEW YEAR] " + chr.getName() + " threw away the New Year card.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(nyc.receiverId == cid) {
|
||||
nyc.receiverDiscardCard = true;
|
||||
nyc.receiverReceivedCard = false;
|
||||
|
||||
chr.removeNewYearRecord(nyc);
|
||||
deleteNewYearCard(nyc.id);
|
||||
|
||||
chr.getMap().broadcastMessage(MaplePacketCreator.onNewYearCardRes(chr, nyc, 0xE, 0));
|
||||
|
||||
MapleCharacter other = chr.getClient().getWorldServer().getPlayerStorage().getCharacterById(nyc.getSenderId());
|
||||
if(other != null && other.isLoggedin() && !other.isAwayFromWorld()) {
|
||||
other.removeNewYearRecord(nyc);
|
||||
other.getMap().broadcastMessage(MaplePacketCreator.onNewYearCardRes(other, nyc, 0xE, 0));
|
||||
|
||||
other.dropMessage(6, "[NEW YEAR] " + chr.getName() + " threw away the New Year card.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void startPendingNewYearCardRequests() {
|
||||
try (Connection con = DatabaseConnection.getConnection()) {
|
||||
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM newyear WHERE timereceived = 0 AND senderdiscard = 0")) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
NewYearCardRecord newyear = new NewYearCardRecord(rs.getInt("senderid"), rs.getString("sendername"), rs.getInt("receiverid"), rs.getString("receivername"), rs.getString("message"));
|
||||
newyear.setExtraNewYearCardRecord(rs.getInt("id"), rs.getBoolean("senderdiscard"), rs.getBoolean("receiverdiscard"), rs.getBoolean("received"), rs.getLong("timesent"), rs.getLong("timereceived"));
|
||||
|
||||
Server.getInstance().setNewYearCard(newyear);
|
||||
newyear.startNewYearCardTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user