Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aab9823a06 | ||
|
|
3f800c4a68 | ||
|
|
31e901ab6d | ||
|
|
238c01baf4 | ||
|
|
5a4bdd343c | ||
|
|
d916502f58 | ||
|
|
1791365e0f | ||
|
|
de2a86c859 | ||
|
|
5aeed01e38 | ||
|
|
6ab1af99da | ||
|
|
c7b2d218ef | ||
|
|
01ae462b72 | ||
|
|
eb603e7ee9 | ||
|
|
b67b29def5 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -21,3 +21,6 @@
|
|||||||
# Database
|
# Database
|
||||||
database/docker-db-data
|
database/docker-db-data
|
||||||
database/docker-pg-db-data
|
database/docker-pg-db-data
|
||||||
|
|
||||||
|
# macOS files
|
||||||
|
.DS_Store
|
||||||
|
|||||||
12
pom.xml
12
pom.xml
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>cosmic-maplestory</groupId>
|
<groupId>cosmic-maplestory</groupId>
|
||||||
@@ -52,7 +53,8 @@
|
|||||||
<!-- Maven plugins -->
|
<!-- Maven plugins -->
|
||||||
<maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version> <!-- For running unit tests -->
|
<maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version> <!-- For running unit tests -->
|
||||||
<maven-jar-plugin.version>3.4.1</maven-jar-plugin.version> <!-- Disabled. (for building thin jar) -->
|
<maven-jar-plugin.version>3.4.1</maven-jar-plugin.version> <!-- Disabled. (for building thin jar) -->
|
||||||
<maven-assembly-plugin.version>3.7.1</maven-assembly-plugin.version> <!-- For packaging the executable fat jar -->
|
<maven-assembly-plugin.version>3.7.1
|
||||||
|
</maven-assembly-plugin.version> <!-- For packaging the executable fat jar -->
|
||||||
|
|
||||||
<!-- Dependencies -->
|
<!-- Dependencies -->
|
||||||
<slf4j-api.version>2.0.13</slf4j-api.version> <!-- Logging facade -->
|
<slf4j-api.version>2.0.13</slf4j-api.version> <!-- Logging facade -->
|
||||||
@@ -180,6 +182,12 @@
|
|||||||
<version>${mockito.version}</version>
|
<version>${mockito.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-junit-jupiter</artifactId>
|
||||||
|
<version>${mockito.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -32,14 +32,14 @@ function action(mode, type, selection) {
|
|||||||
} else if (status == 1) {
|
} else if (status == 1) {
|
||||||
if (selection == 0) {
|
if (selection == 0) {
|
||||||
apqpoints = cm.getPlayer().getAriantPoints();
|
apqpoints = cm.getPlayer().getAriantPoints();
|
||||||
if (apqpoints < 100) {
|
if (apqpoints >= 100) {
|
||||||
cm.sendOk("Your Battle Arena score: #b" + apqpoints + "#k points. You need to surpass #b100 points#k so that I can give you the #bPalm Tree Beach Chair#k. Talk to me again when you have enough points.");
|
cm.sendNext("Wow, it looks like you got the #b100#k points ready to trade, let's trade?!");
|
||||||
cm.dispose();
|
|
||||||
} else if (apqpoints + arena.getAriantRewardTier(cm.getPlayer()) >= 100) {
|
} else if (apqpoints + arena.getAriantRewardTier(cm.getPlayer()) >= 100) {
|
||||||
cm.sendOk("Your Battle Arena score: #b" + apqpoints + "#k points and you pratically already have that score! Talk to my wife, #p2101016# to get them and then re-chat with me!");
|
cm.sendOk("Your Battle Arena score: #b" + apqpoints + "#k points and you pratically already have that score! Talk to my wife, #p2101016# to get them and then re-chat with me!");
|
||||||
cm.dispose();
|
cm.dispose();
|
||||||
} else {
|
} else {
|
||||||
cm.sendNext("Wow, it looks like you got the #b100#k points ready to trade, let's trade?!");
|
cm.sendOk("Your Battle Arena score: #b" + apqpoints + "#k points. You need to surpass #b100 points#k so that I can give you the #bPalm Tree Beach Chair#k. Talk to me again when you have enough points.");
|
||||||
|
cm.dispose();
|
||||||
}
|
}
|
||||||
} else if (selection == 1) {
|
} else if (selection == 1) {
|
||||||
cm.sendOk("The main objective of the Battle Arena is to allow the player to accumulate points so that they can be traded honorably for the highest prize: the #bPalm Tree Beach Chair#k. Collect points during the battles and talk to me when it's time to get the prize. In each battle, the player is given the opportunity to score points based on the amount of jewelry that the player has at the end. But be careful! If your points distance from other players #ris too high#k, this will have been all for nothing and you will earn mere #r1 point#k only.");
|
cm.sendOk("The main objective of the Battle Arena is to allow the player to accumulate points so that they can be traded honorably for the highest prize: the #bPalm Tree Beach Chair#k. Collect points during the battles and talk to me when it's time to get the prize. In each battle, the player is given the opportunity to score points based on the amount of jewelry that the player has at the end. But be careful! If your points distance from other players #ris too high#k, this will have been all for nothing and you will earn mere #r1 point#k only.");
|
||||||
|
|||||||
@@ -2068,7 +2068,7 @@ public class Character extends AbstractCharacterObject {
|
|||||||
this.getCashShop().gainCash(1, nxGain);
|
this.getCashShop().gainCash(1, nxGain);
|
||||||
|
|
||||||
if (YamlConfig.config.server.USE_ANNOUNCE_NX_COUPON_LOOT) {
|
if (YamlConfig.config.server.USE_ANNOUNCE_NX_COUPON_LOOT) {
|
||||||
showHint("You have earned #e#b" + nxGain + " NX#k#n. (" + this.getCashShop().getCash(1) + " NX)", 300);
|
showHint("You have earned #e#b" + nxGain + " NX#k#n. (" + this.getCashShop().getCash(CashShop.NX_CREDIT) + " NX)", 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getMap().pickItemDrop(pickupPacket, mapitem);
|
this.getMap().pickItemDrop(pickupPacket, mapitem);
|
||||||
@@ -2120,7 +2120,7 @@ public class Character extends AbstractCharacterObject {
|
|||||||
this.getCashShop().gainCash(1, nxGain);
|
this.getCashShop().gainCash(1, nxGain);
|
||||||
|
|
||||||
if (YamlConfig.config.server.USE_ANNOUNCE_NX_COUPON_LOOT) {
|
if (YamlConfig.config.server.USE_ANNOUNCE_NX_COUPON_LOOT) {
|
||||||
showHint("You have earned #e#b" + nxGain + " NX#k#n. (" + this.getCashShop().getCash(1) + " NX)", 300);
|
showHint("You have earned #e#b" + nxGain + " NX#k#n. (" + this.getCashShop().getCash(CashShop.NX_CREDIT) + " NX)", 300);
|
||||||
}
|
}
|
||||||
} else if (applyConsumeOnPickup(mItem.getItemId())) {
|
} else if (applyConsumeOnPickup(mItem.getItemId())) {
|
||||||
} else if (InventoryManipulator.addFromDrop(client, mItem, true)) {
|
} else if (InventoryManipulator.addFromDrop(client, mItem, true)) {
|
||||||
@@ -6063,7 +6063,8 @@ public class Character extends AbstractCharacterObject {
|
|||||||
sendPacket(PacketCreator.giveBuff(energybar, 0, stat));
|
sendPacket(PacketCreator.giveBuff(energybar, 0, stat));
|
||||||
sendPacket(PacketCreator.showOwnBuffEffect(energycharge.getId(), 2));
|
sendPacket(PacketCreator.showOwnBuffEffect(energycharge.getId(), 2));
|
||||||
getMap().broadcastPacket(this, PacketCreator.showBuffEffect(id, energycharge.getId(), 2));
|
getMap().broadcastPacket(this, PacketCreator.showBuffEffect(id, energycharge.getId(), 2));
|
||||||
getMap().broadcastPacket(this, PacketCreator.giveForeignBuff(energybar, stat));
|
getMap().broadcastPacket(this, PacketCreator.giveForeignPirateBuff(id, energycharge.getId(),
|
||||||
|
ceffect.getDuration(), stat));
|
||||||
}
|
}
|
||||||
if (energybar >= 10000 && energybar < 11000) {
|
if (energybar >= 10000 && energybar < 11000) {
|
||||||
energybar = 15000;
|
energybar = 15000;
|
||||||
|
|||||||
@@ -312,6 +312,10 @@ public class ItemId {
|
|||||||
return itemId == NX_CARD_100 || itemId == NX_CARD_250;
|
return itemId == NX_CARD_100 || itemId == NX_CARD_250;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isCashPackage(int itemId) {
|
||||||
|
return itemId / 10000 == 910;
|
||||||
|
}
|
||||||
|
|
||||||
// Face expression
|
// Face expression
|
||||||
private static final int FACE_EXPRESSION_MIN = 5160000;
|
private static final int FACE_EXPRESSION_MIN = 5160000;
|
||||||
private static final int FACE_EXPRESSION_MAX = 5160014;
|
private static final int FACE_EXPRESSION_MAX = 5160014;
|
||||||
|
|||||||
@@ -82,6 +82,11 @@ public class ByteBufInPacket implements InPacket {
|
|||||||
return byteBuf.readerIndex();
|
return byteBuf.readerIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof ByteBufInPacket other && byteBuf.equals(other.byteBuf);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final int readerIndex = byteBuf.readerIndex();
|
final int readerIndex = byteBuf.readerIndex();
|
||||||
|
|||||||
@@ -91,4 +91,9 @@ public class ByteBufOutPacket implements OutPacket {
|
|||||||
public void skip(int numberOfBytes) {
|
public void skip(int numberOfBytes) {
|
||||||
writeBytes(new byte[numberOfBytes]);
|
writeBytes(new byte[numberOfBytes]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof ByteBufOutPacket other && byteBuf.equals(other.byteBuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public final class CashOperationHandler extends AbstractPacketHandler {
|
|||||||
CashItem cItem = CashItemFactory.getItem(p.readInt());
|
CashItem cItem = CashItemFactory.getItem(p.readInt());
|
||||||
Map<String, String> recipient = Character.getCharacterFromDatabase(p.readString());
|
Map<String, String> recipient = Character.getCharacterFromDatabase(p.readString());
|
||||||
String message = p.readString();
|
String message = p.readString();
|
||||||
if (!canBuy(chr, cItem, cs.getCash(4)) || message.length() < 1 || message.length() > 73) {
|
if (!canBuy(chr, cItem, cs.getCash(CashShop.NX_PREPAID)) || message.isEmpty() || message.length() > 73) {
|
||||||
c.enableCSActions();
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -405,7 +405,7 @@ public final class CashOperationHandler extends AbstractPacketHandler {
|
|||||||
c.sendPacket(PacketCreator.showCash(c.getPlayer()));
|
c.sendPacket(PacketCreator.showCash(c.getPlayer()));
|
||||||
} else if (action == 0x2E) { //name change
|
} else if (action == 0x2E) { //name change
|
||||||
CashItem cItem = CashItemFactory.getItem(p.readInt());
|
CashItem cItem = CashItemFactory.getItem(p.readInt());
|
||||||
if (cItem == null || !canBuy(chr, cItem, cs.getCash(4))) {
|
if (cItem == null || !canBuy(chr, cItem, cs.getCash(CashShop.NX_PREPAID))) {
|
||||||
c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
|
c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
|
||||||
c.enableCSActions();
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
@@ -434,7 +434,7 @@ public final class CashOperationHandler extends AbstractPacketHandler {
|
|||||||
c.enableCSActions();
|
c.enableCSActions();
|
||||||
} else if (action == 0x31) { //world transfer
|
} else if (action == 0x31) { //world transfer
|
||||||
CashItem cItem = CashItemFactory.getItem(p.readInt());
|
CashItem cItem = CashItemFactory.getItem(p.readInt());
|
||||||
if (cItem == null || !canBuy(chr, cItem, cs.getCash(4))) {
|
if (cItem == null || !canBuy(chr, cItem, cs.getCash(CashShop.NX_PREPAID))) {
|
||||||
c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
|
c.sendPacket(PacketCreator.showCashShopMessage((byte) 0));
|
||||||
c.enableCSActions();
|
c.enableCSActions();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -24,27 +24,34 @@ import client.inventory.Item;
|
|||||||
import net.AbstractPacketHandler;
|
import net.AbstractPacketHandler;
|
||||||
import net.packet.InPacket;
|
import net.packet.InPacket;
|
||||||
import server.CashShop;
|
import server.CashShop;
|
||||||
|
import server.CashShop.CashShopSurpriseResult;
|
||||||
import tools.PacketCreator;
|
import tools.PacketCreator;
|
||||||
import tools.Pair;
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author RonanLana
|
* @author RonanLana
|
||||||
|
* @author Ponk
|
||||||
*/
|
*/
|
||||||
public class CashShopSurpriseHandler extends AbstractPacketHandler {
|
public class CashShopSurpriseHandler extends AbstractPacketHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void handlePacket(InPacket p, Client c) {
|
public final void handlePacket(InPacket p, Client c) {
|
||||||
CashShop cs = c.getPlayer().getCashShop();
|
CashShop cs = c.getPlayer().getCashShop();
|
||||||
|
if (!cs.isOpened()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cs.isOpened()) {
|
long cashId = p.readLong();
|
||||||
Pair<Item, Item> cssResult = cs.openCashShopSurprise();
|
Optional<CashShopSurpriseResult> result = cs.openCashShopSurprise(cashId);
|
||||||
|
if (result.isEmpty()) {
|
||||||
if (cssResult != null) {
|
|
||||||
Item cssItem = cssResult.getLeft(), cssBox = cssResult.getRight();
|
|
||||||
c.sendPacket(PacketCreator.onCashGachaponOpenSuccess(c.getAccID(), cssBox.getSN(), cssBox.getQuantity(), cssItem, cssItem.getItemId(), cssItem.getQuantity(), true));
|
|
||||||
c.sendPacket(PacketCreator.showCashInventory(c));
|
|
||||||
} else {
|
|
||||||
c.sendPacket(PacketCreator.onCashItemGachaponOpenFailed());
|
c.sendPacket(PacketCreator.onCashItemGachaponOpenFailed());
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item usedCashShopSurprise = result.get().usedCashShopSurprise();
|
||||||
|
Item reward = result.get().reward();
|
||||||
|
c.sendPacket(PacketCreator.onCashGachaponOpenSuccess(c.getAccID(), usedCashShopSurprise.getCashId(),
|
||||||
|
usedCashShopSurprise.getQuantity(), reward, reward.getItemId(), reward.getQuantity(), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import net.server.Server;
|
|||||||
import net.server.channel.Channel;
|
import net.server.channel.Channel;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import server.CashShop;
|
||||||
import server.ItemInformationProvider;
|
import server.ItemInformationProvider;
|
||||||
import server.MTSItemInfo;
|
import server.MTSItemInfo;
|
||||||
import tools.DatabaseConnection;
|
import tools.DatabaseConnection;
|
||||||
@@ -402,7 +403,7 @@ public final class MTSHandler extends AbstractPacketHandler {
|
|||||||
ResultSet rs = ps.executeQuery();
|
ResultSet rs = ps.executeQuery();
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
int price = rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1); // taxes
|
int price = rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1); // taxes
|
||||||
if (c.getPlayer().getCashShop().getCash(4) >= price) { // FIX
|
if (c.getPlayer().getCashShop().getCash(CashShop.NX_PREPAID) >= price) { // FIX
|
||||||
boolean alwaysnull = true;
|
boolean alwaysnull = true;
|
||||||
for (Channel cserv : Server.getInstance().getAllChannels()) {
|
for (Channel cserv : Server.getInstance().getAllChannels()) {
|
||||||
Character victim = cserv.getPlayerStorage().getCharacterById(rs.getInt("seller"));
|
Character victim = cserv.getPlayerStorage().getCharacterById(rs.getInt("seller"));
|
||||||
@@ -459,11 +460,11 @@ public final class MTSHandler extends AbstractPacketHandler {
|
|||||||
ResultSet rs = ps.executeQuery();
|
ResultSet rs = ps.executeQuery();
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
int price = rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1);
|
int price = rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1);
|
||||||
if (c.getPlayer().getCashShop().getCash(4) >= price) {
|
if (c.getPlayer().getCashShop().getCash(CashShop.NX_PREPAID) >= price) {
|
||||||
for (Channel cserv : Server.getInstance().getAllChannels()) {
|
for (Channel cserv : Server.getInstance().getAllChannels()) {
|
||||||
Character victim = cserv.getPlayerStorage().getCharacterById(rs.getInt("seller"));
|
Character victim = cserv.getPlayerStorage().getCharacterById(rs.getInt("seller"));
|
||||||
if (victim != null) {
|
if (victim != null) {
|
||||||
victim.getCashShop().gainCash(4, rs.getInt("price"));
|
victim.getCashShop().gainCash(CashShop.NX_PREPAID, rs.getInt("price"));
|
||||||
} else {
|
} else {
|
||||||
try (PreparedStatement pse = con.prepareStatement("SELECT accountid FROM characters WHERE id = ?")) {
|
try (PreparedStatement pse = con.prepareStatement("SELECT accountid FROM characters WHERE id = ?")) {
|
||||||
pse.setInt(1, rs.getInt("seller"));
|
pse.setInt(1, rs.getInt("seller"));
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ public final class UseCatchItemHandler extends AbstractPacketHandler {
|
|||||||
mob.getMap().killMonster(mob, null, false);
|
mob.getMap().killMonster(mob, null, false);
|
||||||
InventoryManipulator.removeById(c, InventoryType.USE, itemId, 1, true, true);
|
InventoryManipulator.removeById(c, InventoryType.USE, itemId, 1, true, true);
|
||||||
InventoryManipulator.addById(c, ItemId.ARPQ_SPIRIT_JEWEL, (short) 1, "", -1);
|
InventoryManipulator.addById(c, ItemId.ARPQ_SPIRIT_JEWEL, (short) 1, "", -1);
|
||||||
|
chr.updateAriantScore();
|
||||||
} else {
|
} else {
|
||||||
chr.getMap().broadcastMessage(PacketCreator.catchMonster(monsterid, itemId, (byte) 0));
|
chr.getMap().broadcastMessage(PacketCreator.catchMonster(monsterid, itemId, (byte) 0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import client.inventory.Pet;
|
|||||||
import config.YamlConfig;
|
import config.YamlConfig;
|
||||||
import constants.id.ItemId;
|
import constants.id.ItemId;
|
||||||
import constants.inventory.ItemConstants;
|
import constants.inventory.ItemConstants;
|
||||||
|
import net.jcip.annotations.GuardedBy;
|
||||||
import net.server.Server;
|
import net.server.Server;
|
||||||
import provider.Data;
|
import provider.Data;
|
||||||
import provider.DataProvider;
|
import provider.DataProvider;
|
||||||
@@ -36,7 +37,6 @@ import provider.DataProviderFactory;
|
|||||||
import provider.DataTool;
|
import provider.DataTool;
|
||||||
import provider.wz.WZFiles;
|
import provider.wz.WZFiles;
|
||||||
import tools.DatabaseConnection;
|
import tools.DatabaseConnection;
|
||||||
import tools.PacketCreator;
|
|
||||||
import tools.Pair;
|
import tools.Pair;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@@ -48,6 +48,8 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@@ -56,208 +58,12 @@ import static java.util.concurrent.TimeUnit.HOURS;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @author Flav
|
* @author Flav
|
||||||
|
* @author Ponk
|
||||||
*/
|
*/
|
||||||
public class CashShop {
|
public class CashShop {
|
||||||
public static class CashItem {
|
public static final int NX_CREDIT = 1;
|
||||||
|
public static final int MAPLE_POINT = 2;
|
||||||
private final int sn;
|
public static final int NX_PREPAID = 4;
|
||||||
private final int itemId;
|
|
||||||
private final int price;
|
|
||||||
private final long period;
|
|
||||||
private final short count;
|
|
||||||
private final boolean onSale;
|
|
||||||
|
|
||||||
private CashItem(int sn, int itemId, int price, long period, short count, boolean onSale) {
|
|
||||||
this.sn = sn;
|
|
||||||
this.itemId = itemId;
|
|
||||||
this.price = price;
|
|
||||||
this.period = (period == 0 ? 90 : period);
|
|
||||||
this.count = count;
|
|
||||||
this.onSale = onSale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSN() {
|
|
||||||
return sn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getItemId() {
|
|
||||||
return itemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPrice() {
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getCount() {
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOnSale() {
|
|
||||||
return onSale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Item toItem() {
|
|
||||||
Item item;
|
|
||||||
|
|
||||||
int petid = -1;
|
|
||||||
if (ItemConstants.isPet(itemId)) {
|
|
||||||
petid = Pet.createPet(itemId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ItemConstants.getInventoryType(itemId).equals(InventoryType.EQUIP)) {
|
|
||||||
item = ItemInformationProvider.getInstance().getEquipById(itemId);
|
|
||||||
} else {
|
|
||||||
item = new Item(itemId, (byte) 0, count, petid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ItemConstants.EXPIRING_ITEMS) {
|
|
||||||
if (period == 1) {
|
|
||||||
switch (itemId) {
|
|
||||||
case ItemId.DROP_COUPON_2X_4H, ItemId.EXP_COUPON_2X_4H: // 4 Hour 2X coupons, the period is 1, but we don't want them to last a day.
|
|
||||||
item.setExpiration(Server.getInstance().getCurrentTime() + HOURS.toMillis(4));
|
|
||||||
/*
|
|
||||||
} else if(itemId == 5211047 || itemId == 5360014) { // 3 Hour 2X coupons, unused as of now
|
|
||||||
item.setExpiration(Server.getInstance().getCurrentTime() + HOURS.toMillis(3));
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case ItemId.EXP_COUPON_3X_2H:
|
|
||||||
item.setExpiration(Server.getInstance().getCurrentTime() + HOURS.toMillis(2));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
item.setExpiration(Server.getInstance().getCurrentTime() + DAYS.toMillis(1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.setExpiration(Server.getInstance().getCurrentTime() + DAYS.toMillis(period));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item.setSN(sn);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SpecialCashItem {
|
|
||||||
private final int sn;
|
|
||||||
private final int modifier;
|
|
||||||
private final byte info; //?
|
|
||||||
|
|
||||||
public SpecialCashItem(int sn, int modifier, byte info) {
|
|
||||||
this.sn = sn;
|
|
||||||
this.modifier = modifier;
|
|
||||||
this.info = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSN() {
|
|
||||||
return sn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getModifier() {
|
|
||||||
return modifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte getInfo() {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CashItemFactory {
|
|
||||||
private static volatile Map<Integer, CashItem> items = new HashMap<>();
|
|
||||||
private static volatile List<Integer> randomitemsns = new ArrayList<>();
|
|
||||||
private static volatile Map<Integer, List<Integer>> packages = new HashMap<>();
|
|
||||||
private static volatile List<SpecialCashItem> specialcashitems = new ArrayList<>();
|
|
||||||
|
|
||||||
public static void loadAllCashItems() {
|
|
||||||
DataProvider etc = DataProviderFactory.getDataProvider(WZFiles.ETC);
|
|
||||||
|
|
||||||
Map<Integer, CashItem> loadedItems = new HashMap<>();
|
|
||||||
List<Integer> onSaleItems = new ArrayList<>();
|
|
||||||
for (Data item : etc.getData("Commodity.img").getChildren()) {
|
|
||||||
int sn = DataTool.getIntConvert("SN", item);
|
|
||||||
int itemId = DataTool.getIntConvert("ItemId", item);
|
|
||||||
int price = DataTool.getIntConvert("Price", item, 0);
|
|
||||||
long period = DataTool.getIntConvert("Period", item, 1);
|
|
||||||
short count = (short) DataTool.getIntConvert("Count", item, 1);
|
|
||||||
boolean onSale = DataTool.getIntConvert("OnSale", item, 0) == 1;
|
|
||||||
loadedItems.put(sn, new CashItem(sn, itemId, price, period, count, onSale));
|
|
||||||
|
|
||||||
if (onSale) {
|
|
||||||
onSaleItems.add(sn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CashItemFactory.items = loadedItems;
|
|
||||||
CashItemFactory.randomitemsns = onSaleItems;
|
|
||||||
|
|
||||||
Map<Integer, List<Integer>> loadedPackages = new HashMap<>();
|
|
||||||
for (Data cashPackage : etc.getData("CashPackage.img").getChildren()) {
|
|
||||||
List<Integer> cPackage = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Data item : cashPackage.getChildByPath("SN").getChildren()) {
|
|
||||||
cPackage.add(Integer.parseInt(item.getData().toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
loadedPackages.put(Integer.parseInt(cashPackage.getName()), cPackage);
|
|
||||||
}
|
|
||||||
CashItemFactory.packages = loadedPackages;
|
|
||||||
|
|
||||||
List<SpecialCashItem> loadedSpecialItems = new ArrayList<>();
|
|
||||||
try (Connection con = DatabaseConnection.getConnection();
|
|
||||||
PreparedStatement ps = con.prepareStatement("SELECT * FROM specialcashitems");
|
|
||||||
ResultSet rs = ps.executeQuery()) {
|
|
||||||
while (rs.next()) {
|
|
||||||
loadedSpecialItems.add(new SpecialCashItem(rs.getInt("sn"), rs.getInt("modifier"), rs.getByte("info")));
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
CashItemFactory.specialcashitems = loadedSpecialItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CashItem getRandomCashItem() {
|
|
||||||
if (randomitemsns.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rnd = (int) (Math.random() * randomitemsns.size());
|
|
||||||
return items.get(randomitemsns.get(rnd));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CashItem getItem(int sn) {
|
|
||||||
return items.get(sn);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Item> getPackage(int itemId) {
|
|
||||||
List<Item> cashPackage = new ArrayList<>();
|
|
||||||
|
|
||||||
for (int sn : packages.get(itemId)) {
|
|
||||||
cashPackage.add(getItem(sn).toItem());
|
|
||||||
}
|
|
||||||
|
|
||||||
return cashPackage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPackage(int itemId) {
|
|
||||||
return packages.containsKey(itemId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<SpecialCashItem> getSpecialCashItems() {
|
|
||||||
return specialcashitems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reloadSpecialCashItems() {//Yay?
|
|
||||||
List<SpecialCashItem> loadedSpecialItems = new ArrayList<>();
|
|
||||||
try (Connection con = DatabaseConnection.getConnection();
|
|
||||||
PreparedStatement ps = con.prepareStatement("SELECT * FROM specialcashitems");
|
|
||||||
ResultSet rs = ps.executeQuery()) {
|
|
||||||
while (rs.next()) {
|
|
||||||
loadedSpecialItems.add(new SpecialCashItem(rs.getInt("sn"), rs.getInt("modifier"), rs.getByte("info")));
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
CashItemFactory.specialcashitems = loadedSpecialItems;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int accountId;
|
private final int accountId;
|
||||||
private final int characterId;
|
private final int characterId;
|
||||||
@@ -320,30 +126,212 @@ public class CashShop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCash(int type) {
|
public static class CashItem {
|
||||||
switch (type) {
|
|
||||||
case 1:
|
private final int sn;
|
||||||
return nxCredit;
|
private final int itemId;
|
||||||
case 2:
|
private final int price;
|
||||||
return maplePoint;
|
private final long period;
|
||||||
case 4:
|
private final short count;
|
||||||
return nxPrepaid;
|
private final boolean onSale;
|
||||||
|
|
||||||
|
private CashItem(int sn, int itemId, int price, long period, short count, boolean onSale) {
|
||||||
|
this.sn = sn;
|
||||||
|
this.itemId = itemId;
|
||||||
|
this.price = price;
|
||||||
|
this.period = (period == 0 ? 90 : period);
|
||||||
|
this.count = count;
|
||||||
|
this.onSale = onSale;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
public int getSN() {
|
||||||
|
return sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemId() {
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnSale() {
|
||||||
|
return onSale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item toItem() {
|
||||||
|
Item item;
|
||||||
|
|
||||||
|
int petid = -1;
|
||||||
|
if (ItemConstants.isPet(itemId)) {
|
||||||
|
petid = Pet.createPet(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ItemConstants.getInventoryType(itemId).equals(InventoryType.EQUIP)) {
|
||||||
|
item = ItemInformationProvider.getInstance().getEquipById(itemId);
|
||||||
|
} else {
|
||||||
|
item = new Item(itemId, (byte) 0, count, petid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ItemConstants.EXPIRING_ITEMS) {
|
||||||
|
if (period == 1) {
|
||||||
|
switch (itemId) {
|
||||||
|
case ItemId.DROP_COUPON_2X_4H,
|
||||||
|
ItemId.EXP_COUPON_2X_4H: // 4 Hour 2X coupons, the period is 1, but we don't want them to last a day.
|
||||||
|
item.setExpiration(Server.getInstance().getCurrentTime() + HOURS.toMillis(4));
|
||||||
|
/*
|
||||||
|
} else if(itemId == 5211047 || itemId == 5360014) { // 3 Hour 2X coupons, unused as of now
|
||||||
|
item.setExpiration(Server.getInstance().getCurrentTime() + HOURS.toMillis(3));
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
case ItemId.EXP_COUPON_3X_2H:
|
||||||
|
item.setExpiration(Server.getInstance().getCurrentTime() + HOURS.toMillis(2));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
item.setExpiration(Server.getInstance().getCurrentTime() + DAYS.toMillis(1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.setExpiration(Server.getInstance().getCurrentTime() + DAYS.toMillis(period));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setSN(sn);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SpecialCashItem {
|
||||||
|
private final int sn;
|
||||||
|
private final int modifier;
|
||||||
|
private final byte info; //?
|
||||||
|
|
||||||
|
public SpecialCashItem(int sn, int modifier, byte info) {
|
||||||
|
this.sn = sn;
|
||||||
|
this.modifier = modifier;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSN() {
|
||||||
|
return sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getModifier() {
|
||||||
|
return modifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getInfo() {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CashItemFactory {
|
||||||
|
private static volatile Map<Integer, CashItem> items = new HashMap<>();
|
||||||
|
private static volatile Map<Integer, List<Integer>> packages = new HashMap<>();
|
||||||
|
private static volatile List<SpecialCashItem> specialcashitems = new ArrayList<>();
|
||||||
|
|
||||||
|
public static void loadAllCashItems() {
|
||||||
|
DataProvider etc = DataProviderFactory.getDataProvider(WZFiles.ETC);
|
||||||
|
|
||||||
|
Map<Integer, CashItem> loadedItems = new HashMap<>();
|
||||||
|
for (Data item : etc.getData("Commodity.img").getChildren()) {
|
||||||
|
int sn = DataTool.getIntConvert("SN", item);
|
||||||
|
int itemId = DataTool.getIntConvert("ItemId", item);
|
||||||
|
int price = DataTool.getIntConvert("Price", item, 0);
|
||||||
|
long period = DataTool.getIntConvert("Period", item, 1);
|
||||||
|
short count = (short) DataTool.getIntConvert("Count", item, 1);
|
||||||
|
boolean onSale = DataTool.getIntConvert("OnSale", item, 0) == 1;
|
||||||
|
loadedItems.put(sn, new CashItem(sn, itemId, price, period, count, onSale));
|
||||||
|
}
|
||||||
|
CashItemFactory.items = loadedItems;
|
||||||
|
|
||||||
|
Map<Integer, List<Integer>> loadedPackages = new HashMap<>();
|
||||||
|
for (Data cashPackage : etc.getData("CashPackage.img").getChildren()) {
|
||||||
|
List<Integer> cPackage = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Data item : cashPackage.getChildByPath("SN").getChildren()) {
|
||||||
|
cPackage.add(Integer.parseInt(item.getData().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
loadedPackages.put(Integer.parseInt(cashPackage.getName()), cPackage);
|
||||||
|
}
|
||||||
|
CashItemFactory.packages = loadedPackages;
|
||||||
|
|
||||||
|
List<SpecialCashItem> loadedSpecialItems = new ArrayList<>();
|
||||||
|
try (Connection con = DatabaseConnection.getConnection();
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT * FROM specialcashitems");
|
||||||
|
ResultSet rs = ps.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
loadedSpecialItems.add(new SpecialCashItem(rs.getInt("sn"), rs.getInt("modifier"), rs.getByte("info")));
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
CashItemFactory.specialcashitems = loadedSpecialItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<CashItem> getRandomCashItem() {
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CashItem> itemPool = items.values().stream()
|
||||||
|
.filter(CashItem::isOnSale)
|
||||||
|
.filter(cashItem -> !ItemId.isCashPackage(cashItem.itemId))
|
||||||
|
.toList();
|
||||||
|
return Optional.of(getRandomItem(itemPool));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CashItem getRandomItem(List<CashItem> items) {
|
||||||
|
return items.get(new Random().nextInt(items.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CashItem getItem(int sn) {
|
||||||
|
return items.get(sn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Item> getPackage(int itemId) {
|
||||||
|
List<Item> cashPackage = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int sn : packages.get(itemId)) {
|
||||||
|
cashPackage.add(getItem(sn).toItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
return cashPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPackage(int itemId) {
|
||||||
|
return packages.containsKey(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SpecialCashItem> getSpecialCashItems() {
|
||||||
|
return specialcashitems;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record CashShopSurpriseResult(Item usedCashShopSurprise, Item reward) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCash(int type) {
|
||||||
|
return switch (type) {
|
||||||
|
case NX_CREDIT -> nxCredit;
|
||||||
|
case MAPLE_POINT -> maplePoint;
|
||||||
|
case NX_PREPAID -> nxPrepaid;
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void gainCash(int type, int cash) {
|
public void gainCash(int type, int cash) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case NX_CREDIT -> nxCredit += cash;
|
||||||
nxCredit += cash;
|
case MAPLE_POINT -> maplePoint += cash;
|
||||||
break;
|
case NX_PREPAID -> nxPrepaid += cash;
|
||||||
case 2:
|
|
||||||
maplePoint += cash;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
nxPrepaid += cash;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,17 +396,6 @@ public class CashShop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getItemsSize() {
|
|
||||||
int size = 0;
|
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
size = inventory.size();
|
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Integer> getWishList() {
|
public List<Integer> getWishList() {
|
||||||
return wishList;
|
return wishList;
|
||||||
}
|
}
|
||||||
@@ -537,47 +514,57 @@ public class CashShop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Item getCashShopItemByItemid(int itemid) {
|
public Optional<CashShopSurpriseResult> openCashShopSurprise(long cashId) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
for (Item it : inventory) {
|
Optional<Item> maybeCashShopSurprise = getItemByCashId(cashId);
|
||||||
if (it.getItemId() == itemid) {
|
if (maybeCashShopSurprise.isEmpty() ||
|
||||||
return it;
|
maybeCashShopSurprise.get().getItemId() != ItemId.CASH_SHOP_SURPRISE) {
|
||||||
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item cashShopSurprise = maybeCashShopSurprise.get();
|
||||||
|
if (cashShopSurprise.getQuantity() <= 0) {
|
||||||
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getItemsSize() >= 100) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<CashItem> cashItemReward = CashItemFactory.getRandomCashItem();
|
||||||
|
if (cashItemReward.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
short newQuantity = (short) (cashShopSurprise.getQuantity() - 1);
|
||||||
|
cashShopSurprise.setQuantity(newQuantity);
|
||||||
|
if (newQuantity <= 0) {
|
||||||
|
removeFromInventory(cashShopSurprise);
|
||||||
|
}
|
||||||
|
|
||||||
|
Item itemReward = cashItemReward.get().toItem();
|
||||||
|
addToInventory(itemReward);
|
||||||
|
|
||||||
|
return Optional.of(new CashShopSurpriseResult(cashShopSurprise, itemReward));
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized Pair<Item, Item> openCashShopSurprise() {
|
@GuardedBy("lock")
|
||||||
Item css = getCashShopItemByItemid(ItemId.CASH_SHOP_SURPRISE);
|
private Optional<Item> getItemByCashId(long cashId) {
|
||||||
|
return inventory.stream()
|
||||||
if (css != null) {
|
.filter(item -> item.getCashId() == cashId)
|
||||||
if (getItemsSize() >= 100) {
|
.findAny();
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CashItem cItem = CashItemFactory.getRandomCashItem();
|
public int getItemsSize() {
|
||||||
|
lock.lock();
|
||||||
if (cItem != null) {
|
try {
|
||||||
if (css.getQuantity() > 1) {
|
return inventory.size();
|
||||||
css.setQuantity((short) (css.getQuantity() - 1));
|
} finally {
|
||||||
} else {
|
lock.unlock();
|
||||||
removeFromInventory(css);
|
|
||||||
}
|
|
||||||
|
|
||||||
Item item = cItem.toItem();
|
|
||||||
addToInventory(item);
|
|
||||||
|
|
||||||
return new Pair<>(item, css);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ import net.server.world.Party;
|
|||||||
import net.server.world.PartyCharacter;
|
import net.server.world.PartyCharacter;
|
||||||
import net.server.world.PartyOperation;
|
import net.server.world.PartyOperation;
|
||||||
import net.server.world.World;
|
import net.server.world.World;
|
||||||
|
import server.CashShop;
|
||||||
import server.CashShop.CashItem;
|
import server.CashShop.CashItem;
|
||||||
import server.CashShop.CashItemFactory;
|
import server.CashShop.CashItemFactory;
|
||||||
import server.CashShop.SpecialCashItem;
|
import server.CashShop.SpecialCashItem;
|
||||||
@@ -5580,8 +5581,8 @@ public class PacketCreator {
|
|||||||
|
|
||||||
public static Packet showMTSCash(Character chr) {
|
public static Packet showMTSCash(Character chr) {
|
||||||
final OutPacket p = OutPacket.create(SendOpcode.MTS_OPERATION2);
|
final OutPacket p = OutPacket.create(SendOpcode.MTS_OPERATION2);
|
||||||
p.writeInt(chr.getCashShop().getCash(4));
|
p.writeInt(chr.getCashShop().getCash(CashShop.NX_PREPAID));
|
||||||
p.writeInt(chr.getCashShop().getCash(2));
|
p.writeInt(chr.getCashShop().getCash(CashShop.MAPLE_POINT));
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5689,9 +5690,9 @@ public class PacketCreator {
|
|||||||
|
|
||||||
public static Packet showCash(Character mc) {
|
public static Packet showCash(Character mc) {
|
||||||
final OutPacket p = OutPacket.create(SendOpcode.QUERY_CASH_RESULT);
|
final OutPacket p = OutPacket.create(SendOpcode.QUERY_CASH_RESULT);
|
||||||
p.writeInt(mc.getCashShop().getCash(1));
|
p.writeInt(mc.getCashShop().getCash(CashShop.NX_CREDIT));
|
||||||
p.writeInt(mc.getCashShop().getCash(2));
|
p.writeInt(mc.getCashShop().getCash(CashShop.MAPLE_POINT));
|
||||||
p.writeInt(mc.getCashShop().getCash(4));
|
p.writeInt(mc.getCashShop().getCash(CashShop.NX_PREPAID));
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6479,14 +6480,15 @@ public class PacketCreator {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Packet onCashGachaponOpenSuccess(int accountid, long sn, int remainingBoxes, Item item, int itemid, int nSelectedItemCount, boolean bJackpot) {
|
public static Packet onCashGachaponOpenSuccess(int accountid, long boxCashId, int remainingBoxes, Item reward,
|
||||||
|
int rewardItemId, int rewardQuantity, boolean bJackpot) {
|
||||||
OutPacket p = OutPacket.create(SendOpcode.CASHSHOP_CASH_ITEM_GACHAPON_RESULT);
|
OutPacket p = OutPacket.create(SendOpcode.CASHSHOP_CASH_ITEM_GACHAPON_RESULT);
|
||||||
p.writeByte(0xE5); // subopcode thanks to Ubaware
|
p.writeByte(0xE5); // subopcode thanks to Ubaware
|
||||||
p.writeLong(sn);// sn of the box used
|
p.writeLong(boxCashId);
|
||||||
p.writeInt(remainingBoxes);
|
p.writeInt(remainingBoxes);
|
||||||
addCashItemInformation(p, item, accountid);
|
addCashItemInformation(p, reward, accountid);
|
||||||
p.writeInt(itemid);// the itemid of the liSN?
|
p.writeInt(rewardItemId);
|
||||||
p.writeByte(nSelectedItemCount);// the total count now? o.O
|
p.writeByte(rewardQuantity); // nSelectedItemCount
|
||||||
p.writeBool(bJackpot);// "CashGachaponJackpot"
|
p.writeBool(bJackpot);// "CashGachaponJackpot"
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/test/java/constants/id/ItemIdTest.java
Normal file
19
src/test/java/constants/id/ItemIdTest.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package constants.id;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class ItemIdTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isCashPackage() {
|
||||||
|
assertTrue(ItemId.isCashPackage(9102237));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void isNotCashPackage() {
|
||||||
|
assertFalse(ItemId.isCashPackage(4000000));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -235,4 +235,12 @@ class ByteBufInPacketTest {
|
|||||||
|
|
||||||
assertEquals(initial.length(), afterReadingOpcode.length());
|
assertEquals(initial.length(), afterReadingOpcode.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void equalsShouldCompareBytes() {
|
||||||
|
ByteBufInPacket packet1 = new ByteBufInPacket(Unpooled.wrappedBuffer(new byte[]{ 11, 22, 33, 44 }));
|
||||||
|
ByteBufInPacket packet2 = new ByteBufInPacket(Unpooled.wrappedBuffer(new byte[]{ 11, 22, 33, 44 }));
|
||||||
|
|
||||||
|
assertEquals(packet1, packet2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -203,4 +203,14 @@ class ByteBufOutPacketTest {
|
|||||||
assertEquals(0, wrapped.readByte());
|
assertEquals(0, wrapped.readByte());
|
||||||
assertEquals(secondWrittenByte, wrapped.readByte());
|
assertEquals(secondWrittenByte, wrapped.readByte());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void equalsShouldCompareBytes() {
|
||||||
|
ByteBufOutPacket packet1 = new ByteBufOutPacket();
|
||||||
|
packet1.writeBytes(new byte[] { 55, 66, 77, 88 });
|
||||||
|
ByteBufOutPacket packet2 = new ByteBufOutPacket();
|
||||||
|
packet2.writeBytes(new byte[] { 55, 66, 77, 88 });
|
||||||
|
|
||||||
|
assertEquals(packet1, packet2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package net.server.channel.handlers;
|
||||||
|
|
||||||
|
import client.inventory.Item;
|
||||||
|
import constants.id.ItemId;
|
||||||
|
import net.packet.InPacket;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import server.CashShop;
|
||||||
|
import testutil.HandlerTest;
|
||||||
|
import testutil.Items;
|
||||||
|
import testutil.Packets;
|
||||||
|
import tools.PacketCreator;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class CashShopSurpriseHandlerTest extends HandlerTest {
|
||||||
|
private final CashShopSurpriseHandler handler = new CashShopSurpriseHandler();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CashShop cashShop;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void prepareCashShop() {
|
||||||
|
when(chr.getCashShop()).thenReturn(cashShop);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InPacket useCashShopSurprisePacket(long cashId) {
|
||||||
|
return Packets.buildInPacket(out -> out.writeLong(cashId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldDoNothingWhenCsIsNotOpened() {
|
||||||
|
when(cashShop.isOpened()).thenReturn(false);
|
||||||
|
|
||||||
|
handler.handlePacket(useCashShopSurprisePacket(123), client);
|
||||||
|
|
||||||
|
verify(cashShop, never()).openCashShopSurprise(anyLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldSendFailurePacketWhenFailToOpen() {
|
||||||
|
when(cashShop.isOpened()).thenReturn(true);
|
||||||
|
when(cashShop.openCashShopSurprise(anyLong())).thenReturn(Optional.empty());
|
||||||
|
|
||||||
|
handler.handlePacket(useCashShopSurprisePacket(456), client);
|
||||||
|
|
||||||
|
verify(client).sendPacket(PacketCreator.onCashItemGachaponOpenFailed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldSendSuccessPacketWhenSuccessfullyOpen() {
|
||||||
|
when(cashShop.isOpened()).thenReturn(true);
|
||||||
|
Item cashShopSurprise = Items.itemWithQuantity(ItemId.CASH_SHOP_SURPRISE, 3);
|
||||||
|
Item reward = Items.itemWithQuantity(5000012, 1);
|
||||||
|
when(cashShop.openCashShopSurprise(789)).thenReturn(Optional.of(new CashShop.CashShopSurpriseResult(
|
||||||
|
cashShopSurprise, reward)));
|
||||||
|
|
||||||
|
handler.handlePacket(useCashShopSurprisePacket(789), client);
|
||||||
|
|
||||||
|
verify(client).sendPacket(PacketCreator.onCashGachaponOpenSuccess(ACCOUNT_ID, cashShopSurprise.getCashId(), 3,
|
||||||
|
reward, 5000012, 1, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,10 @@ public class AnyValues {
|
|||||||
return "string";
|
return "string";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static short anyShort() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
public static DaoException daoException() {
|
public static DaoException daoException() {
|
||||||
return new DaoException(string(), new RuntimeException());
|
return new DaoException(string(), new RuntimeException());
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/test/java/testutil/HandlerTest.java
Normal file
24
src/test/java/testutil/HandlerTest.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package testutil;
|
||||||
|
|
||||||
|
import client.Character;
|
||||||
|
import client.Client;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.lenient;
|
||||||
|
|
||||||
|
public abstract class HandlerTest {
|
||||||
|
protected static final int ACCOUNT_ID = 1702;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
protected Client client;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
protected Character chr;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void prepareClient() {
|
||||||
|
lenient().when(client.getAccID()).thenReturn(ACCOUNT_ID);
|
||||||
|
lenient().when(client.getPlayer()).thenReturn(chr);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/test/java/testutil/Items.java
Normal file
10
src/test/java/testutil/Items.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package testutil;
|
||||||
|
|
||||||
|
import client.inventory.Item;
|
||||||
|
|
||||||
|
public class Items {
|
||||||
|
|
||||||
|
public static Item itemWithQuantity(int itemId, int quantity) {
|
||||||
|
return new Item(itemId, AnyValues.anyShort(), (short) quantity);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/test/java/testutil/Packets.java
Normal file
18
src/test/java/testutil/Packets.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package testutil;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import net.packet.ByteBufInPacket;
|
||||||
|
import net.packet.ByteBufOutPacket;
|
||||||
|
import net.packet.InPacket;
|
||||||
|
import net.packet.OutPacket;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class Packets {
|
||||||
|
|
||||||
|
public static InPacket buildInPacket(Consumer<OutPacket> contentProvider) {
|
||||||
|
OutPacket builderInput = new ByteBufOutPacket();
|
||||||
|
contentProvider.accept(builderInput);
|
||||||
|
return new ByteBufInPacket(Unpooled.wrappedBuffer(builderInput.getBytes()));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user