CPQ tidyup patch + Guild Creation matcher + Solution to Login Accid=0

Adjusted AP gains, to get it to work following the AP Reset check method.
Fixed usage of inexistent itemids on CPQ and fishing.
Fixed one-of-a-kind items being lost in player trades due to missing inventory checks.
Implemented matching system for the guild creation phase. All players intending to join the new guild must be on the Guild Headquartes and accept the creation of the guild.
Fixed changing jobs not properly updating info on the party tab.
Fixed double tooltip information on CPQ actions UI.
Fixed CPQ not disbanding after a player leaves the party/instance.
Fixed checks for "in-progress" CPQ instances.
Fixed changing maps on CPQ not leading players back to the starting battlefield.
Reviewed login system, now preventing non-local IP connecting on local server and local IP on non-local server.
Reviewed login system, now cherrypicking sessions in transition state when trying to disconnect them due to a failed login (avoiding possible mishaps due to duplicate sessions of a same account).
Adjusted PiratePQ stage 2, now mobs respawn rather than making party leader request for new waves.
Adjusted Prime Minister, its spawn is no longer related to starting the quest. It should also allow party fights.
Fixed "forcevac" command not properly applying, rather sending to inventory, "consume-on-pickup" items.
Fixed (probably) accId = 0 issue on login, that was occurring due to client accountid's being set to 0 a while before being checked once again on finishLogin().
Fixed an issue with extended time on CPQ not properly showing the end-match's visual effect.
This commit is contained in:
ronancpl
2019-03-26 16:28:41 -03:00
parent 3bdf8cb2be
commit 83266508af
95 changed files with 2980 additions and 1420 deletions
+68 -50
View File
@@ -161,7 +161,6 @@ import constants.skills.Shadower;
import constants.skills.Sniper;
import constants.skills.Swordsman;
import constants.skills.ThunderBreaker;
import net.server.channel.handlers.PartyOperationHandler;
import scripting.item.ItemScriptManager;
import server.life.MobSkillFactory;
import server.maps.MapleMapItem;
@@ -1063,12 +1062,14 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
gainSp(spGain, GameConstants.getSkillBook(newJob.getId()), true);
}
// thanks xinyifly for finding out job advancements awarding APs
/*
if (newJob.getId() % 10 >= 1) {
gainAp(5, true);
// thanks xinyifly for finding out missing AP awards (AP Reset can be used as a compass)
if (newJob.getId() % 100 >= 1) {
if (this.isCygnus()) {
gainAp(7, true);
} else {
gainAp(5, true);
}
}
*/
if (!isGM()) {
for (byte i = 1; i < 5; i++) {
@@ -1128,6 +1129,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
effLock.unlock();
}
setMPC(new MaplePartyCharacter(this));
silentPartyUpdate();
if (dragon != null) {
@@ -1152,7 +1154,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
if (ServerConstants.USE_ANNOUNCE_CHANGEJOB) {
if (!this.isGM()) {
broadcastAcquaintances(6, "[" + GameConstants.ordinal(GameConstants.getJobBranch(newJob)) + " Job] " + name + " has just become a " + newJob.name() + ".");
broadcastAcquaintances(6, "[" + GameConstants.ordinal(GameConstants.getJobBranch(newJob)) + " Job] " + name + " has just become a " + GameConstants.getJobName(this.job.getId()) + "."); // thanks Vcoc for noticing job name appearing in uppercase here
}
}
}
@@ -1199,14 +1201,16 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
public MapleMap getWarpMap(int map) {
MapleMap target;
MapleMap warpMap;
EventInstanceManager eim = getEventInstance();
if (eim == null) {
target = client.getChannelServer().getMapFactory().getMap(map);
if (eim != null) {
warpMap = eim.getMapInstance(map);
} else if (this.getMonsterCarnival() != null && this.getMonsterCarnival().getEventMap().getId() == map) {
warpMap = this.getMonsterCarnival().getEventMap();
} else {
target = eim.getMapInstance(map);
warpMap = client.getChannelServer().getMapFactory().getMap(map);
}
return target;
return warpMap;
}
// for use ONLY inside OnUserEnter map scripts that requires a player to change map while still moving between maps.
@@ -1812,14 +1816,14 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
}
private boolean useItem(final int id) {
if (id / 1000000 == 2) {
if (ii.isConsumeOnPickup(id)) {
if (ItemConstants.isPartyItem(id)) {
public boolean applyConsumeOnPickup(final int itemid) {
if (itemid / 1000000 == 2) {
if (ii.isConsumeOnPickup(itemid)) {
if (ItemConstants.isPartyItem(itemid)) {
List<MapleCharacter> pchr = this.getPartyMembersOnSameMap();
if(!ItemConstants.isPartyAllcure(id)) {
MapleStatEffect mse = ii.getItemEffect(id);
if(!ItemConstants.isPartyAllcure(itemid)) {
MapleStatEffect mse = ii.getItemEffect(itemid);
if(!pchr.isEmpty()) {
for (MapleCharacter mc : pchr) {
@@ -1838,7 +1842,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
}
} else {
ii.getItemEffect(id).applyTo(this);
ii.getItemEffect(itemid).applyTo(this);
}
if (itemid / 10000 == 238) {
this.getMonsterBook().addCard(client, itemid);
}
return true;
}
@@ -1955,10 +1963,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
this.getCashShop().gainCash(1, nxGain);
showHint("You have earned #e#b" + nxGain + " NX#k#n. (" + this.getCashShop().getCash(1) + " NX)", 300);
} else if (useItem(mItem.getItemId())) {
if (mItem.getItemId() / 10000 == 238) {
this.getMonsterBook().addCard(client, mItem.getItemId());
}
} else if (applyConsumeOnPickup(mItem.getItemId())) {
} else if (MapleInventoryManipulator.addFromDrop(client, mItem, true)) {
} else if (mItem.getItemId() == 4031868) {
this.getMap().broadcastMessage(MaplePacketCreator.updateAriantPQRanking(this.getName(), this.getItemQuantity(4031868, false), false));
@@ -5647,11 +5652,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
public boolean haveItem(int itemid) {
return getItemQuantity(itemid, false) > 0;
return getItemQuantity(itemid, ItemConstants.isEquipment(itemid)) > 0;
}
public boolean haveCleanItem(int itemid) {
return getCleanItemQuantity(itemid, false) > 0;
return getCleanItemQuantity(itemid, ItemConstants.isEquipment(itemid)) > 0;
}
public boolean hasEmptySlot(int itemId) {
@@ -5847,7 +5852,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
public boolean attemptCatchFish(int baitLevel) {
return GameConstants.isFishingArea(mapid) && this.getPosition().getY() > 0 && ItemConstants.isFishingChair(chair.get()) && this.getWorldServer().registerFisherPlayer(this, baitLevel);
return ServerConstants.USE_FISHING_SYSTEM && GameConstants.isFishingArea(mapid) && this.getPosition().getY() > 0 && ItemConstants.isFishingChair(chair.get()) && this.getWorldServer().registerFisherPlayer(this, baitLevel);
}
public void leaveMap() {
@@ -5969,8 +5974,15 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
} else {
int remainingAp = 5;
if (isCygnus() && level > 10 && level < 70) {
remainingAp++;
if (isCygnus()) {
if (level > 10) {
if (level <= 17) {
remainingAp += 2;
} else if (level < 77) {
remainingAp++;
}
}
}
gainAp(remainingAp, true);
@@ -6119,23 +6131,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
Runnable r = new Runnable() {
@Override
public void run() {
MapleParty party;
boolean partyLeader;
prtLock.lock();
try {
party = getParty();
partyLeader = party != null && isPartyLeader();
} finally {
prtLock.unlock();
}
if (party != null) {
if(partyLeader) {
party.assignNewLeader(client);
}
PartyOperationHandler.leaveParty(party, mpc, client);
if (leaveParty()) {
showHint("You have reached #blevel 10#k, therefore you must leave your #rstarter party#k.");
}
}
@@ -6147,6 +6143,28 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
levelUpMessages();
guildUpdate();
}
public boolean leaveParty() {
MapleParty party;
boolean partyLeader;
prtLock.lock();
try {
party = getParty();
partyLeader = party != null && isPartyLeader();
} finally {
prtLock.unlock();
}
if (party != null) {
if(partyLeader) party.assignNewLeader(client);
MapleParty.leaveParty(party, client);
return true;
} else {
return false;
}
}
private void levelUpMessages() {
if (level % 5 != 0) { //Performance FTW?
@@ -10288,11 +10306,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
this.challenged = challenged;
}
public void setLingua(int num) {
getClient().setLingua(num);
public void setLanguage(int num) {
getClient().setLanguage(num);
try {
Connection con = DatabaseConnection.getConnection();
try (PreparedStatement ps = con.prepareStatement("UPDATE accounts SET lingua = ? WHERE id = ?")) {
try (PreparedStatement ps = con.prepareStatement("UPDATE accounts SET language = ? WHERE id = ?")) {
ps.setInt(1, num);
ps.setInt(2, getClient().getAccID());
ps.executeUpdate();
@@ -10304,8 +10322,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
}
public int getLingua() {
return getClient().getLingua();
public int getLanguage() {
return getClient().getLanguage();
}
}
+37 -17
View File
@@ -90,12 +90,13 @@ public class MapleClient {
public static final String CLIENT_KEY = "CLIENT";
public static final String CLIENT_HWID = "HWID";
public static final String CLIENT_NIBBLEHWID = "HWID2";
public static final String CLIENT_REMOTE_ADDRESS = "REMOTE_IP";
private MapleAESOFB send;
private MapleAESOFB receive;
private final IoSession session;
private MapleCharacter player;
private int channel = 1;
private int accId = 0;
private int accId = -4;
private boolean loggedIn = false;
private boolean serverTransition = false;
private Calendar birthday = null;
@@ -124,7 +125,7 @@ public class MapleClient {
private int visibleWorlds;
private long lastNpcClick;
private long sessionId;
private int lingua = 0;
private int lang = 0;
static {
for (int i = 0; i < 200; i++) {
@@ -534,7 +535,7 @@ public class MapleClient {
if (loginattempt > 4) {
loggedIn = false;
MapleSessionCoordinator.getInstance().closeSession(session, false);
return loginok;
return 6; // thanks Survival_Project for finding out an issue with AUTOMATIC_REGISTER here
}
Connection con = null;
@@ -542,16 +543,15 @@ public class MapleClient {
ResultSet rs = null;
try {
con = DatabaseConnection.getConnection();
ps = con.prepareStatement("SELECT id, password, gender, banned, pin, pic, characterslots, tos, lingua FROM accounts WHERE name = ?");
ps = con.prepareStatement("SELECT id, password, gender, banned, pin, pic, characterslots, tos, language FROM accounts WHERE name = ?");
ps.setString(1, login);
rs = ps.executeQuery();
accId = -2;
if (rs.next()) {
accId = rs.getInt("id");
if (accId == 0) {
// odd case where accId is actually attributed as 0 (further on this leads to getLoginState ACCID = 0, an absurd), thanks Thora for finding this issue
return 15;
} else if (accId < 0) {
if (accId <= 0) {
FilePrinter.printError(FilePrinter.LOGIN_EXCEPTION, "Tried to login with accid " + accId);
return 15;
}
boolean banned = (rs.getByte("banned") == 1);
@@ -560,7 +560,7 @@ public class MapleClient {
pic = rs.getString("pic");
gender = rs.getByte("gender");
characterSlots = rs.getByte("characterslots");
lingua = rs.getInt("lingua");
lang = rs.getInt("language");
String passhash = rs.getString("password");
byte tos = rs.getByte("tos");
@@ -583,7 +583,9 @@ public class MapleClient {
loggedIn = false;
loginok = 4;
}
}
} else {
accId = -3;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
@@ -822,9 +824,10 @@ public class MapleClient {
int state = rs.getInt("loggedin");
if (state == LOGIN_SERVER_TRANSITION) {
if (rs.getTimestamp("lastlogin").getTime() + 30000 < Server.getInstance().getCurrentTime()) {
int accountId = accId;
state = LOGIN_NOTLOGGEDIN;
MapleSessionCoordinator.getInstance().closeSession(session, null);
updateLoginState(LOGIN_NOTLOGGEDIN);
updateLoginState(LOGIN_NOTLOGGEDIN); // ACCID = 0, issue found thanks to Tochi & K u ssss o & Thora & Omo Oppa
this.setAccID(accountId);
}
}
rs.close();
@@ -1026,6 +1029,9 @@ public class MapleClient {
MapleSessionCoordinator.getInstance().closeSession(session, false);
session.removeAttribute(MapleClient.CLIENT_KEY);
}
if (!Server.getInstance().hasCharacteridInTransition(session)) {
updateLoginState(MapleClient.LOGIN_NOTLOGGEDIN);
}
engines = null; // thanks Tochi for pointing out a NPE here
}
@@ -1068,7 +1074,21 @@ public class MapleClient {
public boolean deleteCharacter(int cid, int senderAccId) {
try {
return MapleCharacter.deleteCharFromDB(MapleCharacter.loadCharFromDB(cid, this, false), senderAccId);
MapleCharacter chr = MapleCharacter.loadCharFromDB(cid, this, false);
Integer partyid = chr.getWorldServer().getCharacterPartyid(cid);
if (partyid != null) {
this.setPlayer(chr);
MapleParty party = chr.getWorldServer().getParty(partyid);
chr.setParty(party);
chr.getMPC();
chr.leaveParty(); // thanks Vcoc for pointing out deleted characters would still stay in a party
this.setPlayer(null);
}
return MapleCharacter.deleteCharFromDB(chr, senderAccId);
} catch(SQLException ex) {
ex.printStackTrace();
return false;
@@ -1545,11 +1565,11 @@ public class MapleClient {
return MapleLoginBypassCoordinator.getInstance().canLoginBypass(getNibbleHWID(), accId, true);
}
public int getLingua() {
return lingua;
public int getLanguage() {
return lang;
}
public void setLingua(int lingua) {
this.lingua = lingua;
public void setLanguage(int lingua) {
this.lang = lingua;
}
}
+1 -1
View File
@@ -186,7 +186,7 @@ public class CommandsExecutor {
addCommand("uptime", UptimeCommand.class);
addCommand("gacha", GachaCommand.class);
addCommand("dispose", DisposeCommand.class);
addCommand("changel", ChangeLinguaCommand.class);
addCommand("changel", ChangeLanguageCommand.class);
addCommand("equiplv", EquipLvCommand.class);
addCommand("showrates", ShowRatesCommand.class);
addCommand("rates", RatesCommand.class);
@@ -26,7 +26,7 @@ package client.command.commands.gm0;
import client.command.Command;
import client.MapleClient;
public class ChangeLinguaCommand extends Command {
public class ChangeLanguageCommand extends Command {
{
setDescription("");
}
@@ -37,6 +37,6 @@ public class ChangeLinguaCommand extends Command {
c.getPlayer().yellowMessage("Syntax: !changel <0=ptb, 1=esp, 2=eng>");
return;
}
c.setLingua(Integer.parseInt(params[0]));
c.setLanguage(Integer.parseInt(params[0]));
}
}
@@ -51,7 +51,7 @@ public class GmCommand extends Command {
return;
}
String message = player.getLastCommandMessage();
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.sendYellowTip("[GM MESSAGE]:" + MapleCharacter.makeMapleReadable(player.getName()) + ": " + message));
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.sendYellowTip("[GM Message]:" + MapleCharacter.makeMapleReadable(player.getName()) + ": " + message));
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.serverNotice(1, message));
FilePrinter.printError(FilePrinter.COMMAND_GM, MapleCharacter.makeMapleReadable(player.getName()) + ": " + message);
player.dropMessage(5, "Your message '" + message + "' was sent to GMs.");
@@ -44,7 +44,7 @@ public class ReportBugCommand extends Command {
return;
}
String message = player.getLastCommandMessage();
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.sendYellowTip("[BUG]:" + MapleCharacter.makeMapleReadable(player.getName()) + ": " + message));
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.sendYellowTip("[Bug]:" + MapleCharacter.makeMapleReadable(player.getName()) + ": " + message));
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.serverNotice(1, message));
FilePrinter.printError(FilePrinter.COMMAND_BUG, MapleCharacter.makeMapleReadable(player.getName()) + ": " + message);
player.dropMessage(5, "Your bug '" + message + "' was submitted successfully to our developers. Thank you!");
@@ -42,7 +42,6 @@ public class CakeCommand extends Command {
double mobHp = Double.parseDouble(params[0]);
int newHp = (mobHp <= 0) ? Integer.MAX_VALUE : ((mobHp > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int) mobHp);
monster.getStats().setHp(newHp);
monster.setStartingHp(newHp);
}
@@ -54,6 +54,7 @@ public class ForceVacCommand extends Command {
if (mapItem.getMeso() > 0) {
player.gainMeso(mapItem.getMeso(), true);
} else if (player.applyConsumeOnPickup(mapItem.getItemId())) { // thanks Vcoc for pointing out consumables on pickup not being processed here
} else if (mapItem.getItemId() == 4031865 || mapItem.getItemId() == 4031866) {
// Add NX to account, show effect and make item disappear
player.getCashShop().gainCash(1, mapItem.getItemId() == 4031865 ? 100 : 250);
@@ -84,7 +84,7 @@ public class DebugCommand extends Command {
case "portal":
MaplePortal portal = player.getMap().findClosestPortal(player.getPosition());
if (portal != null)
player.dropMessage(6, "Closest portal: " + portal.getId() + " '" + portal.getName() + "' Type: " + portal.getType() + " --> toMap: " + portal.getTargetMapId() + " scriptname: '" + portal.getScriptName() + "' state: " + portal.getPortalState() + ".");
player.dropMessage(6, "Closest portal: " + portal.getId() + " '" + portal.getName() + "' Type: " + portal.getType() + " --> toMap: " + portal.getTargetMapId() + " scriptname: '" + portal.getScriptName() + "' state: " + (portal.getPortalState() ? 1 : 0) + ".");
else player.dropMessage(6, "There is no portal on this map.");
break;
+1 -1
View File
@@ -93,7 +93,7 @@ public abstract class CharacterFactory {
c.announce(MaplePacketCreator.addNewCharEntry(newchar));
Server.getInstance().createCharacterEntry(newchar);
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.sendYellowTip("[NEW CHAR]: " + c.getAccountName() + " has created a new character with IGN " + name));
Server.getInstance().broadcastGMMessage(c.getWorld(), MaplePacketCreator.sendYellowTip("[New Char]: " + c.getAccountName() + " has created a new character with IGN " + name));
FilePrinter.print(FilePrinter.CREATED_CHAR + c.getAccountName() + ".txt", c.getAccountName() + " created character with IGN " + name);
return 0;
@@ -265,8 +265,12 @@ public class MapleInventoryManipulator {
MapleCharacter chr = c.getPlayer();
MapleInventory inv = chr.getInventory(type);
if(ii.isPickupRestricted(itemid) && haveItemWithId(inv, itemid)) {
return false;
if (ii.isPickupRestricted(itemid)) {
if (haveItemWithId(inv, itemid)) {
return false;
} else if (ItemConstants.isEquipment(itemid) && haveItemWithId(chr.getInventory(MapleInventoryType.EQUIPPED), itemid)) {
return false;
}
}
if (!type.equals(MapleInventoryType.EQUIP)) {
@@ -313,8 +317,12 @@ public class MapleInventoryManipulator {
MapleCharacter chr = c.getPlayer();
MapleInventory inv = chr.getInventory(type);
if(ii.isPickupRestricted(itemid) && haveItemWithId(inv, itemid)) {
return 0;
if (ii.isPickupRestricted(itemid)) {
if (haveItemWithId(inv, itemid)) {
return 0;
} else if (ItemConstants.isEquipment(itemid) && haveItemWithId(chr.getInventory(MapleInventoryType.EQUIPPED), itemid)) {
return 0; // thanks Captain & Aika & Vcoc for pointing out inventory checkup on player trades missing out one-of-a-kind items.
}
}
if (!type.equals(MapleInventoryType.EQUIP)) {
@@ -430,7 +438,7 @@ public class MapleInventoryManipulator {
}
}
if (removeQuantity > 0 && type != MapleInventoryType.CANHOLD) {
throw new RuntimeException("[HACK] Not enough items available of Item:" + itemId + ", Quantity (After Quantity/Over Current Quantity): " + (quantity - removeQuantity) + "/" + quantity);
throw new RuntimeException("[Hack] Not enough items available of Item:" + itemId + ", Quantity (After Quantity/Over Current Quantity): " + (quantity - removeQuantity) + "/" + quantity);
}
}
+2 -2
View File
@@ -318,7 +318,7 @@ public class NewYearCardRecord {
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.");
other.dropMessage(6, "[New Year] " + chr.getName() + " threw away the New Year card.");
}
}
} else {
@@ -336,7 +336,7 @@ public class NewYearCardRecord {
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.");
other.dropMessage(6, "[New Year] " + chr.getName() + " threw away the New Year card.");
}
}
}
+3 -20
View File
@@ -42,6 +42,7 @@ import java.util.List;
import net.server.channel.Channel;
import server.DueyPackages;
import server.MapleItemInformationProvider;
import server.MapleTrade;
import tools.DatabaseConnection;
import tools.FilePrinter;
import tools.MaplePacketCreator;
@@ -230,24 +231,6 @@ public class DueyProcessor {
}
}
private static int getFee(long meso) {
long fee = 0;
if (meso >= 100000000) {
fee = (meso * 6) / 100;
} else if (meso >= 25000000) {
fee = (meso * 5) / 100;
} else if (meso >= 10000000) {
fee = (meso * 4) / 100;
} else if (meso >= 5000000) {
fee = (meso * 3) / 100;
} else if (meso >= 1000000) {
fee = (meso * 18) / 1000;
} else if (meso >= 100000) {
fee = (meso * 8) / 1000;
}
return (int) fee;
}
private static void addMesoToDB(int mesos, String sName, int recipientID) {
addItemToDB(null, 1, mesos, sName, recipientID);
}
@@ -404,7 +387,7 @@ public class DueyProcessor {
}
MapleKarmaManipulator.toggleKarmaFlagToUntradeable(item);
addItemToDB(item, amount, mesos - getFee(mesos), c.getPlayer().getName(), getAccIdFromCNAME(recipient, false));
addItemToDB(item, amount, mesos - MapleTrade.getFee(mesos), c.getPlayer().getName(), getAccIdFromCNAME(recipient, false));
} else {
if (item != null) {
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_INCORRECT_REQUEST.getCode()));
@@ -415,7 +398,7 @@ public class DueyProcessor {
c.getPlayer().gainMeso(-finalcost, false);
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_SUCCESSFULLY_SENT.getCode()));
addMesoToDB(mesos - getFee(mesos), c.getPlayer().getName(), getAccIdFromCNAME(recipient, false));
addMesoToDB(mesos - MapleTrade.getFee(mesos), c.getPlayer().getName(), getAccIdFromCNAME(recipient, false));
}
if (rClient != null && rClient.isLoggedIn() && !rClient.getPlayer().isAwayFromWorld()) {
+49 -49
View File
@@ -7,65 +7,65 @@ import client.MapleCharacter;
* @author Drago - Dragohe4rt
*/
public class LanguageConstants {
// Portugues
public static String CPQAzul;
public static String CPQErro;
public static String CPQEntrada;
public static String CPQEscolha;
public static String CPQVermelho;
public static String CPQBlue;
public static String CPQError;
public static String CPQEntry;
public static String CPQFindError;
public static String CPQRed;
public static String CPQPlayerExit;
public static String CPQEntradaLobby;
public static String CPQInicioEscolha;
public static String CPQTempoExtendido;
public static String CPQLiderNaoEncontrado;
public static String CPQInicioEscolhaEmEscolha;
public static String CPQInicioEscolhaEnviada;
public static String CPQEntryLobby;
public static String CPQPickRoom;
public static String CPQExtendTime;
public static String CPQLeaderNotFound;
public static String CPQChallengeRoomAnswer;
public static String CPQChallengeRoomSent;
public static LanguageConstants Linguas(MapleCharacter chr) {
if (chr.getLingua() == 0) {
LanguageConstants.CPQAzul = "Maple Azul";
LanguageConstants.CPQVermelho = "Maple Vermelho";
LanguageConstants.CPQTempoExtendido = "O tempo foi estendido.";
public static LanguageConstants Languages(MapleCharacter chr) {
if (chr.getLanguage() == 0) {
LanguageConstants.CPQBlue = "Maple Azul";
LanguageConstants.CPQRed = "Maple Vermelho";
LanguageConstants.CPQExtendTime = "O tempo foi estendido.";
LanguageConstants.CPQPlayerExit = " deixou o Carnaval de Monstros.";
LanguageConstants.CPQErro = "Ocorreu um problema. Favor recriar a sala.";
LanguageConstants.CPQLiderNaoEncontrado = "Nao foi possivel encontrar o Lider.";
LanguageConstants.CPQInicioEscolha = "Inscreva-se no Festival de Monstros!\\r\\n";
LanguageConstants.CPQInicioEscolhaEmEscolha = "O grupo esta respondendo um desafio no momento.";
LanguageConstants.CPQInicioEscolhaEnviada = "Um desafio foi enviado para o grupo na sala. Aguarde um momento.";
LanguageConstants.CPQEscolha = "Nao foi possivel encontrar um grupo nesta sala.\\r\\nProvavelmente o grupo foi desfeito dentro da sala!";
LanguageConstants.CPQEntradaLobby = "Agora voce ira receber desafios de outros grupos. Se voce nao aceitar um desafio em 3 minutos, voce sera levado para fora.";
LanguageConstants.CPQEntrada = "Voce pode selecionar \"Invocar Monstros\", \"Habilidade\", ou \"Protetor\" como sua tatica durante o Carnaval dos Monstros. Use Tab a F1~F12 para acesso rapido!";
LanguageConstants.CPQError = "Ocorreu um problema. Favor recriar a sala.";
LanguageConstants.CPQLeaderNotFound = "Nao foi possivel encontrar o Lider.";
LanguageConstants.CPQPickRoom = "Inscreva-se no Festival de Monstros!\r\n";
LanguageConstants.CPQChallengeRoomAnswer = "O grupo esta respondendo um desafio no momento.";
LanguageConstants.CPQChallengeRoomSent = "Um desafio foi enviado para o grupo na sala. Aguarde um momento.";
LanguageConstants.CPQFindError = "Nao foi possivel encontrar um grupo nesta sala.\r\nProvavelmente o grupo foi desfeito dentro da sala!";
LanguageConstants.CPQEntryLobby = "Agora voce ira receber desafios de outros grupos. Se voce nao aceitar um desafio em 3 minutos, voce sera levado para fora.";
LanguageConstants.CPQEntry = "Voce pode selecionar \"Invocar Monstros\", \"Habilidade\", ou \"Protetor\" como sua tatica durante o Carnaval dos Monstros. Use Tab a F1~F12 para acesso rapido!";
} else if (chr.getLingua() == 1) {
LanguageConstants.CPQAzul = "Maple Azul";
LanguageConstants.CPQVermelho = "Maple Rojo";
LanguageConstants.CPQTempoExtendido = "El tiempo se ha ampliado.";
} else if (chr.getLanguage() == 1) {
LanguageConstants.CPQBlue = "Maple Azul";
LanguageConstants.CPQRed = "Maple Rojo";
LanguageConstants.CPQExtendTime = "El tiempo se ha ampliado.";
LanguageConstants.CPQPlayerExit = " ha dejado el Carnaval de Monstruos.";
LanguageConstants.CPQLiderNaoEncontrado = "No se pudo encontrar el Lider.";
LanguageConstants.CPQInicioEscolha = "!Inscribete en el Festival de Monstruos!\\r\\n";
LanguageConstants.CPQErro = "Se ha producido un problema. Por favor, volver a crear una sala.";
LanguageConstants.CPQInicioEscolhaEmEscolha = "El grupo esta respondiendo un desafio en el momento.";
LanguageConstants.CPQInicioEscolhaEnviada = "Un desafio fue enviado al grupo en la sala. Espera un momento.";
LanguageConstants.CPQEscolha = "No se pudo encontrar un grupo en esta sala.\\r\\nProbablemente el grupo fue deshecho dentro de la sala!";
LanguageConstants.CPQEntradaLobby = "Ahora usted recibira los retos de otros grupos. Si usted no acepta un desafio en 3 minutos, usted sera llevado hacia fuera.";
LanguageConstants.CPQEntrada = "Usted puede seleccionar \"Invocar Monstruos \", \"Habilidad \", o \"Protector \" como su tactica durante el Carnaval de los Monstruos. Utilice Tab y F1 ~ F12 para acceso rapido!";
LanguageConstants.CPQLeaderNotFound = "No se pudo encontrar el Lider.";
LanguageConstants.CPQPickRoom = "!Inscribete en el Festival de Monstruos!\r\n";
LanguageConstants.CPQError = "Se ha producido un problema. Por favor, volver a crear una sala.";
LanguageConstants.CPQChallengeRoomAnswer = "El grupo esta respondiendo un desafio en el momento.";
LanguageConstants.CPQChallengeRoomSent = "Un desafio fue enviado al grupo en la sala. Espera un momento.";
LanguageConstants.CPQFindError = "No se pudo encontrar un grupo en esta sala.\r\nProbablemente el grupo fue deshecho dentro de la sala!";
LanguageConstants.CPQEntryLobby = "Ahora usted recibira los retos de otros grupos. Si usted no acepta un desafio en 3 minutos, usted sera llevado hacia fuera.";
LanguageConstants.CPQEntry = "Usted puede seleccionar \"Invocar Monstruos \", \"Habilidad \", o \"Protector \" como su tactica durante el Carnaval de los Monstruos. Utilice Tab y F1 ~ F12 para acceso rapido!";
} else if (chr.getLingua() == 2) {
LanguageConstants.CPQAzul = "Maple Blue";
LanguageConstants.CPQVermelho = "Maple Red";
} else if (chr.getLanguage() == 2) {
LanguageConstants.CPQBlue = "Maple Blue";
LanguageConstants.CPQRed = "Maple Red";
LanguageConstants.CPQPlayerExit = " left the Carnival of Monsters.";
LanguageConstants.CPQTempoExtendido = "The time has been extended.";
LanguageConstants.CPQLiderNaoEncontrado = "Could not find the Leader.";
LanguageConstants.CPQErro = "There was a problem. Please re-create a room.";
LanguageConstants.CPQInicioEscolha = "Sign up for the Monster Festival!\\r\\n";
LanguageConstants.CPQInicioEscolhaEmEscolha = "The group is currently facing a challenge.";
LanguageConstants.CPQInicioEscolhaEnviada = "A challenge has been sent to the group in the room. Please wait a while.";
LanguageConstants.CPQEscolha = "We could not find a group in this room.\\r\\nProbably the group was scrapped inside the room!";
LanguageConstants.CPQEntradaLobby = "You will now receive challenges from other groups. If you do not accept a challenge within 3 minutes, you will be taken out.";
LanguageConstants.CPQEntrada = "You can select \"Summon Monsters \", \"Ability \", or \"Protector \" as your tactic during the Monster Carnival. Use Tab and F1 ~ F12 for quick access!";
LanguageConstants.CPQExtendTime = "The time has been extended.";
LanguageConstants.CPQLeaderNotFound = "Could not find the Leader.";
LanguageConstants.CPQError = "There was a problem. Please re-create a room.";
LanguageConstants.CPQPickRoom = "Sign up for the Monster Festival!\r\n";
LanguageConstants.CPQChallengeRoomAnswer = "The group is currently facing a challenge.";
LanguageConstants.CPQChallengeRoomSent = "A challenge has been sent to the group in the room. Please wait a while.";
LanguageConstants.CPQFindError = "We could not find a group in this room.\r\nProbably the group was scrapped inside the room!";
LanguageConstants.CPQEntryLobby = "You will now receive challenges from other groups. If you do not accept a challenge within 3 minutes, you will be taken out.";
LanguageConstants.CPQEntry = "You can select \"Summon Monsters \", \"Ability \", or \"Protector \" as your tactic during the Monster Carnival. Use Tab and F1 ~ F12 for quick access!";
}
return null;
+6 -1
View File
@@ -28,7 +28,7 @@ public class ServerConstants {
public static final long COUPON_INTERVAL = 60 * 60 * 1000; //60 minutes, 3600000.
public static final long UPDATE_INTERVAL = 777; //Dictates the frequency on which the "centralized server time" is updated.
public static final boolean ENABLE_PIC = false; //Pick true/false to enable or disable Pic. Delete character required PIC available.
public static final boolean ENABLE_PIC = false; //Pick true/false to enable or disable Pic. Delete character requires PIC available.
public static final boolean ENABLE_PIN = false; //Pick true/false to enable or disable Pin.
public static final int BYPASS_PIC_EXPIRATION = 20; //Enables PIC bypass, which will remain active for that account by that client machine for N minutes. Set 0 to disable.
@@ -48,6 +48,7 @@ public class ServerConstants {
//Ip Configuration
public static String HOST;
public static boolean LOCALSERVER;
//Other Configuration
public static boolean JAVA_8;
@@ -66,6 +67,7 @@ public class ServerConstants {
public static final boolean USE_MAXRANGE = true; //Will send and receive packets from all events on a map, rather than those of only view range.
public static final boolean USE_MAXRANGE_ECHO_OF_HERO = true;
public static final boolean USE_MTS = false;
public static final boolean USE_CPQ = true; //Renders the CPQ available or not.
public static final boolean USE_AUTOHIDE_GM = false; //When enabled, GMs are automatically hidden when joining. Thanks to Steven Deblois (steven1152).
public static final boolean USE_BUYBACK_SYSTEM = true; //Enables the HeavenMS-builtin buyback system, to be used by dead players when clicking the MTS button.
public static final boolean USE_FIXED_RATIO_HPMP_UPDATE = true; //Enables the HeavenMS-builtin HPMP update based on the current pool to max pool ratio.
@@ -108,6 +110,7 @@ public class ServerConstants {
public static final boolean USE_ENABLE_CHAT_LOG = false; //Write in-game chat to log
public static final boolean USE_REBIRTH_SYSTEM = false; //Flag to enable/disable rebirth system
public static final boolean USE_MAP_OWNERSHIP_SYSTEM = true; //Flag to enable/disable map ownership system
public static final boolean USE_FISHING_SYSTEM = true; //Flag to enable/disable fishing system
//Events/PQs Configuration
public static final boolean USE_OLD_GMS_STYLED_PQ_NPCS = true; //Enables PQ NPCs with similar behaviour to old GMS style, that skips info about the PQs and immediately tries to register the party in.
@@ -219,6 +222,7 @@ public class ServerConstants {
public static final int QUEST_POINT_PER_EVENT_CLEAR = 1; //Each completed event instance awards N quest points, set 0 to disable.
//Guild Configuration
public static final int CREATE_GUILD_MIN_PARTNERS = 6; //Minimum number of members on Guild Headquarters to establish a new guild.
public static final int CREATE_GUILD_COST = 1500000;
public static final int CHANGE_EMBLEM_COST = 5000000;
public static final int EXPAND_GUILD_BASE_COST = 500000;
@@ -302,6 +306,7 @@ public class ServerConstants {
//Server Host
ServerConstants.HOST = p.getProperty("HOST");
ServerConstants.LOCALSERVER = ServerConstants.HOST.startsWith("127.") || ServerConstants.HOST.startsWith("localhost");
//Sql Database
ServerConstants.DB_URL = p.getProperty("URL");
+3
View File
@@ -34,6 +34,7 @@ import org.apache.mina.core.session.IoSession;
import client.MapleClient;
import constants.ServerConstants;
import java.net.InetSocketAddress;
import net.server.Server;
import net.server.audit.locks.MonitoredLockType;
@@ -105,6 +106,8 @@ public class MapleServerHandler extends IoHandlerAdapter {
@Override
public void sessionOpened(IoSession session) {
session.setAttribute(MapleClient.CLIENT_REMOTE_ADDRESS, ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress());
if (!Server.getInstance().isOnline()) {
MapleSessionCoordinator.getInstance().closeSession(session, true);
return;
+29 -6
View File
@@ -98,6 +98,7 @@ import server.quest.MapleQuest;
import tools.AutoJCE;
import tools.DatabaseConnection;
import tools.Pair;
import org.apache.mina.core.session.IoSession;
public class Server {
@@ -1630,12 +1631,12 @@ public class Server {
return gmLevel;
}
private static String getRemoteIp(InetSocketAddress isa) {
return isa.getAddress().getHostAddress();
private static String getRemoteIp(IoSession session) {
return MapleSessionCoordinator.getSessionRemoteAddress(session);
}
public void setCharacteridInTransition(InetSocketAddress isa, int charId) {
String remoteIp = getRemoteIp(isa);
public void setCharacteridInTransition(IoSession session, int charId) {
String remoteIp = getRemoteIp(session);
lgnWLock.lock();
try {
@@ -1645,8 +1646,8 @@ public class Server {
}
}
public boolean validateCharacteridInTransition(InetSocketAddress isa, int charId) {
String remoteIp = getRemoteIp(isa);
public boolean validateCharacteridInTransition(IoSession session, int charId) {
String remoteIp = getRemoteIp(session);
lgnWLock.lock();
try {
@@ -1657,6 +1658,28 @@ public class Server {
}
}
public Integer freeCharacteridInTransition(IoSession session) {
String remoteIp = getRemoteIp(session);
lgnWLock.lock();
try {
return transitioningChars.remove(remoteIp);
} finally {
lgnWLock.unlock();
}
}
public boolean hasCharacteridInTransition(IoSession session) {
String remoteIp = getRemoteIp(session);
lgnRLock.lock();
try {
return transitioningChars.containsKey(remoteIp);
} finally {
lgnRLock.unlock();
}
}
public void registerLoginState(MapleClient c) {
srvLock.lock();
try {
+17
View File
@@ -106,6 +106,7 @@ public final class Channel {
private MapleEvent event;
private boolean finishedShutdown = false;
private int usedDojo = 0;
private Set<Integer> usedMC = new HashSet<>();
private ScheduledFuture<?> respawnTask;
@@ -992,6 +993,22 @@ public final class Channel {
}
}
private static int getMonsterCarnivalRoom(boolean cpq1, int field) {
return (cpq1 ? 0 : 100) + field;
}
public void initMonsterCarnival(boolean cpq1, int field) {
usedMC.add(getMonsterCarnivalRoom(cpq1, field));
}
public void finishMonsterCarnival(boolean cpq1, int field) {
usedMC.remove(getMonsterCarnivalRoom(cpq1, field));
}
public boolean canInitMonsterCarnival(boolean cpq1, int field) {
return !usedMC.contains(getMonsterCarnivalRoom(cpq1, field));
}
private static int getChannelSchedulerIndex(int mapid) {
int section = 1000000000 / ServerConstants.CHANNEL_LOCKS;
return mapid / section;
@@ -30,8 +30,13 @@ import net.AbstractMaplePacketHandler;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.MaplePacketCreator;
import client.MapleCharacter;
import java.util.HashSet;
import java.util.Set;
import net.server.Server;
import net.server.coordinator.matchchecker.MatchCheckerListenerFactory.MatchCheckerType;
import net.server.guild.MapleAlliance;
import net.server.world.MapleParty;
import net.server.world.World;
public final class GuildOperationHandler extends AbstractMaplePacketHandler {
private boolean isGuildNameAcceptable(String name) {
@@ -56,36 +61,37 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
//c.announce(MaplePacketCreator.showGuildInfo(mc));
break;
case 0x02:
if (mc.getGuildId() > 0 || mc.getMapId() != 200000301) {
c.getPlayer().dropMessage(1, "You cannot create a new Guild while in one.");
if (mc.getGuildId() > 0) {
mc.dropMessage(1, "You cannot create a new Guild while in one.");
return;
}
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.");
mc.dropMessage(1, "You do not have " + GameConstants.numberWithCommas(ServerConstants.CREATE_GUILD_COST) + " mesos to create a Guild.");
return;
}
String guildName = slea.readMapleAsciiString();
if (!isGuildNameAcceptable(guildName)) {
c.getPlayer().dropMessage(1, "The Guild name you have chosen is not accepted.");
mc.dropMessage(1, "The Guild name you have chosen is not accepted.");
return;
}
int gid = Server.getInstance().createGuild(mc.getId(), guildName);
if (gid == 0) {
c.announce(MaplePacketCreator.genericGuildMessage((byte) 0x1c));
Set<MapleCharacter> eligibleMembers = new HashSet<>(MapleGuild.getEligiblePlayersForGuild(mc));
if (eligibleMembers.size() < ServerConstants.CREATE_GUILD_MIN_PARTNERS) {
mc.dropMessage(1, "The Guild you are trying to create don't meet the minimum criteria of number of founders.");
return;
}
mc.gainMeso(-ServerConstants.CREATE_GUILD_COST, true, false, true);
mc.getMGC().setGuildId(gid);
Server.getInstance().getGuild(mc.getGuildId(), mc.getWorld(), mc); // initialize guild structure
Server.getInstance().changeRank(gid, mc.getId(), 1);
if (!MapleParty.createParty(mc, true)) {
mc.dropMessage(1, "You cannot create a new Guild while in a party.");
return;
}
c.announce(MaplePacketCreator.showGuildInfo(mc));
Set<Integer> eligibleCids = new HashSet<>();
for (MapleCharacter chr : eligibleMembers) {
eligibleCids.add(chr.getId());
}
c.getPlayer().dropMessage(1, "You have successfully created a Guild.");
mc.getGuild().broadcastNameChanged();
mc.getGuild().broadcastEmblemChanged();
c.getWorldServer().getMatchCheckerCoordinator().createMatchConfirmation(MatchCheckerType.GUILD_CREATION, c.getWorld(), mc.getId(), eligibleCids, guildName);
break;
case 0x05:
if (mc.getGuildId() <= 0 || mc.getGuildRank() > 2) {
@@ -101,13 +107,13 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
break;
case 0x06:
if (mc.getGuildId() > 0) {
System.out.println("[hax] " + mc.getName() + " attempted to join a guild when s/he is already in one.");
System.out.println("[Hack] " + mc.getName() + " attempted to join a guild when s/he is already in one.");
return;
}
gid = slea.readInt();
int gid = slea.readInt();
int cid = slea.readInt();
if (cid != mc.getId()) {
System.out.println("[hax] " + mc.getName() + " attempted to join a guild with a different character id.");
System.out.println("[Hack] " + mc.getName() + " attempted to join a guild with a different character id.");
return;
}
@@ -121,7 +127,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
int s = Server.getInstance().addGuildMember(mc.getMGC(), mc);
if (s == 0) {
c.getPlayer().dropMessage(1, "The guild you are trying to join is already full.");
mc.dropMessage(1, "The guild you are trying to join is already full.");
mc.getMGC().setGuildId(0);
return;
}
@@ -139,7 +145,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
cid = slea.readInt();
String name = slea.readMapleAsciiString();
if (cid != mc.getId() || !name.equals(mc.getName()) || mc.getGuildId() <= 0) {
System.out.println("[hax] " + mc.getName() + " tried to quit guild under the name \"" + name + "\" and current guild id of " + mc.getGuildId() + ".");
System.out.println("[Hack] " + mc.getName() + " tried to quit guild under the name \"" + name + "\" and current guild id of " + mc.getGuildId() + ".");
return;
}
@@ -162,7 +168,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
cid = slea.readInt();
name = slea.readMapleAsciiString();
if (mc.getGuildRank() > 2 || mc.getGuildId() <= 0) {
System.out.println("[hax] " + mc.getName() + " is trying to expel without rank 1 or 2.");
System.out.println("[Hack] " + mc.getName() + " is trying to expel without rank 1 or 2.");
return;
}
@@ -171,7 +177,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
break;
case 0x0d:
if (mc.getGuildId() <= 0 || mc.getGuildRank() != 1) {
System.out.println("[hax] " + mc.getName() + " tried to change guild rank titles when s/he does not have permission.");
System.out.println("[Hack] " + mc.getName() + " tried to change guild rank titles when s/he does not have permission.");
return;
}
String ranks[] = new String[5];
@@ -185,7 +191,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
cid = slea.readInt();
byte newRank = slea.readByte();
if (mc.getGuildRank() > 2 || (newRank <= 2 && mc.getGuildRank() != 1) || mc.getGuildId() <= 0) {
System.out.println("[hax] " + mc.getName() + " is trying to change rank outside of his/her permissions.");
System.out.println("[Hack] " + mc.getName() + " is trying to change rank outside of his/her permissions.");
return;
}
if (newRank <= 1 || newRank > 5) {
@@ -195,7 +201,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
break;
case 0x0f:
if (mc.getGuildId() <= 0 || mc.getGuildRank() != 1 || mc.getMapId() != 200000301) {
System.out.println("[hax] " + mc.getName() + " tried to change guild emblem without being the guild leader.");
System.out.println("[Hack] " + mc.getName() + " tried to change guild emblem without being the guild leader.");
return;
}
if (mc.getMeso() < ServerConstants.CHANGE_EMBLEM_COST) {
@@ -219,7 +225,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
break;
case 0x10:
if (mc.getGuildId() <= 0 || mc.getGuildRank() > 2) {
if(mc.getGuildId() <= 0) System.out.println("[hax] " + mc.getName() + " tried to change guild notice while not in a guild.");
if(mc.getGuildId() <= 0) System.out.println("[Hack] " + mc.getName() + " tried to change guild notice while not in a guild.");
return;
}
String notice = slea.readMapleAsciiString();
@@ -227,6 +233,32 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
return;
}
Server.getInstance().setGuildNotice(mc.getGuildId(), notice);
break;
case 0x1E:
slea.readInt();
World wserv = c.getWorldServer();
if (mc.getParty() != null) {
wserv.getMatchCheckerCoordinator().dismissMatchConfirmation(mc.getId());
return;
}
int leaderid = wserv.getMatchCheckerCoordinator().getMatchConfirmationLeaderid(mc.getId());
if (leaderid != -1) {
boolean result = slea.readByte() != 0;
if (result) {
MapleCharacter leader = wserv.getPlayerStorage().getCharacterById(leaderid);
if (leader != null) {
int partyid = leader.getPartyId();
if (partyid != -1) {
MapleParty.joinParty(mc, partyid, true);
}
}
}
wserv.getMatchCheckerCoordinator().answerMatchConfirmation(mc.getId(), result);
}
break;
default:
System.out.println("Unhandled GUILD_OPERATION packet: \n" + slea.toString());
@@ -37,91 +37,92 @@ import tools.data.input.SeekableLittleEndianAccessor;
public final class MessengerHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
c.tryacquireClient();
try {
String input;
byte mode = slea.readByte();
MapleCharacter player = c.getPlayer();
World world = c.getWorldServer();
MapleMessenger messenger = player.getMessenger();
switch (mode) {
case 0x00:
int messengerid = slea.readInt();
if (messenger == null) {
if (messengerid == 0) {
MapleInviteCoordinator.removeInvite(InviteType.MESSENGER, player.getId());
MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, 0);
messenger = world.createMessenger(messengerplayer);
player.setMessenger(messenger);
player.setMessengerPosition(0);
if (c.tryacquireClient()) {
try {
String input;
byte mode = slea.readByte();
MapleCharacter player = c.getPlayer();
World world = c.getWorldServer();
MapleMessenger messenger = player.getMessenger();
switch (mode) {
case 0x00:
int messengerid = slea.readInt();
if (messenger == null) {
if (messengerid == 0) {
MapleInviteCoordinator.removeInvite(InviteType.MESSENGER, player.getId());
MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, 0);
messenger = world.createMessenger(messengerplayer);
player.setMessenger(messenger);
player.setMessengerPosition(0);
} else {
messenger = world.getMessenger(messengerid);
if (messenger != null) {
Pair<InviteResult, MapleCharacter> inviteRes = MapleInviteCoordinator.answerInvite(InviteType.MESSENGER, player.getId(), messengerid, true);
InviteResult res = inviteRes.getLeft();
if (res == InviteResult.ACCEPTED) {
int position = messenger.getLowestPosition();
MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, position);
if (messenger.getMembers().size() < 3) {
player.setMessenger(messenger);
player.setMessengerPosition(position);
world.joinMessenger(messenger.getId(), messengerplayer, player.getName(), messengerplayer.getChannel());
}
} else {
player.message("Could not verify your Maple Messenger accept since the invitation rescinded.");
}
}
}
} else {
messenger = world.getMessenger(messengerid);
if (messenger != null) {
Pair<InviteResult, MapleCharacter> inviteRes = MapleInviteCoordinator.answerInvite(InviteType.MESSENGER, player.getId(), messengerid, true);
InviteResult res = inviteRes.getLeft();
if (res == InviteResult.ACCEPTED) {
int position = messenger.getLowestPosition();
MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, position);
if (messenger.getMembers().size() < 3) {
player.setMessenger(messenger);
player.setMessengerPosition(position);
world.joinMessenger(messenger.getId(), messengerplayer, player.getName(), messengerplayer.getChannel());
MapleInviteCoordinator.answerInvite(InviteType.MESSENGER, player.getId(), messengerid, false);
}
break;
case 0x02:
player.closePlayerMessenger();
break;
case 0x03:
if (messenger == null) {
c.announce(MaplePacketCreator.messengerChat(player.getName() + " : This Maple Messenger is currently unavailable. Please quit this chat."));
} else if (messenger.getMembers().size() < 3) {
input = slea.readMapleAsciiString();
MapleCharacter target = c.getChannelServer().getPlayerStorage().getCharacterByName(input);
if (target != null) {
if (target.getMessenger() == null) {
if (MapleInviteCoordinator.createInvite(InviteType.MESSENGER, c.getPlayer(), messenger.getId(), target.getId())) {
target.getClient().announce(MaplePacketCreator.messengerInvite(c.getPlayer().getName(), messenger.getId()));
c.announce(MaplePacketCreator.messengerNote(input, 4, 1));
} else {
c.announce(MaplePacketCreator.messengerChat(player.getName() + " : " + input + " is already managing a Maple Messenger invitation"));
}
} else {
player.message("Could not verify your Maple Messenger accept since the invitation rescinded.");
}
}
}
} else {
MapleInviteCoordinator.answerInvite(InviteType.MESSENGER, player.getId(), messengerid, false);
}
break;
case 0x02:
player.closePlayerMessenger();
break;
case 0x03:
if (messenger == null) {
c.announce(MaplePacketCreator.messengerChat(player.getName() + " : This Maple Messenger is currently unavailable. Please quit this chat."));
} else if (messenger.getMembers().size() < 3) {
input = slea.readMapleAsciiString();
MapleCharacter target = c.getChannelServer().getPlayerStorage().getCharacterByName(input);
if (target != null) {
if (target.getMessenger() == null) {
if (MapleInviteCoordinator.createInvite(InviteType.MESSENGER, c.getPlayer(), messenger.getId(), target.getId())) {
target.getClient().announce(MaplePacketCreator.messengerInvite(c.getPlayer().getName(), messenger.getId()));
c.announce(MaplePacketCreator.messengerNote(input, 4, 1));
} else {
c.announce(MaplePacketCreator.messengerChat(player.getName() + " : " + input + " is already managing a Maple Messenger invitation"));
c.announce(MaplePacketCreator.messengerChat(player.getName() + " : " + input + " is already using Maple Messenger"));
}
} else {
c.announce(MaplePacketCreator.messengerChat(player.getName() + " : " + input + " is already using Maple Messenger"));
if (world.find(input) > -1) {
world.messengerInvite(c.getPlayer().getName(), messenger.getId(), input, c.getChannel());
} else {
c.announce(MaplePacketCreator.messengerNote(input, 4, 0));
}
}
} else {
if (world.find(input) > -1) {
world.messengerInvite(c.getPlayer().getName(), messenger.getId(), input, c.getChannel());
} else {
c.announce(MaplePacketCreator.messengerNote(input, 4, 0));
}
c.announce(MaplePacketCreator.messengerChat(player.getName() + " : You cannot have more than 3 people in the Maple Messenger"));
}
} else {
c.announce(MaplePacketCreator.messengerChat(player.getName() + " : You cannot have more than 3 people in the Maple Messenger"));
}
break;
case 0x05:
String targeted = slea.readMapleAsciiString();
world.declineChat(targeted, player);
break;
case 0x06:
if (messenger != null) {
MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, player.getMessengerPosition());
input = slea.readMapleAsciiString();
world.messengerChat(messenger, input, messengerplayer.getName());
}
break;
break;
case 0x05:
String targeted = slea.readMapleAsciiString();
world.declineChat(targeted, player);
break;
case 0x06:
if (messenger != null) {
MapleMessengerCharacter messengerplayer = new MapleMessengerCharacter(player, player.getMessengerPosition());
input = slea.readMapleAsciiString();
world.messengerChat(messenger, input, messengerplayer.getName());
}
break;
}
} finally {
c.releaseClient();
}
} finally {
c.releaseClient();
}
}
}
@@ -47,120 +47,117 @@ public final class MonsterCarnivalHandler extends AbstractMaplePacketHandler {
@Override
public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
c.tryacquireClient();
try {
if (c.tryacquireClient()) {
try {
int tab = slea.readByte();
int num = slea.readByte();
int neededCP = 0;
if (tab == 0) {
final List<Pair<Integer, Integer>> mobs = c.getPlayer().getMap().getMobsToSpawn();
if (num >= mobs.size() || c.getPlayer().getCP() < mobs.get(num).right) {
c.announce(MaplePacketCreator.CPQMessage((byte) 1));
c.announce(MaplePacketCreator.enableActions());
return;
}
final MapleMonster mob = MapleLifeFactory.getMonster(mobs.get(num).left);
MonsterCarnival mcpq = c.getPlayer().getMonsterCarnival();
if (mcpq != null) {
if (!mcpq.canSummonR() && c.getPlayer().getTeam() == 0 || !mcpq.canSummonB() && c.getPlayer().getTeam() == 1) {
c.announce(MaplePacketCreator.CPQMessage((byte) 2));
try {
int tab = slea.readByte();
int num = slea.readByte();
int neededCP = 0;
if (tab == 0) {
final List<Pair<Integer, Integer>> mobs = c.getPlayer().getMap().getMobsToSpawn();
if (num >= mobs.size() || c.getPlayer().getCP() < mobs.get(num).right) {
c.announce(MaplePacketCreator.CPQMessage((byte) 1));
c.announce(MaplePacketCreator.enableActions());
return;
}
if (c.getPlayer().getTeam() == 0) {
mcpq.summonR();
} else {
mcpq.summonB();
}
Point spawnPos = c.getPlayer().getMap().getRandomSP(c.getPlayer().getTeam());
mob.setPosition(spawnPos);
c.getPlayer().getMap().addMonsterSpawn(mob, 1, c.getPlayer().getTeam());
c.getPlayer().getMap().addAllMonsterSpawn(mob, 1, c.getPlayer().getTeam());
c.announce(MaplePacketCreator.enableActions());
}
neededCP = mobs.get(num).right;
} else if (tab == 1) { //debuffs
final List<Integer> skillid = c.getPlayer().getMap().getSkillIds();
if (num >= skillid.size()) {
c.getPlayer().dropMessage(5, "Ocorreu um erro.");
c.announce(MaplePacketCreator.enableActions());
return;
}
final MCSkill skill = MapleCarnivalFactory.getInstance().getSkill(skillid.get(num)); //ugh wtf
if (skill == null || c.getPlayer().getCP() < skill.cpLoss) {
c.announce(MaplePacketCreator.CPQMessage((byte) 1));
c.announce(MaplePacketCreator.enableActions());
return;
}
final MapleDisease dis = skill.getDisease();
MapleParty enemies = c.getPlayer().getParty().getEnemy();
if (skill.targetsAll) {
int chanceAcerto = 0;
if (dis.getDisease() == 121 || dis.getDisease() == 122 || dis.getDisease() == 125 || dis.getDisease() == 126) {
chanceAcerto = (int) (Math.random() * 100);
}
if (chanceAcerto <= 80) {
for (MaplePartyCharacter chrS : enemies.getPartyMembers()) {
if (dis == null) {
chrS.getPlayer().dispel();
} else {
chrS.getPlayer().giveDebuff(dis, skill.getSkill());
}
if (!skill.targetsAll) {
break;
}
final MapleMonster mob = MapleLifeFactory.getMonster(mobs.get(num).left);
MonsterCarnival mcpq = c.getPlayer().getMonsterCarnival();
if (mcpq != null) {
if (!mcpq.canSummonR() && c.getPlayer().getTeam() == 0 || !mcpq.canSummonB() && c.getPlayer().getTeam() == 1) {
c.announce(MaplePacketCreator.CPQMessage((byte) 2));
c.announce(MaplePacketCreator.enableActions());
return;
}
}
} else {
int amount = enemies.getMembers().size() - 1;
int randd = (int) Math.floor(Math.random() * amount);
MapleCharacter chrApp = c.getChannelServer().getPlayerStorage().getCharacterById(enemies.getMemberByPos(randd).getId());
if (chrApp != null && chrApp.getMap().isCPQMap()) {
if (dis == null) {
chrApp.dispel();
if (c.getPlayer().getTeam() == 0) {
mcpq.summonR();
} else {
chrApp.giveDebuff(dis, skill.getSkill());
mcpq.summonB();
}
Point spawnPos = c.getPlayer().getMap().getRandomSP(c.getPlayer().getTeam());
mob.setPosition(spawnPos);
c.getPlayer().getMap().addMonsterSpawn(mob, 1, c.getPlayer().getTeam());
c.getPlayer().getMap().addAllMonsterSpawn(mob, 1, c.getPlayer().getTeam());
c.announce(MaplePacketCreator.enableActions());
}
neededCP = mobs.get(num).right;
} else if (tab == 1) { //debuffs
final List<Integer> skillid = c.getPlayer().getMap().getSkillIds();
if (num >= skillid.size()) {
c.getPlayer().dropMessage(5, "An unexpected error has occurred.");
c.announce(MaplePacketCreator.enableActions());
return;
}
final MCSkill skill = MapleCarnivalFactory.getInstance().getSkill(skillid.get(num)); //ugh wtf
if (skill == null || c.getPlayer().getCP() < skill.cpLoss) {
c.announce(MaplePacketCreator.CPQMessage((byte) 1));
c.announce(MaplePacketCreator.enableActions());
return;
}
final MapleDisease dis = skill.getDisease();
MapleParty enemies = c.getPlayer().getParty().getEnemy();
if (skill.targetsAll) {
int chanceAcerto = 0;
if (dis.getDisease() == 121 || dis.getDisease() == 122 || dis.getDisease() == 125 || dis.getDisease() == 126) {
chanceAcerto = (int) (Math.random() * 100);
}
if (chanceAcerto <= 80) {
for (MaplePartyCharacter chrS : enemies.getPartyMembers()) {
if (dis == null) {
chrS.getPlayer().dispel();
} else {
chrS.getPlayer().giveDebuff(dis, skill.getSkill());
}
}
}
} else {
int amount = enemies.getMembers().size() - 1;
int randd = (int) Math.floor(Math.random() * amount);
MapleCharacter chrApp = c.getPlayer().getMap().getCharacterById(enemies.getMemberByPos(randd).getId());
if (chrApp != null && chrApp.getMap().isCPQMap()) {
if (dis == null) {
chrApp.dispel();
} else {
chrApp.giveDebuff(dis, skill.getSkill());
}
}
}
}
neededCP = skill.cpLoss;
c.announce(MaplePacketCreator.enableActions());
} else if (tab == 2) { //protectors
final MCSkill skill = MapleCarnivalFactory.getInstance().getGuardian(num);
if (skill == null || c.getPlayer().getCP() < skill.cpLoss) {
c.announce(MaplePacketCreator.CPQMessage((byte) 1));
c.announce(MaplePacketCreator.enableActions());
return;
}
int success = c.getPlayer().getMap().spawnGuardian(c.getPlayer().getTeam(), num);
if (success == -1 || success == 0 || success == 2) {
if (success == -1) {
c.announce(MaplePacketCreator.CPQMessage((byte) 3));
} else if (success == 0) {
c.announce(MaplePacketCreator.CPQMessage((byte) 4));
} else if (success == 2) {
c.announce(MaplePacketCreator.CPQMessage((byte) 3));
}
c.announce(MaplePacketCreator.enableActions());
return;
} else {
neededCP = skill.cpLoss;
c.announce(MaplePacketCreator.enableActions());
} else if (tab == 2) { //protectors
final MCSkill skill = MapleCarnivalFactory.getInstance().getGuardian(num);
if (skill == null || c.getPlayer().getCP() < skill.cpLoss) {
c.announce(MaplePacketCreator.CPQMessage((byte) 1));
c.announce(MaplePacketCreator.enableActions());
return;
}
int success = c.getPlayer().getMap().spawnGuardian(c.getPlayer().getTeam(), num);
if (success == -1 || success == 0 || success == 2) {
if (success == -1) {
c.announce(MaplePacketCreator.CPQMessage((byte) 3));
} else if (success == 0) {
c.announce(MaplePacketCreator.CPQMessage((byte) 4));
} else if (success == 2) {
c.announce(MaplePacketCreator.CPQMessage((byte) 3));
}
c.announce(MaplePacketCreator.enableActions());
return;
} else {
neededCP = skill.cpLoss;
}
}
c.getPlayer().gainCP(-neededCP);
c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.playerSummoned(c.getPlayer().getName(), tab, num));
}catch (Exception e) {
e.printStackTrace();
}
c.getPlayer().gainCP(-neededCP);
c.getPlayer().getMap().broadcastMessage(MaplePacketCreator.playerSummoned(c.getPlayer().getName(), tab, num));
}catch (Exception e) {
e.printStackTrace();
} finally {
c.releaseClient();
}
} finally {
c.releaseClient();
}
}
}
@@ -100,7 +100,7 @@ public final class NewYearCardHandler extends AbstractMaplePacketHandler {
NewYearCardRecord.updateNewYearCard(newyear);
player.getClient().getAbstractPlayerInteraction().gainItem(4301000, (short)1);
if(!newyear.getMessage().isEmpty()) player.dropMessage(6, "[NEW YEAR] " + newyear.getSenderName() + ": " + newyear.getMessage());
if(!newyear.getMessage().isEmpty()) player.dropMessage(6, "[New Year] " + newyear.getSenderName() + ": " + newyear.getMessage());
player.addNewYearRecord(newyear);
player.announce(MaplePacketCreator.onNewYearCardRes(player, newyear, 6, 0)); // successfully rcvd
@@ -110,17 +110,17 @@ public final class NewYearCardHandler extends AbstractMaplePacketHandler {
MapleCharacter sender = c.getWorldServer().getPlayerStorage().getCharacterById(newyear.getSenderId());
if(sender != null && sender.isLoggedinWorld()) {
sender.getMap().broadcastMessage(MaplePacketCreator.onNewYearCardRes(sender, newyear, 0xD, 0));
sender.dropMessage(6, "[NEW YEAR] Your addressee successfully received the New Year card.");
sender.dropMessage(6, "[New Year] Your addressee successfully received the New Year card.");
}
} else {
player.announce(MaplePacketCreator.onNewYearCardRes(player, -1, 5, 0x10)); // inventory full
}
} else {
player.dropMessage(6, "[NEW YEAR] The sender of the New Year card already dropped it. Nothing to receive.");
player.dropMessage(6, "[New Year] The sender of the New Year card already dropped it. Nothing to receive.");
}
} else {
if(newyear == null) {
player.dropMessage(6, "[NEW YEAR] The sender of the New Year card already dropped it. Nothing to receive.");
player.dropMessage(6, "[New Year] The sender of the New Year card already dropped it. Nothing to receive.");
}
}
}
@@ -34,72 +34,33 @@ import constants.ServerConstants;
import net.server.coordinator.MapleInviteCoordinator;
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
import net.server.coordinator.MapleInviteCoordinator.InviteType;
import net.server.coordinator.MapleMatchCheckerCoordinator;
import net.server.coordinator.matchchecker.MatchCheckerListenerFactory.MatchCheckerType;
import scripting.event.EventInstanceManager;
import server.maps.MapleMap;
import tools.Pair;
import java.util.List;
import server.partyquest.MonsterCarnival;
public final class PartyOperationHandler extends AbstractMaplePacketHandler {
public static void leaveParty(MapleParty party, MaplePartyCharacter partyplayer, MapleClient c) {
World world = c.getWorldServer();
MapleCharacter player = c.getPlayer();
if (party != null && partyplayer != null) {
if (partyplayer.getId() == party.getLeaderId()) {
c.getWorldServer().removeMapPartyMembers(party.getId());
world.updateParty(party.getId(), PartyOperation.DISBAND, partyplayer);
if (player.getEventInstance() != null) {
player.getEventInstance().disbandParty();
}
} else {
player.getMap().removePartyMember(player);
world.updateParty(party.getId(), PartyOperation.LEAVE, partyplayer);
if (player.getEventInstance() != null) {
player.getEventInstance().leftParty(player);
}
}
player.setParty(null);
}
}
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
int operation = slea.readByte();
MapleCharacter player = c.getPlayer();
World world = c.getWorldServer();
MapleParty party = player.getParty();
MaplePartyCharacter partyplayer = player.getMPC();
switch (operation) {
case 1: { // create
if(player.getLevel() < 10 && !ServerConstants.USE_PARTY_FOR_STARTERS) {
c.announce(MaplePacketCreator.partyStatusMessage(10));
return;
}
if (party == null) {
partyplayer = new MaplePartyCharacter(player);
party = world.createParty(partyplayer);
player.setParty(party);
player.setMPC(partyplayer);
player.getMap().addPartyMember(player);
player.silentPartyUpdate();
player.partyOperationUpdate(party, null);
c.announce(MaplePacketCreator.partyCreated(party, partyplayer.getId()));
} else {
c.announce(MaplePacketCreator.serverNotice(5, "You can't create a party as you are already in one."));
}
MapleParty.createParty(player, false);
break;
}
case 2: { // leave/disband
if (party != null) {
List<MapleCharacter> partymembers = player.getPartyMembers();
leaveParty(party, partyplayer, c);
MapleParty.leaveParty(party, c);
player.partyOperationUpdate(party, partymembers);
}
break;
@@ -110,27 +71,7 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler {
Pair<InviteResult, MapleCharacter> inviteRes = MapleInviteCoordinator.answerInvite(InviteType.PARTY, player.getId(), partyid, true);
InviteResult res = inviteRes.getLeft();
if (res == InviteResult.ACCEPTED) {
if (party == null) {
party = world.getParty(partyid);
if (party != null) {
if (party.getMembers().size() < 6) {
partyplayer = new MaplePartyCharacter(player);
player.getMap().addPartyMember(player);
world.updateParty(party.getId(), PartyOperation.JOIN, partyplayer);
player.receivePartyMemberHP();
player.updatePartyMemberHP();
player.partyOperationUpdate(party, null);
} else {
c.announce(MaplePacketCreator.partyStatusMessage(17));
}
} else {
c.announce(MaplePacketCreator.serverNotice(5, "The person you have invited to the party is already in one."));
}
} else {
c.announce(MaplePacketCreator.serverNotice(5, "You can't join the party as you are already in one."));
}
MapleParty.joinParty(player, partyid, false);
} else {
c.announce(MaplePacketCreator.serverNotice(5, "You couldn't join the party due to an expired invitation request."));
}
@@ -151,19 +92,11 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler {
if (invited.getParty() == null) {
if (party == null) {
if(player.getLevel() < 10 && !ServerConstants.USE_PARTY_FOR_STARTERS) {
c.announce(MaplePacketCreator.partyStatusMessage(10));
if (!MapleParty.createParty(player, false)) {
return;
}
partyplayer = new MaplePartyCharacter(player);
party = world.createParty(partyplayer);
player.setParty(party);
player.setMPC(partyplayer);
player.getMap().addPartyMember(player);
player.partyOperationUpdate(party, null);
c.announce(MaplePacketCreator.partyCreated(party, partyplayer.getId()));
party = player.getParty();
}
if (party.getMembers().size() < 6) {
if (MapleInviteCoordinator.createInvite(InviteType.PARTY, player, party.getId(), invited.getId())) {
@@ -184,30 +117,7 @@ public final class PartyOperationHandler extends AbstractMaplePacketHandler {
}
case 5: { // expel
int cid = slea.readInt();
if (partyplayer.equals(party.getLeader())) {
MaplePartyCharacter expelled = party.getMemberById(cid);
if (expelled != null) {
MapleCharacter emc = expelled.getPlayer();
if(emc != null) {
List<MapleCharacter> partyMembers = emc.getPartyMembers();
MapleMap map = emc.getMap();
if(map != null) map.removePartyMember(emc);
EventInstanceManager eim = emc.getEventInstance();
if(eim != null) {
eim.leftParty(emc);
}
emc.setParty(null);
world.updateParty(party.getId(), PartyOperation.EXPEL, expelled);
emc.partyOperationUpdate(party, partyMembers);
} else {
world.updateParty(party.getId(), PartyOperation.EXPEL, expelled);
}
}
}
MapleParty.expelFromParty(party, c, cid);
break;
}
case 6: { // change leader
@@ -484,7 +484,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
byte targetSlot = slea.readByte();
if (targetSlot < 1 || targetSlot > 9) {
System.out.println("[h4x] " + chr.getName() + " Trying to dupe on trade slot.");
System.out.println("[Hack] " + chr.getName() + " Trying to dupe on trade slot.");
c.announce(MaplePacketCreator.enableActions());
return;
}
@@ -59,7 +59,6 @@ import client.inventory.MapleInventoryType;
import client.inventory.MaplePet;
import constants.GameConstants;
import constants.ServerConstants;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
@@ -128,7 +127,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
IoSession session = c.getSession();
String remoteHwid;
if (player == null) {
if (!server.validateCharacteridInTransition((InetSocketAddress) session.getRemoteAddress(), cid)) {
if (!server.validateCharacteridInTransition(session, cid)) {
c.disconnect(true, false);
return;
}
@@ -412,10 +412,10 @@ public final class RingActionHandler extends AbstractMaplePacketHandler {
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!");
guestChr.dropMessage(6, "[Wedding] You've been invited to " + groom + " and " + bride + "'s Wedding!");
} else {
if(guestChr != null && guestChr.isLoggedinWorld()) {
guestChr.dropMessage(6, "[WEDDING] You've been invited to " + groom + " and " + bride + "'s Wedding! Receive your invitation from Duey!");
guestChr.dropMessage(6, "[Wedding] You've been invited to " + groom + " and " + bride + "'s Wedding! Receive your invitation from Duey!");
} else {
c.getPlayer().sendNote(name, "You've been invited to " + groom + " and " + bride + "'s Wedding! Receive your invitation from Duey!", (byte) 0);
}
@@ -33,122 +33,123 @@ public final class WeddingHandler extends AbstractMaplePacketHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
c.tryacquireClient();
try {
MapleCharacter chr = c.getPlayer();
final byte mode = slea.readByte();
if (mode == 6) { //additem
short slot = slea.readShort();
int itemid = slea.readInt();
short quantity = slea.readShort();
if (c.tryacquireClient()) {
try {
MapleCharacter chr = c.getPlayer();
final byte mode = slea.readByte();
MapleMarriage marriage = c.getPlayer().getMarriageInstance();
if (marriage != null) {
try {
boolean groomWishlist = marriage.giftItemToSpouse(chr.getId());
String groomWishlistProp = "giftedItem" + (groomWishlist ? "G" : "B") + chr.getId();
int giftCount = marriage.getIntProperty(groomWishlistProp);
if (giftCount < ServerConstants.WEDDING_GIFT_LIMIT) {
int cid = marriage.getIntProperty(groomWishlist ? "groomId" : "brideId");
if (chr.getId() != cid) { // cannot gift yourself
MapleCharacter spouse = marriage.getPlayerById(cid);
if (spouse != null) {
MapleInventoryType type = ItemConstants.getInventoryType(itemid);
MapleInventory chrInv = chr.getInventory(type);
if (mode == 6) { //additem
short slot = slea.readShort();
int itemid = slea.readInt();
short quantity = slea.readShort();
chrInv.lockInventory();
try {
Item item = chrInv.getItem((byte) slot);
if (item != null) {
if (!item.isUntradeable()) {
if (itemid == item.getItemId() && quantity <= item.getQuantity()) {
Item newItem = item.copy();
MapleMarriage marriage = c.getPlayer().getMarriageInstance();
if (marriage != null) {
try {
boolean groomWishlist = marriage.giftItemToSpouse(chr.getId());
String groomWishlistProp = "giftedItem" + (groomWishlist ? "G" : "B") + chr.getId();
marriage.addGiftItem(groomWishlist, newItem);
MapleInventoryManipulator.removeFromSlot(c, type, slot, quantity, false, false);
int giftCount = marriage.getIntProperty(groomWishlistProp);
if (giftCount < ServerConstants.WEDDING_GIFT_LIMIT) {
int cid = marriage.getIntProperty(groomWishlist ? "groomId" : "brideId");
if (chr.getId() != cid) { // cannot gift yourself
MapleCharacter spouse = marriage.getPlayerById(cid);
if (spouse != null) {
MapleInventoryType type = ItemConstants.getInventoryType(itemid);
MapleInventory chrInv = chr.getInventory(type);
if (ServerConstants.USE_ENFORCE_MERCHANT_SAVE) chr.saveCharToDB(false);
marriage.saveGiftItemsToDb(c, groomWishlist, cid);
chrInv.lockInventory();
try {
Item item = chrInv.getItem((byte) slot);
if (item != null) {
if (!item.isUntradeable()) {
if (itemid == item.getItemId() && quantity <= item.getQuantity()) {
Item newItem = item.copy();
MapleKarmaManipulator.toggleKarmaFlagToUntradeable(newItem);
marriage.setIntProperty(groomWishlistProp, giftCount + 1);
marriage.addGiftItem(groomWishlist, newItem);
MapleInventoryManipulator.removeFromSlot(c, type, slot, quantity, false, false);
c.announce(Wedding.OnWeddingGiftResult((byte) 0xB, marriage.getWishlistItems(groomWishlist), Collections.singletonList(newItem)));
if (ServerConstants.USE_ENFORCE_MERCHANT_SAVE) chr.saveCharToDB(false);
marriage.saveGiftItemsToDb(c, groomWishlist, cid);
MapleKarmaManipulator.toggleKarmaFlagToUntradeable(newItem);
marriage.setIntProperty(groomWishlistProp, giftCount + 1);
c.announce(Wedding.OnWeddingGiftResult((byte) 0xB, marriage.getWishlistItems(groomWishlist), Collections.singletonList(newItem)));
}
} else {
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, marriage.getWishlistItems(groomWishlist), null));
}
} else {
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, marriage.getWishlistItems(groomWishlist), null));
}
} finally {
chrInv.unlockInventory();
}
} finally {
chrInv.unlockInventory();
} else {
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, marriage.getWishlistItems(groomWishlist), null));
}
} else {
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, marriage.getWishlistItems(groomWishlist), null));
}
} else {
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, marriage.getWishlistItems(groomWishlist), null));
c.announce(Wedding.OnWeddingGiftResult((byte) 0xC, marriage.getWishlistItems(groomWishlist), null));
}
} else {
c.announce(Wedding.OnWeddingGiftResult((byte) 0xC, marriage.getWishlistItems(groomWishlist), null));
}
} catch (NumberFormatException nfe) {}
} else {
c.announce(MaplePacketCreator.enableActions());
}
} else if (mode == 7) { // take items
slea.readByte(); // invType
int itemPos = slea.readByte();
MapleMarriage marriage = chr.getMarriageInstance();
if (marriage != null) {
Boolean groomWishlist = marriage.isMarriageGroom(chr);
if (groomWishlist != null) {
Item item = marriage.getGiftItem(c, groomWishlist, itemPos);
if (item != null) {
if (MapleInventory.checkSpot(chr, item)) {
marriage.removeGiftItem(groomWishlist, item);
marriage.saveGiftItemsToDb(c, groomWishlist, chr.getId());
MapleInventoryManipulator.addFromDrop(c, item, true);
} catch (NumberFormatException nfe) {}
} else {
c.announce(MaplePacketCreator.enableActions());
}
} else if (mode == 7) { // take items
slea.readByte(); // invType
int itemPos = slea.readByte();
c.announce(Wedding.OnWeddingGiftResult((byte) 0xF, marriage.getWishlistItems(groomWishlist), marriage.getGiftItems(c, groomWishlist)));
MapleMarriage marriage = chr.getMarriageInstance();
if (marriage != null) {
Boolean groomWishlist = marriage.isMarriageGroom(chr);
if (groomWishlist != null) {
Item item = marriage.getGiftItem(c, groomWishlist, itemPos);
if (item != null) {
if (MapleInventory.checkSpot(chr, item)) {
marriage.removeGiftItem(groomWishlist, item);
marriage.saveGiftItemsToDb(c, groomWishlist, chr.getId());
MapleInventoryManipulator.addFromDrop(c, item, true);
c.announce(Wedding.OnWeddingGiftResult((byte) 0xF, marriage.getWishlistItems(groomWishlist), marriage.getGiftItems(c, groomWishlist)));
} else {
c.getPlayer().dropMessage(1, "Free a slot on your inventory before collecting this item.");
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, marriage.getWishlistItems(groomWishlist), marriage.getGiftItems(c, groomWishlist)));
}
} else {
c.getPlayer().dropMessage(1, "Free a slot on your inventory before collecting this item.");
c.getPlayer().dropMessage(1, "You have already collected this item.");
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, marriage.getWishlistItems(groomWishlist), marriage.getGiftItems(c, groomWishlist)));
}
} else {
c.getPlayer().dropMessage(1, "You have already collected this item.");
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, marriage.getWishlistItems(groomWishlist), marriage.getGiftItems(c, groomWishlist)));
}
}
} else {
List<Item> items = c.getAbstractPlayerInteraction().getUnclaimedMarriageGifts();
try {
Item item = items.get(itemPos);
if (MapleInventory.checkSpot(chr, item)) {
items.remove(itemPos);
MapleMarriage.saveGiftItemsToDb(c, items, chr.getId());
} else {
List<Item> items = c.getAbstractPlayerInteraction().getUnclaimedMarriageGifts();
try {
Item item = items.get(itemPos);
if (MapleInventory.checkSpot(chr, item)) {
items.remove(itemPos);
MapleMarriage.saveGiftItemsToDb(c, items, chr.getId());
MapleInventoryManipulator.addFromDrop(c, item, true);
c.announce(Wedding.OnWeddingGiftResult((byte) 0xF, Collections.singletonList(""), items));
} else {
c.getPlayer().dropMessage(1, "Free a slot on your inventory before collecting this item.");
MapleInventoryManipulator.addFromDrop(c, item, true);
c.announce(Wedding.OnWeddingGiftResult((byte) 0xF, Collections.singletonList(""), items));
} else {
c.getPlayer().dropMessage(1, "Free a slot on your inventory before collecting this item.");
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, Collections.singletonList(""), items));
}
} catch (Exception e) {
c.getPlayer().dropMessage(1, "You have already collected this item.");
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, Collections.singletonList(""), items));
}
} catch (Exception e) {
c.getPlayer().dropMessage(1, "You have already collected this item.");
c.announce(Wedding.OnWeddingGiftResult((byte) 0xE, Collections.singletonList(""), items));
}
} else if (mode == 8) { // out of Wedding Registry
c.announce(MaplePacketCreator.enableActions());
} else {
System.out.println(mode);
}
} else if (mode == 8) { // out of Wedding Registry
c.announce(MaplePacketCreator.enableActions());
} else {
System.out.println(mode);
} finally {
c.releaseClient();
}
} finally {
c.releaseClient();
}
}
}
@@ -0,0 +1,358 @@
/*
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
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.coordinator;
import client.MapleCharacter;
import net.server.PlayerStorage;
import net.server.Server;
import net.server.coordinator.matchchecker.AbstractMatchCheckerListener;
import net.server.coordinator.matchchecker.MatchCheckerListenerFactory.MatchCheckerType;
import net.server.world.World;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Semaphore;
/**
*
* @author Ronan
*/
public class MapleMatchCheckerCoordinator {
private final Map<Integer, MapleMatchCheckingElement> matchEntries = new HashMap<>();
private final Set<Integer> pooledCids = new HashSet<>();
private final Semaphore semaphorePool = new Semaphore(7);
private class MapleMatchCheckingEntry {
private boolean accepted;
private int cid;
private MapleMatchCheckingEntry(int cid) {
this.cid = cid;
this.accepted = false;
}
private boolean setAccept() {
if (!this.accepted) {
this.accepted = true;
return true;
} else {
return false;
}
}
private boolean getAccept() {
return this.accepted;
}
}
private class MapleMatchCheckingElement {
private int leaderCid;
private int world;
private MatchCheckerType matchType;
private AbstractMatchCheckerListener listener;
private Map<Integer, MapleMatchCheckingEntry> confirmingMembers = new HashMap<>();
private int confirmCount;
private String message;
private MapleMatchCheckingElement(MatchCheckerType matchType, int leaderCid, int world, AbstractMatchCheckerListener leaderListener, Set<Integer> matchPlayers, String message) {
this.leaderCid = leaderCid;
this.world = world;
this.listener = leaderListener;
this.confirmCount = 0;
this.message = message;
this.matchType = matchType;
for (Integer cid : matchPlayers) {
MapleMatchCheckingEntry mmcEntry = new MapleMatchCheckingEntry(cid);
confirmingMembers.put(cid, mmcEntry);
}
}
private boolean acceptEntry(int cid) {
MapleMatchCheckingEntry mmcEntry = confirmingMembers.get(cid);
if (mmcEntry != null) {
if (mmcEntry.setAccept()) {
this.confirmCount++;
if (this.confirmCount == this.confirmingMembers.size()) {
return true;
}
}
}
return false;
}
private Set<Integer> getMatchPlayers() {
return confirmingMembers.keySet();
}
private Set<MapleCharacter> getMatchCharacters() {
Set<MapleCharacter> players = new HashSet<>();
World wserv = Server.getInstance().getWorld(world);
if (wserv != null) {
PlayerStorage ps = wserv.getPlayerStorage();
for (Integer cid : getMatchPlayers()) {
MapleCharacter chr = ps.getCharacterById(cid);
if (chr != null) {
players.add(chr);
}
}
}
return players;
}
private void dispatchMatchCreated() {
Set<MapleCharacter> nonLeaderMatchPlayers = getMatchCharacters();
MapleCharacter leader = null;
for (MapleCharacter chr : nonLeaderMatchPlayers) {
if (chr.getId() == leaderCid) {
leader = chr;
break;
}
}
nonLeaderMatchPlayers.remove(leader);
listener.onMatchCreated(leader, nonLeaderMatchPlayers, message);
}
private void dispatchMatchResult(boolean accept) {
if (accept) {
listener.onMatchAccepted(leaderCid, getMatchCharacters(), message);
} else {
listener.onMatchDeclined(leaderCid, getMatchCharacters(), message);
}
}
private void dispatchMatchDismissed() {
listener.onMatchDismissed(leaderCid, getMatchCharacters(), message);
}
}
private void unpoolMatchPlayer(Integer cid) {
unpoolMatchPlayers(Collections.singleton(cid));
}
private void unpoolMatchPlayers(Set<Integer> matchPlayers) {
for (Integer cid : matchPlayers) {
pooledCids.remove(cid);
}
}
private boolean poolMatchPlayer(Integer cid) {
return poolMatchPlayers(Collections.singleton(cid));
}
private boolean poolMatchPlayers(Set<Integer> matchPlayers) {
Set<Integer> pooledPlayers = new HashSet<>();
for (Integer cid : matchPlayers) {
if (!pooledCids.add(cid)) {
unpoolMatchPlayers(pooledPlayers);
return false;
} else {
pooledPlayers.add(cid);
}
}
return true;
}
private boolean isMatchingAvailable(Set<Integer> matchPlayers) {
for (Integer cid : matchPlayers) {
if (matchEntries.containsKey(cid)) {
return false;
}
}
return true;
}
public int getMatchConfirmationLeaderid(int cid) {
MapleMatchCheckingElement mmce = matchEntries.get(cid);
if (mmce != null) {
return mmce.leaderCid;
} else {
return -1;
}
}
public MatchCheckerType getMatchConfirmationType(int cid) {
MapleMatchCheckingElement mmce = matchEntries.get(cid);
if (mmce != null) {
return mmce.matchType;
} else {
return null;
}
}
private void createMatchConfirmationInternal(MatchCheckerType matchType, int world, int leaderCid, AbstractMatchCheckerListener leaderListener, Set<Integer> players, String message) {
MapleMatchCheckingElement mmce = new MapleMatchCheckingElement(matchType, leaderCid, world, leaderListener, players, message);
for (Integer cid : players) {
matchEntries.put(cid, mmce);
}
mmce.dispatchMatchCreated();
if (mmce.acceptEntry(leaderCid)) {
acceptMatchElement(mmce, leaderCid);
}
}
public boolean createMatchConfirmation(MatchCheckerType matchType, int world, int leaderCid, Set<Integer> players, String message) {
try {
semaphorePool.acquire();
try {
if (poolMatchPlayers(players)) {
try {
if (isMatchingAvailable(players)) {
AbstractMatchCheckerListener leaderListener = matchType.getListener();
createMatchConfirmationInternal(matchType, world, leaderCid, leaderListener, players, message);
return true;
}
} finally {
unpoolMatchPlayers(players);
}
}
} finally {
semaphorePool.release();
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
return false;
}
private void disposeMatchElement(MapleMatchCheckingElement mmce) {
Set<Integer> matchPlayers = mmce.getMatchPlayers();
while (!poolMatchPlayers(matchPlayers)) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {}
}
try {
for (Integer cid : matchPlayers) {
matchEntries.remove(cid);
}
} finally {
unpoolMatchPlayers(matchPlayers);
}
}
private void acceptMatchElement(MapleMatchCheckingElement mmce, int cid) {
if (mmce.acceptEntry(cid)) {
unpoolMatchPlayer(cid);
disposeMatchElement(mmce);
mmce.dispatchMatchResult(true);
}
}
private void denyMatchElement(MapleMatchCheckingElement mmce, int cid) {
unpoolMatchPlayer(cid);
disposeMatchElement(mmce);
mmce.dispatchMatchResult(false);
}
private void dismissMatchElement(MapleMatchCheckingElement mmce, int cid) {
unpoolMatchPlayer(cid);
disposeMatchElement(mmce);
mmce.dispatchMatchDismissed();
}
public boolean answerMatchConfirmation(int cid, boolean accept) {
try {
semaphorePool.acquire();
try {
while (matchEntries.containsKey(cid)) {
if (poolMatchPlayer(cid)) {
try {
MapleMatchCheckingElement mmce = matchEntries.get(cid);
if (mmce != null) {
if (accept) {
acceptMatchElement(mmce, cid);
} else {
denyMatchElement(mmce, cid);
}
return true;
}
} finally {
unpoolMatchPlayer(cid);
}
}
}
} finally {
semaphorePool.release();
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
return false;
}
public boolean dismissMatchConfirmation(int cid) {
try {
semaphorePool.acquire();
try {
while (matchEntries.containsKey(cid)) {
if (poolMatchPlayer(cid)) {
try {
MapleMatchCheckingElement mmce = matchEntries.get(cid);
if (mmce != null) {
dismissMatchElement(mmce, cid);
return true;
}
} finally {
unpoolMatchPlayer(cid);
}
}
}
} finally {
semaphorePool.release();
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
return false;
}
}
@@ -19,6 +19,7 @@
*/
package net.server.coordinator;
import client.MapleCharacter;
import client.MapleClient;
import constants.ServerConstants;
@@ -28,7 +29,6 @@ import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
import org.apache.mina.core.session.IoSession;
import tools.DatabaseConnection;
import java.net.InetSocketAddress;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -220,8 +220,8 @@ public class MapleSessionCoordinator {
return poolLock.get(Math.abs(remoteHost.hashCode()) % 100);
}
private static String getRemoteIp(IoSession session) {
return ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress();
public static String getSessionRemoteAddress(IoSession session) {
return (String) session.getAttribute(MapleClient.CLIENT_REMOTE_ADDRESS);
}
private static MapleClient getSessionClient(IoSession session) {
@@ -245,7 +245,7 @@ public class MapleSessionCoordinator {
public boolean canStartLoginSession(IoSession session) {
if (!ServerConstants.DETERRED_MULTICLIENT) return true;
String remoteHost = getRemoteIp(session);
String remoteHost = getSessionRemoteAddress(session);
Lock lock = getCoodinatorLock(remoteHost);
try {
@@ -305,7 +305,7 @@ public class MapleSessionCoordinator {
}
public void closeLoginSession(IoSession session) {
String remoteIp = getRemoteIp(session);
String remoteIp = getSessionRemoteAddress(session);
Set<IoSession> lrh = loginRemoteHosts.get(remoteIp);
if (lrh != null) {
lrh.remove(session);
@@ -336,7 +336,7 @@ public class MapleSessionCoordinator {
return AntiMulticlientResult.SUCCESS;
}
String remoteHost = getRemoteIp(session);
String remoteHost = getSessionRemoteAddress(session);
Lock lock = getCoodinatorLock(remoteHost);
try {
@@ -402,7 +402,7 @@ public class MapleSessionCoordinator {
}
public AntiMulticlientResult attemptGameSession(IoSession session, int accountId, String remoteHwid) {
String remoteHost = getRemoteIp(session);
String remoteHost = getSessionRemoteAddress(session);
if (!ServerConstants.DETERRED_MULTICLIENT) {
associateRemoteHostHwid(remoteHost, remoteHwid);
return AntiMulticlientResult.SUCCESS;
@@ -472,14 +472,47 @@ public class MapleSessionCoordinator {
}
}
private static MapleClient fetchInTransitionSessionClient(IoSession session) {
String remoteHwid = MapleSessionCoordinator.getInstance().getGameSessionHwid(session);
if (remoteHwid != null) { // maybe this session was currently in-transition?
int hwidLen = remoteHwid.length();
if (hwidLen <= 8) {
session.setAttribute(MapleClient.CLIENT_NIBBLEHWID, remoteHwid);
} else {
session.setAttribute(MapleClient.CLIENT_HWID, remoteHwid);
session.setAttribute(MapleClient.CLIENT_NIBBLEHWID, remoteHwid.substring(hwidLen - 8, hwidLen));
}
MapleClient client = new MapleClient(null, null, session);
Integer cid = Server.getInstance().freeCharacteridInTransition(session);
if (cid != null) {
try {
client.setAccID(MapleCharacter.loadCharFromDB(cid, client, false).getAccountID());
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}
session.setAttribute(MapleClient.CLIENT_KEY, client);
return client;
}
return null;
}
public void closeSession(IoSession session, Boolean immediately) {
MapleClient client = getSessionClient(session);
if (client == null) {
client = fetchInTransitionSessionClient(session);
}
String hwid = (String) session.removeAttribute(MapleClient.CLIENT_NIBBLEHWID); // making sure to clean up calls to this function on login phase
onlineRemoteHwids.remove(hwid);
hwid = (String) session.removeAttribute(MapleClient.CLIENT_HWID);
onlineRemoteHwids.remove(hwid);
MapleClient client = getSessionClient(session);
if (client != null) {
if (hwid != null) { // is a game session
onlineClients.remove(client.getAccID());
@@ -496,10 +529,12 @@ public class MapleSessionCoordinator {
if (immediately != null) {
session.close(immediately);
}
// session.removeAttribute(MapleClient.CLIENT_REMOTE_ADDRESS); No real need for removing String property on closed sessions
}
public String getGameSessionHwid(IoSession session) {
String remoteHost = getRemoteIp(session);
String remoteHost = getSessionRemoteAddress(session);
return cachedHostHwids.get(remoteHost);
}
@@ -0,0 +1,34 @@
/*
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
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.coordinator.matchchecker;
import client.MapleCharacter;
import java.util.Set;
/**
*
* @author Ronan
*/
public interface AbstractMatchCheckerListener {
public void onMatchCreated(MapleCharacter leader, Set<MapleCharacter> nonLeaderMatchPlayers, String message);
public void onMatchAccepted(int leaderid, Set<MapleCharacter> matchPlayers, String message);
public void onMatchDeclined(int leaderid, Set<MapleCharacter> matchPlayers, String message);
public void onMatchDismissed(int leaderid, Set<MapleCharacter> matchPlayers, String message);
}
@@ -0,0 +1,45 @@
/*
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
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.coordinator.matchchecker;
import net.server.coordinator.matchchecker.listener.MatchCheckerGuildCreation;
/**
*
* @author Ronan
*/
public class MatchCheckerListenerFactory {
public enum MatchCheckerType {
GUILD_CREATION(MatchCheckerGuildCreation.loadListener());
private final AbstractMatchCheckerListener listener;
private MatchCheckerType(AbstractMatchCheckerListener listener) {
this.listener = listener;
}
public AbstractMatchCheckerListener getListener() {
return this.listener;
}
}
}
@@ -0,0 +1,28 @@
/*
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
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.coordinator.matchchecker;
/**
*
* @author Ronan
*/
public interface MatchCheckerListenerRecipe {
public AbstractMatchCheckerListener getListener();
}
@@ -0,0 +1,181 @@
/*
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
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.coordinator.matchchecker.listener;
import client.MapleCharacter;
import constants.GameConstants;
import constants.ServerConstants;
import net.server.coordinator.matchchecker.AbstractMatchCheckerListener;
import net.server.coordinator.matchchecker.MatchCheckerListenerRecipe;
import net.server.guild.MapleGuild;
import net.server.guild.MapleGuildCharacter;
import java.util.Set;
import net.server.Server;
import net.server.world.MapleParty;
import tools.MaplePacketCreator;
/**
*
* @author Ronan
*/
public class MatchCheckerGuildCreation implements MatchCheckerListenerRecipe {
private static void broadcastGuildCreationDismiss(Set<MapleCharacter> nonLeaderMatchPlayers) {
for (MapleCharacter chr : nonLeaderMatchPlayers) {
if (chr.isLoggedinWorld()) {
chr.announce(MaplePacketCreator.genericGuildMessage((byte) 0x26));
}
}
}
public static AbstractMatchCheckerListener loadListener() {
return (new MatchCheckerGuildCreation()).getListener();
}
@Override
public AbstractMatchCheckerListener getListener() {
return new AbstractMatchCheckerListener() {
@Override
public void onMatchCreated(MapleCharacter leader, Set<MapleCharacter> nonLeaderMatchPlayers, String message) {
byte[] createGuildPacket = MaplePacketCreator.createGuildMessage(leader.getName(), message);
for (MapleCharacter chr : nonLeaderMatchPlayers) {
if (chr.isLoggedinWorld()) {
chr.announce(createGuildPacket);
}
}
}
@Override
public void onMatchAccepted(int leaderid, Set<MapleCharacter> matchPlayers, String message) {
MapleCharacter leader = null;
for (MapleCharacter chr : matchPlayers) {
if (chr.getId() == leaderid) {
leader = chr;
break;
}
}
if (leader == null || !leader.isLoggedinWorld()) {
broadcastGuildCreationDismiss(matchPlayers);
return;
}
matchPlayers.remove(leader);
if (leader.getGuildId() > 0) {
leader.dropMessage(1, "You cannot create a new Guild while in one.");
broadcastGuildCreationDismiss(matchPlayers);
return;
}
int partyid = leader.getPartyId();
if (partyid == -1 || !leader.isPartyLeader()) {
leader.dropMessage(1, "You cannot establish the creation of a new Guild without leading a party.");
broadcastGuildCreationDismiss(matchPlayers);
return;
}
if (leader.getMapId() != 200000301) {
leader.dropMessage(1, "You cannot establish the creation of a new Guild outside of the Guild Headquarters.");
broadcastGuildCreationDismiss(matchPlayers);
return;
}
for (MapleCharacter chr : matchPlayers) {
if (leader.getMap().getCharacterById(chr.getId()) == null) {
leader.dropMessage(1, "You cannot establish the creation of a new Guild if one of the members is not present here.");
broadcastGuildCreationDismiss(matchPlayers);
return;
}
}
if (leader.getMeso() < ServerConstants.CREATE_GUILD_COST) {
leader.dropMessage(1, "You do not have " + GameConstants.numberWithCommas(ServerConstants.CREATE_GUILD_COST) + " mesos to create a Guild.");
broadcastGuildCreationDismiss(matchPlayers);
return;
}
int gid = Server.getInstance().createGuild(leader.getId(), message);
if (gid == 0) {
leader.announce(MaplePacketCreator.genericGuildMessage((byte) 0x23));
broadcastGuildCreationDismiss(matchPlayers);
return;
}
leader.gainMeso(-ServerConstants.CREATE_GUILD_COST, true, false, true);
leader.getMGC().setGuildId(gid);
MapleGuild guild = Server.getInstance().getGuild(leader.getGuildId(), leader.getWorld(), leader); // initialize guild structure
Server.getInstance().changeRank(gid, leader.getId(), 1);
leader.announce(MaplePacketCreator.showGuildInfo(leader));
leader.dropMessage(1, "You have successfully created a Guild.");
for (MapleCharacter chr : matchPlayers) {
boolean cofounder = chr.getPartyId() == partyid;
MapleGuildCharacter mgc = chr.getMGC();
mgc.setGuildId(gid);
mgc.setGuildRank(cofounder ? 2 : 5);
mgc.setAllianceRank(5);
Server.getInstance().addGuildMember(mgc, chr);
if (chr.isLoggedinWorld()) {
chr.announce(MaplePacketCreator.showGuildInfo(chr));
if (cofounder) {
chr.dropMessage(1, "You have successfully cofounded a Guild.");
} else {
chr.dropMessage(1, "You have successfully joined the new Guild.");
}
}
chr.saveGuildStatus(); // update database
}
guild.broadcastNameChanged();
guild.broadcastEmblemChanged();
}
@Override
public void onMatchDeclined(int leaderid, Set<MapleCharacter> matchPlayers, String message) {
for (MapleCharacter chr : matchPlayers) {
if (chr.getId() == leaderid && chr.getClient() != null) {
MapleParty.leaveParty(chr.getParty(), chr.getClient());
}
if (chr.isLoggedinWorld()) {
chr.announce(MaplePacketCreator.genericGuildMessage((byte)0x24));
}
}
}
@Override
public void onMatchDismissed(int leaderid, Set<MapleCharacter> matchPlayers, String message) {
for (MapleCharacter chr : matchPlayers) {
if (chr.getId() == leaderid && chr.getClient() != null) {
MapleParty.leaveParty(chr.getParty(), chr.getClient());
}
if (chr.isLoggedinWorld()) {
chr.message("All cofounders must not be in a party when performing the Guild creation.");
}
}
}
};
}
}
+1 -1
View File
@@ -57,7 +57,7 @@ public class MapleAlliance {
public MapleAlliance(String name, int id) {
this.name = name;
allianceId = id;
String[] ranks = {"Master", "Jr.Master", "Member", "Member", "Member"};
String[] ranks = {"Master", "Jr. Master", "Member", "Member", "Member"};
for (int i = 0; i < 5; i++) {
rankTitles[i] = ranks[i];
}
+15 -1
View File
@@ -34,6 +34,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.Lock;
@@ -746,7 +747,20 @@ public class MapleGuild {
}
return false;
}
public static Set<MapleCharacter> getEligiblePlayersForGuild(MapleCharacter guildLeader) {
Set<MapleCharacter> guildMembers = new HashSet<>();
guildMembers.add(guildLeader);
for (MapleCharacter chr : guildLeader.getMap().getAllPlayers()) {
if (chr.getParty() == null && chr.getGuild() == null) {
guildMembers.add(chr);
}
}
return guildMembers;
}
public static void displayGuildRanks(MapleClient c, int npcid) {
try {
ResultSet rs;
@@ -23,7 +23,6 @@ package net.server.handlers.login;
import client.MapleClient;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import net.AbstractMaplePacketHandler;
import net.server.Server;
@@ -103,7 +102,7 @@ public final class CharSelectedHandler extends AbstractMaplePacketHandler {
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition((InetSocketAddress) session.getRemoteAddress(), charId);
server.setCharacteridInTransition(session, charId);
try {
c.announce(MaplePacketCreator.getServerIP(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]), charId));
@@ -1,7 +1,6 @@
package net.server.handlers.login;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import net.AbstractMaplePacketHandler;
@@ -85,7 +84,7 @@ public class CharSelectedWithPicHandler extends AbstractMaplePacketHandler {
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition((InetSocketAddress) c.getSession().getRemoteAddress(), charId);
server.setCharacteridInTransition(session, charId);
try {
c.announce(MaplePacketCreator.getServerIP(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]), charId));
@@ -38,9 +38,9 @@ import client.MapleClient;
import java.sql.ResultSet;
import java.sql.Statement;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import net.server.coordinator.MapleSessionCoordinator;
import org.apache.mina.core.session.IoSession;
public final class LoginPasswordHandler implements MaplePacketHandler {
@@ -57,15 +57,22 @@ public final class LoginPasswordHandler implements MaplePacketHandler {
}
private static String getRemoteIp(IoSession session) {
return ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress();
return MapleSessionCoordinator.getSessionRemoteAddress(session);
}
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
String remoteHost = getRemoteIp(c.getSession());
if (remoteHost.startsWith("127.") && !ServerConstants.HOST.startsWith("127.")) {
c.announce(MaplePacketCreator.getLoginFailed(13)); // cannot login as localhost if it's not a test server
return;
if (remoteHost.startsWith("127.")) {
if (!ServerConstants.LOCALSERVER) { // thanks Mills for noting HOST can also have a field named "localhost"
c.announce(MaplePacketCreator.getLoginFailed(13)); // cannot login as localhost if it's not a local server
return;
}
} else {
if (ServerConstants.LOCALSERVER) {
c.announce(MaplePacketCreator.getLoginFailed(13)); // cannot login as non-localhost if it's a local server
return;
}
}
String login = slea.readMapleAsciiString();
@@ -9,7 +9,6 @@ import net.server.world.World;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
import client.MapleClient;
import java.net.InetSocketAddress;
import net.server.coordinator.MapleSessionCoordinator;
import net.server.coordinator.MapleSessionCoordinator.AntiMulticlientResult;
import org.apache.mina.core.session.IoSession;
@@ -88,7 +87,7 @@ public final class RegisterPicHandler extends AbstractMaplePacketHandler {
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition((InetSocketAddress) c.getSession().getRemoteAddress(), charId);
server.setCharacteridInTransition(session, charId);
try {
c.announce(MaplePacketCreator.getServerIP(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]), charId));
@@ -2,11 +2,11 @@ package net.server.handlers.login;
import client.MapleClient;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import net.AbstractMaplePacketHandler;
import net.server.Server;
import net.server.coordinator.MapleSessionCoordinator;
import net.server.coordinator.MapleSessionCoordinator.AntiMulticlientResult;
import net.server.world.World;
import org.apache.mina.core.session.IoSession;
import tools.MaplePacketCreator;
@@ -15,7 +15,7 @@ import tools.data.input.SeekableLittleEndianAccessor;
public final class ViewAllCharRegisterPicHandler extends AbstractMaplePacketHandler {
private static int parseAntiMulticlientError(MapleSessionCoordinator.AntiMulticlientResult res) {
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
switch (res) {
case REMOTE_PROCESSING:
return 10;
@@ -57,8 +57,8 @@ public final class ViewAllCharRegisterPicHandler extends AbstractMaplePacketHand
}
IoSession session = c.getSession();
MapleSessionCoordinator.AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != MapleSessionCoordinator.AntiMulticlientResult.SUCCESS) {
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != AntiMulticlientResult.SUCCESS) {
c.announce(MaplePacketCreator.getAfterLoginError(parseAntiMulticlientError(res)));
return;
}
@@ -90,7 +90,7 @@ public final class ViewAllCharRegisterPicHandler extends AbstractMaplePacketHand
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition((InetSocketAddress) c.getSession().getRemoteAddress(), charId);
server.setCharacteridInTransition(session, charId);
try {
c.announce(MaplePacketCreator.getServerIP(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]), charId));
@@ -23,11 +23,11 @@ package net.server.handlers.login;
import client.MapleClient;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import net.AbstractMaplePacketHandler;
import net.server.Server;
import net.server.coordinator.MapleSessionCoordinator;
import net.server.coordinator.MapleSessionCoordinator.AntiMulticlientResult;
import net.server.world.World;
import org.apache.mina.core.session.IoSession;
import tools.MaplePacketCreator;
@@ -36,7 +36,7 @@ import tools.data.input.SeekableLittleEndianAccessor;
public final class ViewAllCharSelectedHandler extends AbstractMaplePacketHandler {
private static int parseAntiMulticlientError(MapleSessionCoordinator.AntiMulticlientResult res) {
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
switch (res) {
case REMOTE_PROCESSING:
return 10;
@@ -77,8 +77,8 @@ public final class ViewAllCharSelectedHandler extends AbstractMaplePacketHandler
}
IoSession session = c.getSession();
MapleSessionCoordinator.AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != MapleSessionCoordinator.AntiMulticlientResult.SUCCESS) {
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != AntiMulticlientResult.SUCCESS) {
c.announce(MaplePacketCreator.getAfterLoginError(parseAntiMulticlientError(res)));
return;
}
@@ -113,7 +113,7 @@ public final class ViewAllCharSelectedHandler extends AbstractMaplePacketHandler
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition((InetSocketAddress) c.getSession().getRemoteAddress(), charId);
server.setCharacteridInTransition(session, charId);
try {
c.announce(MaplePacketCreator.getServerIP(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]), charId));
@@ -10,13 +10,13 @@ import tools.MaplePacketCreator;
import tools.Randomizer;
import tools.data.input.SeekableLittleEndianAccessor;
import client.MapleClient;
import java.net.InetSocketAddress;
import net.server.coordinator.MapleSessionCoordinator;
import net.server.coordinator.MapleSessionCoordinator.AntiMulticlientResult;
import org.apache.mina.core.session.IoSession;
public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandler {
private static int parseAntiMulticlientError(MapleSessionCoordinator.AntiMulticlientResult res) {
private static int parseAntiMulticlientError(AntiMulticlientResult res) {
switch (res) {
case REMOTE_PROCESSING:
return 10;
@@ -59,8 +59,8 @@ public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandle
}
IoSession session = c.getSession();
MapleSessionCoordinator.AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != MapleSessionCoordinator.AntiMulticlientResult.SUCCESS) {
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != AntiMulticlientResult.SUCCESS) {
c.announce(MaplePacketCreator.getAfterLoginError(parseAntiMulticlientError(res)));
return;
}
@@ -90,7 +90,7 @@ public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandle
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition((InetSocketAddress) c.getSession().getRemoteAddress(), charId);
server.setCharacteridInTransition(session, charId);
try {
c.announce(MaplePacketCreator.getServerIP(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1]), charId));
+156
View File
@@ -21,7 +21,9 @@
*/
package net.server.world;
import client.MapleCharacter;
import client.MapleClient;
import constants.ServerConstants;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
@@ -34,7 +36,13 @@ import net.server.audit.LockCollector;
import net.server.audit.locks.MonitoredReentrantLock;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
import net.server.coordinator.MapleMatchCheckerCoordinator;
import net.server.coordinator.matchchecker.MatchCheckerListenerFactory.MatchCheckerType;
import scripting.event.EventInstanceManager;
import server.maps.MapleDoor;
import server.maps.MapleMap;
import server.partyquest.MonsterCarnival;
import tools.MaplePacketCreator;
public class MapleParty {
@@ -315,4 +323,152 @@ public class MapleParty {
}
return true;
}
public static boolean createParty(MapleCharacter player, boolean silentCheck) {
MapleParty party = player.getParty();
if (party == null) {
if(player.getLevel() < 10 && !ServerConstants.USE_PARTY_FOR_STARTERS) {
player.announce(MaplePacketCreator.partyStatusMessage(10));
return false;
}
MaplePartyCharacter partyplayer = new MaplePartyCharacter(player);
party = player.getWorldServer().createParty(partyplayer);
player.setParty(party);
player.setMPC(partyplayer);
player.getMap().addPartyMember(player);
player.silentPartyUpdate();
player.partyOperationUpdate(party, null);
player.announce(MaplePacketCreator.partyCreated(party, partyplayer.getId()));
return true;
} else {
if (!silentCheck) {
player.announce(MaplePacketCreator.partyStatusMessage(16));
}
return false;
}
}
public static boolean joinParty(MapleCharacter player, int partyid, boolean silentCheck) {
MapleParty party = player.getParty();
World world = player.getWorldServer();
if (party == null) {
party = world.getParty(partyid);
if (party != null) {
if (party.getMembers().size() < 6) {
MaplePartyCharacter partyplayer = new MaplePartyCharacter(player);
player.getMap().addPartyMember(player);
world.updateParty(party.getId(), PartyOperation.JOIN, partyplayer);
player.receivePartyMemberHP();
player.updatePartyMemberHP();
player.partyOperationUpdate(party, null);
return true;
} else {
if (!silentCheck) {
player.announce(MaplePacketCreator.partyStatusMessage(17));
}
}
} else {
player.announce(MaplePacketCreator.serverNotice(5, "You couldn't join the party since it had already been disbanded."));
}
} else {
if (!silentCheck) {
player.announce(MaplePacketCreator.serverNotice(5, "You can't join the party as you are already in one."));
}
}
return false;
}
public static void leaveParty(MapleParty party, MapleClient c) {
World world = c.getWorldServer();
MapleCharacter player = c.getPlayer();
MaplePartyCharacter partyplayer = player.getMPC();
if (party != null && partyplayer != null) {
if (partyplayer.getId() == party.getLeaderId()) {
c.getWorldServer().removeMapPartyMembers(party.getId());
MonsterCarnival mcpq = player.getMonsterCarnival();
if (mcpq != null) {
mcpq.leftParty(player.getId());
}
world.updateParty(party.getId(), PartyOperation.DISBAND, partyplayer);
EventInstanceManager eim = player.getEventInstance();
if(eim != null) {
eim.disbandParty();
}
} else {
MapleMap map = player.getMap();
if (map != null) {
map.removePartyMember(player);
}
MonsterCarnival mcpq = player.getMonsterCarnival();
if (mcpq != null) {
mcpq.leftParty(player.getId());
}
world.updateParty(party.getId(), PartyOperation.LEAVE, partyplayer);
EventInstanceManager eim = player.getEventInstance();
if(eim != null) {
eim.leftParty(player);
}
}
player.setParty(null);
MapleMatchCheckerCoordinator mmce = c.getWorldServer().getMatchCheckerCoordinator();
if (mmce.getMatchConfirmationLeaderid(player.getId()) == player.getId() && mmce.getMatchConfirmationType(player.getId()) == MatchCheckerType.GUILD_CREATION) {
mmce.dismissMatchConfirmation(player.getId());
}
}
}
public static void expelFromParty(MapleParty party, MapleClient c, int expelCid) {
World world = c.getWorldServer();
MapleCharacter player = c.getPlayer();
MaplePartyCharacter partyplayer = player.getMPC();
if (party != null && partyplayer != null) {
if (partyplayer.equals(party.getLeader())) {
MaplePartyCharacter expelled = party.getMemberById(expelCid);
if (expelled != null) {
MapleCharacter emc = expelled.getPlayer();
if(emc != null) {
List<MapleCharacter> partyMembers = emc.getPartyMembers();
MapleMap map = emc.getMap();
if(map != null) map.removePartyMember(emc);
MonsterCarnival mcpq = player.getMonsterCarnival();
if (mcpq != null) {
mcpq.leftParty(emc.getId());
}
EventInstanceManager eim = emc.getEventInstance();
if(eim != null) {
eim.leftParty(emc);
}
emc.setParty(null);
world.updateParty(party.getId(), PartyOperation.EXPEL, expelled);
emc.partyOperationUpdate(party, partyMembers);
} else {
world.updateParty(party.getId(), PartyOperation.EXPEL, expelled);
}
}
}
}
}
}
@@ -142,99 +142,4 @@ public class MaplePartyCharacter {
return world;
}
public String getJobNameById(int job) {
switch (job) {
case 0:
return "Aprendiz";
case 100:
return "Guerreiro";// Warrior
case 110:
return "Soldado";
case 111:
return "Templario";
case 112:
return "Heroi";
case 120:
return "Escudeiro";
case 121:
return "Cavaleiro Branco";
case 122:
return "Paladino";
case 130:
return "Lanceiro";
case 131:
return "Cavaleiro Draconiano";
case 132:
return "Cavaleiro Negro";
case 200:
return "Bruxo";
case 210:
return "Feiticeiro (Fogo, Veneno)";
case 211:
return "Mago (Fogo, Veneno)";
case 212:
return "Arquimago (Fogo, Veneno)";
case 220:
return "Feiticeiro (Gelo, Raio)";
case 221:
return "Mago (Gelo, Raio)";
case 222:
return "Arquimago (Gelo, Raio)";
case 230:
return "Clerigo";
case 231:
return "Sacerdote";
case 232:
return "Sumo Sacerdote";
case 300:
return "Arqueiro";
case 310:
return "Cacador";
case 311:
return "Rastreador";
case 312:
return "Mestre Arqueiro";
case 320:
return "Balestreiro";
case 321:
return "Atirador";
case 322:
return "Atirador De Elite";
case 400:
return "Gatuno";
case 410:
return "Mercenario";
case 411:
return "Andarilho";
case 412:
return "Lorde Negro";
case 420:
return "Arruaceiro";
case 421:
return "Mestre Arruaceiro";
case 422:
return "Mestre Das Sombras";
case 500:
return "Pirata";
case 510:
return "Lutador";
case 511:
return "Saqueador";
case 512:
return "Foragido";
case 520:
return "Pistoleiro";
case 521:
return "Bucaneiro";
case 522:
return "Capitao";
default:
return "Unknown Job";
}
}
}
+16 -2
View File
@@ -85,6 +85,7 @@ import net.server.guild.MapleGuildSummary;
import tools.DatabaseConnection;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.packets.Fishing;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.MonitoredReentrantLock;
import net.server.audit.locks.MonitoredReentrantReadWriteLock;
@@ -92,7 +93,7 @@ import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
import net.server.coordinator.MapleInviteCoordinator;
import net.server.coordinator.MapleInviteCoordinator.InviteResult;
import net.server.coordinator.MapleInviteCoordinator.InviteType;
import tools.packets.Fishing;
import net.server.coordinator.MapleMatchCheckerCoordinator;
/**
*
@@ -113,6 +114,7 @@ public class World {
private Map<Integer, Pair<Integer, Integer>> relationshipCouples = new HashMap<>();
private Map<Integer, MapleGuildSummary> gsStore = new HashMap<>();
private PlayerStorage players = new PlayerStorage();
private MapleMatchCheckerCoordinator matchChecker = new MapleMatchCheckerCoordinator();
private final ReentrantReadWriteLock chnLock = new MonitoredReentrantReadWriteLock(MonitoredLockType.WORLD_CHANNELS, true);
private ReadLock chnRLock = chnLock.readLock();
@@ -488,6 +490,10 @@ public class World {
public PlayerStorage getPlayerStorage() {
return players;
}
public MapleMatchCheckerCoordinator getMatchCheckerCoordinator() {
return matchChecker;
}
public void addPlayer(MapleCharacter chr) {
players.addPlayer(chr);
@@ -1267,7 +1273,15 @@ public class World {
private List<List<Pair<Integer, Integer>>> getBoughtCashItems() {
if (ServerConstants.USE_ENFORCE_ITEM_SUGGESTION) {
return new ArrayList<>(0);
List<List<Pair<Integer, Integer>>> boughtCounts = new ArrayList<>(9);
// thanks GabrielSin for pointing out an issue here
for (int i = 0; i < 9; i++) {
List<Pair<Integer, Integer>> tabCounts = new ArrayList<>(0);
boughtCounts.add(tabCounts);
}
return boughtCounts;
}
suggestRLock.lock();
+95 -64
View File
@@ -57,6 +57,7 @@ import client.SkillFactory;
import client.inventory.Item;
import client.inventory.ItemFactory;
import client.inventory.MaplePet;
import constants.GameConstants;
import constants.ItemConstants;
import constants.LanguageConstants;
import net.server.PlayerStorage;
@@ -400,8 +401,8 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
getPlayer().changeJob(job);
}
public MapleJob getJobName(int id) {
return MapleJob.getById(id);
public String getJobName(int id) {
return GameConstants.getJobName(id);
}
public MapleStatEffect getItemEffect(int itemId) {
@@ -617,7 +618,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
}
// By Drago/Dragohe4rt CPQ + WED
public int calcAvgLvl(int map) {
public int cpqCalcAvgLvl(int map) {
int num = 0;
int avg = 0;
for (MapleMapObject mmo : c.getChannelServer().getMapFactory().getMap(map).getAllPlayer()) {
@@ -628,30 +629,38 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
return avg;
}
public void sendCPQMapLists() {
String msg = LanguageConstants.Linguas(getPlayer()).CPQInicioEscolha;
public boolean sendCPQMapLists() {
String msg = LanguageConstants.Languages(getPlayer()).CPQPickRoom;
int msgLen = msg.length();
for (int i = 0; i < 6; i++) {
if (fieldTaken(i)) {
if (fieldLobbied(i)) {
msg += "#b#L" + i + "#Map " + (i + 1) + " (nível: "
+ calcAvgLvl(980000100 + i * 100) + " / "
msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (Level: " // "Carnival field" GMS-like improvement thanks to Jayd
+ cpqCalcAvgLvl(980000100 + i * 100) + " / "
+ getPlayerCount(980000100 + i * 100) + "x"
+ getPlayerCount(980000100 + i * 100) + ") #l\\r\\n";
} else {
continue;
+ getPlayerCount(980000100 + i * 100) + ") #l\r\n";
}
} else {
if (i >= 0 && i <= 3) {
msg += "#b#L" + i + "#Map " + (i + 1) + " (2x2) #l\\r\\n";
msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (2x2) #l\r\n";
} else {
msg += "#b#L" + i + "#Map " + (i + 1) + " (3x3) #l\\r\\n";
msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (3x3) #l\r\n";
}
}
}
sendSimple(msg);
if (msg.length() > msgLen) {
sendSimple(msg);
return true;
} else {
return false;
}
}
public boolean fieldTaken(int field) {
if (!c.getChannelServer().canInitMonsterCarnival(true, field)) {
return true;
}
if (!c.getChannelServer().getMapFactory().getMap(980000100 + field * 100).getAllPlayer().isEmpty()) {
return true;
}
@@ -684,7 +693,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
mc = ps.getCharacterById(mpc.getId());
if (mc != null) {
mc.changeMap(map, map.getPortal(0));
mc.announce(MaplePacketCreator.serverNotice(6, LanguageConstants.Linguas(mc).CPQEntradaLobby));
mc.announce(MaplePacketCreator.serverNotice(6, LanguageConstants.Languages(mc).CPQEntryLobby));
TimerManager tMan = TimerManager.getInstance();
tMan.schedule(new Runnable() {
@Override
@@ -710,7 +719,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
return c.getChannelServer().getPlayerStorage().getCharacterById(id);
}
public void cancelarSaida() {
public void cancelCPQLobby() {
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
@@ -719,10 +728,21 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
}
}
}
private void warpoutCPQLobby() {
MapleMap lobbyMap = c.getPlayer().getMap();
MapleMap out = this.getWarpMap((lobbyMap.getId() > 980030000) ? 980000000 : 980030000);
for (MapleCharacter mc : lobbyMap.getAllPlayers()) {
mc.resetCP();
mc.setTeam(-1);
mc.setMonsterCarnival(null);
mc.changeMap(out, out.getPortal(0));
}
}
public void startCPQ(final MapleCharacter challenger, final int field) {
try {
cancelarSaida();
cancelCPQLobby();
if (challenger != null) {
if (challenger.getParty() == null) {
throw new RuntimeException("Nao existe oponente!");
@@ -759,14 +779,19 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
tMan.schedule(new Runnable() {
@Override
public void run() {
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
mc.setMonsterCarnival(null);
}
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
mc.setMonsterCarnival(null);
try {
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
mc.setMonsterCarnival(null);
}
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
mc.setMonsterCarnival(null);
}
} catch (NullPointerException npe) {
warpoutCPQLobby();
return;
}
new MonsterCarnival(getPlayer().getParty(), challenger.getParty(), mapid, true, (field / 100) % 10);
@@ -779,7 +804,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
public void startCPQ2(final MapleCharacter challenger, final int field) {
try {
cancelarSaida();
cancelCPQLobby();
if (challenger != null) {
if (challenger.getParty() == null) {
throw new RuntimeException("Não existe oponente!");
@@ -798,15 +823,19 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
tMan.schedule(new Runnable() {
@Override
public void run() {
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
mc.setMonsterCarnival(null);
}
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
mc.setMonsterCarnival(null);
try {
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
mc.setMonsterCarnival(null);
}
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
mc.setMonsterCarnival(null);
}
} catch (NullPointerException npe) {
warpoutCPQLobby();
return;
}
new MonsterCarnival(getPlayer().getParty(), challenger.getParty(), mapid, false, (field / 1000) % 10);
@@ -817,35 +846,45 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
}
}
public void sendCPQMapLists2() {
String msg = LanguageConstants.Linguas(getPlayer()).CPQInicioEscolha;
public boolean sendCPQMapLists2() {
String msg = LanguageConstants.Languages(getPlayer()).CPQPickRoom;
int msgLen = msg.length();
for (int i = 0; i < 3; i++) {
if (fieldTaken2(i)) {
if (fieldLobbied2(i)) {
msg += "#b#L" + i + "#Map " + (i + 1) + " (Nível: "
+ calcAvgLvl(980031000 + i * 1000) + "#l\\r\\n";
} else {
continue;
msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (Level: " // "Carnival field" GMS-like improvement thanks to Jayd
+ cpqCalcAvgLvl(980031000 + i * 1000) + " / "
+ getPlayerCount(980031000 + i * 1000) + "x"
+ getPlayerCount(980031000 + i * 1000) + ") #l\r\n";
}
} else {
if (i == 0 || i == 1) {
msg += "#b#L" + i + "#Map " + (i + 1) + " (2x2) #l\\r\\n";
msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (2x2) #l\r\n";
} else {
msg += "#b#L" + i + "#Map " + (i + 1) + " (3x3) #l\\r\\n";
msg += "#b#L" + i + "#Carnival Field " + (i + 1) + " (3x3) #l\r\n";
}
}
}
sendSimple(msg);
if (msg.length() > msgLen) {
sendSimple(msg);
return true;
} else {
return false;
}
}
public boolean fieldTaken2(int field) {
if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) {
if (!c.getChannelServer().canInitMonsterCarnival(false, field)) {
return true;
}
if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) {
return true;
}
if (!c.getChannelServer().getMapFactory().getMap(980031000 + field * 1000).getAllPlayer().isEmpty()) {
if (!c.getChannelServer().getMapFactory().getMap(980031100 + field * 1000).getAllPlayer().isEmpty()) {
return true;
}
if (!c.getChannelServer().getMapFactory().getMap(980031200 + field * 1000).getAllPlayer().isEmpty()) {
return true;
}
return false;
@@ -868,10 +907,10 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
map = cs.getMapFactory().getMap(980031000 + 1000 * field);
for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) {
final MapleCharacter mc;
mc = ps.getCharacterByName(mpc.getName());
mc = ps.getCharacterById(mpc.getId());
if (mc != null) {
mc.changeMap(map, map.getPortal(0));
mc.announce(MaplePacketCreator.serverNotice(6, LanguageConstants.Linguas(mc).CPQEntradaLobby));
mc.announce(MaplePacketCreator.serverNotice(6, LanguageConstants.Languages(mc).CPQEntryLobby));
TimerManager tMan = TimerManager.getInstance();
tMan.schedule(new Runnable() {
@Override
@@ -899,7 +938,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
for (MapleMapObject mmo : map.getAllPlayer()) {
MapleCharacter mc = (MapleCharacter) mmo;
if (mc.getParty() == null) {
sendOk(LanguageConstants.Linguas(mc).CPQEscolha);
sendOk(LanguageConstants.Languages(mc).CPQFindError);
return;
}
if (mc.getParty().getLeader().getId() == mc.getId()) {
@@ -915,10 +954,10 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
}
NPCScriptManager.getInstance().start("cpqchallenge2", leader.getClient(), npc, members);
} else {
sendOk(LanguageConstants.Linguas(leader).CPQInicioEscolhaEmEscolha);
sendOk(LanguageConstants.Languages(leader).CPQChallengeRoomAnswer);
}
} else {
sendOk(LanguageConstants.Linguas(leader).CPQLiderNaoEncontrado);
sendOk(LanguageConstants.Languages(leader).CPQLeaderNotFound);
}
}
@@ -930,13 +969,13 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
MapleCharacter leader = null;
MapleMap map = c.getChannelServer().getMapFactory().getMap(980000100 + 100 * field);
if (map.getAllPlayer().size() != getPlayer().getParty().getMembers().size()) {
sendOk("erro");
sendOk("An unexpected error regarding the other party has occurred.");
return;
}
for (MapleMapObject mmo : map.getAllPlayer()) {
MapleCharacter mc = (MapleCharacter) mmo;
if (mc.getParty() == null) {
sendOk(LanguageConstants.Linguas(mc).CPQEscolha);
sendOk(LanguageConstants.Languages(mc).CPQFindError);
return;
}
if (mc.getParty().getLeader().getId() == mc.getId()) {
@@ -952,23 +991,15 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
}
NPCScriptManager.getInstance().start("cpqchallenge", leader.getClient(), npc, members);
sendOk(LanguageConstants.Linguas(leader).CPQInicioEscolhaEnviada);
sendOk(LanguageConstants.Languages(leader).CPQChallengeRoomSent);
} else {
sendOk(LanguageConstants.Linguas(leader).CPQInicioEscolhaEmEscolha);
sendOk(LanguageConstants.Languages(leader).CPQChallengeRoomAnswer);
}
} else {
sendOk(LanguageConstants.Linguas(leader).CPQLiderNaoEncontrado);
sendOk(LanguageConstants.Languages(leader).CPQLeaderNotFound);
}
}
public MapleCharacter getCharByName(String namee) {
try {
return getClient().getChannelServer().getPlayerStorage().getCharacterByName(namee);
} catch (Exception e) {
return null;
}
}
public void sendMarriageWishlist(boolean groom) {
MapleCharacter player = this.getPlayer();
MapleMarriage marriage = player.getMarriageInstance();
+1 -1
View File
@@ -1657,7 +1657,7 @@ public class MapleItemInformationProvider {
if (!EquipSlot.getFromTextSlot(islot).isAllowed(dst, isCash(id))) {
equip.wear(false);
String itemName = MapleItemInformationProvider.getInstance().getName(equip.getItemId());
Server.getInstance().broadcastGMMessage(chr.getWorld(), MaplePacketCreator.sendYellowTip("[WARNING]: " + chr.getName() + " tried to equip " + itemName + " into slot " + dst + "."));
Server.getInstance().broadcastGMMessage(chr.getWorld(), MaplePacketCreator.sendYellowTip("[Warning]: " + chr.getName() + " tried to equip " + itemName + " into slot " + dst + "."));
AutobanFactory.PACKET_EDIT.alert(chr, chr.getName() + " tried to forcibly equip an item.");
FilePrinter.printError(FilePrinter.EXPLOITS + chr.getName() + ".txt", chr.getName() + " tried to equip " + itemName + " into " + dst + " slot.");
return false;
+32 -27
View File
@@ -69,15 +69,18 @@ public class MapleMarriage extends EventInstanceManager {
}
public List<Item> getGiftItems(MapleClient c, boolean groom) {
c.tryacquireClient();
try {
List<Item> gifts = getGiftItemsList(groom);
synchronized (gifts) {
return new LinkedList<>(gifts);
if (c.tryacquireClient()) {
try {
List<Item> gifts = getGiftItemsList(groom);
synchronized (gifts) {
return new LinkedList<>(gifts);
}
} finally {
c.releaseClient();
}
} finally {
c.releaseClient();
}
return new LinkedList<>();
}
private List<Item> getGiftItemsList(boolean groom) {
@@ -140,21 +143,22 @@ public class MapleMarriage extends EventInstanceManager {
}
public static List<Item> loadGiftItemsFromDb(MapleClient c, int cid) {
c.tryacquireClient();
try {
List<Item> items = new LinkedList<>();
List<Item> items = new LinkedList<>();
if (c.tryacquireClient()) {
try {
for (Pair<Item, MapleInventoryType> it : ItemFactory.MARRIAGE_GIFTS.loadItems(cid, false)) {
items.add(it.getLeft());
try {
for (Pair<Item, MapleInventoryType> it : ItemFactory.MARRIAGE_GIFTS.loadItems(cid, false)) {
items.add(it.getLeft());
}
} catch (SQLException sqle) {
sqle.printStackTrace();
}
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
c.releaseClient();
}
return items;
} finally {
c.releaseClient();
}
return items;
}
public void saveGiftItemsToDb(MapleClient c, boolean groom, int cid) {
@@ -167,17 +171,18 @@ public class MapleMarriage extends EventInstanceManager {
items.add(new Pair<>(it, it.getInventoryType()));
}
c.tryacquireClient();
try {
if (c.tryacquireClient()) {
try {
Connection con = DatabaseConnection.getConnection();
ItemFactory.MARRIAGE_GIFTS.saveItems(items, cid, con);
con.close();
} catch (SQLException sqle) {
sqle.printStackTrace();
try {
Connection con = DatabaseConnection.getConnection();
ItemFactory.MARRIAGE_GIFTS.saveItems(items, cid, con);
con.close();
} catch (SQLException sqle) {
sqle.printStackTrace();
}
} finally {
c.releaseClient();
}
} finally {
c.releaseClient();
}
}
}
+16 -3
View File
@@ -944,13 +944,26 @@ public class MapleStatEffect {
if (skill != null) {
final MapleDisease dis = skill.getDisease();
MapleParty opposition = applyfrom.getParty().getEnemy();
for (MaplePartyCharacter enemyChrs : opposition.getPartyMembers()) {
MapleCharacter chrApp = enemyChrs.getPlayer();
if (skill.targetsAll) {
for (MaplePartyCharacter enemyChrs : opposition.getPartyMembers()) {
MapleCharacter chrApp = enemyChrs.getPlayer();
if (chrApp != null && chrApp.getMap().isCPQMap()) {
if (dis == null) {
chrApp.dispel();
} else {
chrApp.giveDebuff(dis, MCSkill.getMobSkill(dis.getDisease(), skill.level));
}
}
}
} else {
int amount = opposition.getMembers().size() - 1;
int randd = (int) Math.floor(Math.random() * amount);
MapleCharacter chrApp = applyfrom.getMap().getCharacterById(opposition.getMemberByPos(randd).getId());
if (chrApp != null && chrApp.getMap().isCPQMap()) {
if (dis == null) {
chrApp.dispel();
} else {
chrApp.giveDebuff(dis, MCSkill.getMobSkill(dis.getDisease()));
chrApp.giveDebuff(dis, MCSkill.getMobSkill(dis.getDisease(), skill.level));
}
}
}
+22 -4
View File
@@ -83,7 +83,7 @@ public class MapleTrade {
this.number = number;
}
private static int getFee(long meso) {
public static int getFee(long meso) {
long fee = 0;
if (meso >= 100000000) {
fee = (meso * 6) / 100;
@@ -179,7 +179,7 @@ public class MapleTrade {
throw new RuntimeException("Trade is locked.");
}
if (meso < 0) {
System.out.println("[h4x] " + chr.getName() + " Trying to trade < 0 mesos");
System.out.println("[Hack] " + chr.getName() + " Trying to trade < 0 mesos");
return;
}
if (chr.getMeso() >= meso) {
@@ -372,12 +372,30 @@ public class MapleTrade {
chr.setTrade(null);
}
private static byte[] tradeResultsPair(byte result) {
byte selfResult, partnerResult;
if (result == TradeResult.PARTNER_CANCEL.getValue()) {
partnerResult = result;
selfResult = TradeResult.NO_RESPONSE.getValue();
} else if (result == TradeResult.UNSUCCESSFUL_UNIQUE_ITEM_LIMIT.getValue()) {
partnerResult = TradeResult.UNSUCCESSFUL.getValue();
selfResult = result;
} else {
partnerResult = result;
selfResult = result;
}
return new byte[]{selfResult, partnerResult};
}
private synchronized void tradeCancelHandshake(boolean updateSelf, byte result) {
byte selfResult, partnerResult;
MapleTrade self;
partnerResult = result;
selfResult = (result == TradeResult.PARTNER_CANCEL.getValue() ? TradeResult.NO_RESPONSE.getValue() : result);
byte[] pairedResult = tradeResultsPair(result);
selfResult = pairedResult[0];
partnerResult = pairedResult[1];
if (updateSelf) {
self = this;
+4 -3
View File
@@ -127,9 +127,9 @@ public class MapleMonster extends AbstractLoadedMapleLife {
externalLock.unlock();
}
private void initWithStats(MapleMonsterStats stats) {
private void initWithStats(MapleMonsterStats baseStats) {
setStance(5);
this.stats = stats;
this.stats = baseStats.copy();
hp.set(stats.getHp());
mp = stats.getMp();
@@ -223,7 +223,8 @@ public class MapleMonster extends AbstractLoadedMapleLife {
this.hp.addAndGet(hp);
}
public void setStartingHp(int hp) {
public synchronized void setStartingHp(int hp) {
stats.setHp(hp); // refactored mob stats after non-static HP pool suggestion thanks to twigs
this.hp.set(hp);
}
+51 -14
View File
@@ -21,6 +21,7 @@
*/
package server.life;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -36,20 +37,20 @@ import tools.Pair;
* @author Frz
*/
public class MapleMonsterStats {
private boolean changeable;
private int exp, hp, mp, level, PADamage, PDDamage, MADamage, MDDamage, dropPeriod, cp, buffToGive = -1, removeAfter;
private boolean boss, undead, ffaLoot, isExplosiveReward, firstAttack, removeOnMiss;
private String name;
private Map<String, Integer> animationTimes = new HashMap<String, Integer>();
private Map<Element, ElementalEffectiveness> resistance = new HashMap<Element, ElementalEffectiveness>();
private List<Integer> revives = Collections.emptyList();
private byte tagColor, tagBgColor;
private List<Pair<Integer, Integer>> skills = new ArrayList<Pair<Integer, Integer>>();
private Pair<Integer, Integer> cool = null;
private BanishInfo banish = null;
private List<loseItem> loseItem = null;
private selfDestruction selfDestruction = null;
private boolean friendly;
public boolean changeable;
public int exp, hp, mp, level, PADamage, PDDamage, MADamage, MDDamage, dropPeriod, cp, buffToGive = -1, removeAfter;
public boolean boss, undead, ffaLoot, isExplosiveReward, firstAttack, removeOnMiss;
public String name;
public Map<String, Integer> animationTimes = new HashMap<String, Integer>();
public Map<Element, ElementalEffectiveness> resistance = new HashMap<Element, ElementalEffectiveness>();
public List<Integer> revives = Collections.emptyList();
public byte tagColor, tagBgColor;
public List<Pair<Integer, Integer>> skills = new ArrayList<Pair<Integer, Integer>>();
public Pair<Integer, Integer> cool = null;
public BanishInfo banish = null;
public List<loseItem> loseItem = null;
public selfDestruction selfDestruction = null;
public boolean friendly;
public void setChange(boolean change) {
this.changeable = change;
@@ -337,4 +338,40 @@ public class MapleMonsterStats {
public void setMDDamage(int MDDamage) {
this.MDDamage = MDDamage;
}
public MapleMonsterStats copy() {
MapleMonsterStats copy = new MapleMonsterStats();
try {
FieldCopyUtil.setFields(this, copy);
} catch (Exception e) {
e.printStackTrace();
try {
Thread.sleep(10000);
} catch (Exception ex) {
}
}
return copy;
}
// FieldCopyUtil src: http://www.codesenior.com/en/tutorial/Java-Copy-Fields-From-One-Object-to-Another-Object-with-Reflection
private static class FieldCopyUtil { // thanks to Codesenior dev team
private static void setFields(Object from, Object to) {
Field[] fields = from.getClass().getDeclaredFields();
for (Field field : fields) {
try {
Field fieldFrom = from.getClass().getDeclaredField(field.getName());
Object value = fieldFrom.get(from);
to.getClass().getDeclaredField(field.getName()).set(to, value);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}
}
}
+2
View File
@@ -48,6 +48,7 @@ import tools.DatabaseConnection;
import tools.MaplePacketCreator;
import tools.Pair;
import net.server.audit.locks.MonitoredLockType;
import server.MapleTrade;
/**
*
@@ -274,6 +275,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject {
if (c.getPlayer().getMeso() >= price) {
if (canBuy(c, newItem)) {
c.getPlayer().gainMeso(-price, false);
price -= MapleTrade.getFee(price); // thanks BHB for pointing out trade fees not applying here
synchronized (sold) {
sold.add(new SoldItem(c.getPlayer().getName(), pItem.getItem().getItemId(), newItem.getQuantity(), price));
+16 -17
View File
@@ -1264,19 +1264,19 @@ public class MapleMap {
}
public void broadcastBalrogVictory(String leaderName) {
getWorldServer().dropMessage(6, "[VICTORY] " + leaderName + "'s party has successfully defeated the Balrog! Praise to them, they finished with " + countAlivePlayers() + " players alive.");
getWorldServer().dropMessage(6, "[Victory] " + leaderName + "'s party has successfully defeated the Balrog! Praise to them, they finished with " + countAlivePlayers() + " players alive.");
}
public void broadcastHorntailVictory() {
getWorldServer().dropMessage(6, "[VICTORY] To the crew that have finally conquered Horned Tail after numerous attempts, I salute thee! You are the true heroes of Leafre!!");
getWorldServer().dropMessage(6, "[Victory] To the crew that have finally conquered Horned Tail after numerous attempts, I salute thee! You are the true heroes of Leafre!!");
}
public void broadcastZakumVictory() {
getWorldServer().dropMessage(6, "[VICTORY] At last, the tree of evil that for so long overwhelmed Ossyria has fallen. To the crew that managed to finally conquer Zakum, after numerous attempts, victory! You are the true heroes of Ossyria!!");
getWorldServer().dropMessage(6, "[Victory] At last, the tree of evil that for so long overwhelmed Ossyria has fallen. To the crew that managed to finally conquer Zakum, after numerous attempts, victory! You are the true heroes of Ossyria!!");
}
public void broadcastPinkBeanVictory(int channel) {
getWorldServer().dropMessage(6, "[VICTORY] In a swift stroke of sorts, the crew that has attempted Pink Bean at channel " + channel + " has ultimately defeated it. The Temple of Time shines radiantly once again, the day finally coming back, as the crew that managed to finally conquer it returns victoriously from the battlefield!!");
getWorldServer().dropMessage(6, "[Victory] In a swift stroke of sorts, the crew that has attempted Pink Bean at channel " + channel + " has ultimately defeated it. The Temple of Time shines radiantly once again, the day finally coming back, as the crew that managed to finally conquer it returns victoriously from the battlefield!!");
}
private boolean removeKilledMonsterObject(MapleMonster monster) {
@@ -1893,7 +1893,7 @@ public class MapleMap {
public void spawnAllMonsterIdFromMapSpawnList(int id, int difficulty, boolean isPq) {
for(SpawnPoint sp: getAllMonsterSpawn()) {
if(sp.getMonsterId() == id) {
if(sp.getMonsterId() == id && sp.shouldForceSpawn()) {
spawnMonster(sp.getMonster(), difficulty, isPq);
}
}
@@ -2079,7 +2079,7 @@ public class MapleMap {
public MaplePortal getDoorPortal(int doorid) {
MaplePortal doorPortal = portals.get(0x80 + doorid);
if(doorPortal == null) {
FilePrinter.printError(FilePrinter.EXCEPTION, "[DOOR] " + mapName + "(" + mapid + ") does not contain door portalid " + doorid);
FilePrinter.printError(FilePrinter.EXCEPTION, "[Door] " + mapName + "(" + mapid + ") does not contain door portalid " + doorid);
return portals.get(0x80);
}
@@ -4334,10 +4334,10 @@ public class MapleMap {
if (team == 0 && redTeamBuffs.size() >= 4 || team == 1 && blueTeamBuffs.size() >= 4) {
return 2;
}
final MCSkill skil = MapleCarnivalFactory.getInstance().getGuardian(num);
if (team == 0 && redTeamBuffs.contains(skil)) {
final MCSkill skill = MapleCarnivalFactory.getInstance().getGuardian(num);
if (team == 0 && redTeamBuffs.contains(skill)) {
return 0;
} else if (team == 1 && blueTeamBuffs.contains(skil)) {
} else if (team == 1 && blueTeamBuffs.contains(skill)) {
return 0;
}
GuardianSpawnPoint pt = this.getRandomGuardianSpawn(team);
@@ -4352,7 +4352,7 @@ public class MapleMap {
reactor.resetReactorActions(0);
this.spawnReactor(reactor);
reactor.setGuardian(pt);
this.buffMonsters(team, skil);
this.buffMonsters(team, skill);
getReactorByOid(reactor.getObjectId()).hitReactor(((MapleCharacter) this.getAllPlayer().get(0)).getClient());
} catch (Exception e) {
e.printStackTrace();
@@ -4360,21 +4360,20 @@ public class MapleMap {
return 1;
}
public void buffMonsters(int team, MCSkill skil) {
public void buffMonsters(int team, MCSkill skill) {
if (skill == null) return;
if (team == 0) {
redTeamBuffs.add(skil);
redTeamBuffs.add(skill);
} else if (team == 1) {
blueTeamBuffs.add(skil);
blueTeamBuffs.add(skill);
}
for (MapleMapObject mmo : this.mapobjects.values()) {
if (mmo.getType() == MapleMapObjectType.MONSTER) {
MapleMonster mob = (MapleMonster) mmo;
if (mob.getTeam() == team) {
if (skil != null) {
skil.getSkill().applyEffect(null, mob, false, null);
}
skill.getSkill().applyEffect(null, mob, false, null);
}
}
}
}
+2
View File
@@ -42,6 +42,7 @@ import tools.Pair;
import tools.data.output.MaplePacketLittleEndianWriter;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
import server.MapleTrade;
/**
*
@@ -279,6 +280,7 @@ public class MaplePlayerShop extends AbstractMapleMapObject {
}
c.getPlayer().gainMeso(-price, false);
price -= MapleTrade.getFee(price); // thanks BHB for pointing out trade fees not applying here
owner.gainMeso(price, true);
SoldItem soldItem = new SoldItem(c.getPlayer().getName(), pItem.getItem().getItemId(), quantity, price);
@@ -2,7 +2,9 @@ package server.partyquest;
import client.MapleDisease;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import server.life.MobSkillFactory;
import provider.MapleDataProvider;
@@ -20,6 +22,9 @@ public class MapleCarnivalFactory {
private final Map<Integer, MCSkill> skills = new HashMap<Integer, MCSkill>();
private final Map<Integer, MCSkill> guardians = new HashMap<Integer, MCSkill>();
private final MapleDataProvider dataRoot = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Skill.wz"));
private final List<Integer> singleTargetedSkills = new ArrayList<>();
private final List<Integer> multiTargetedSkills = new ArrayList<>();
public MapleCarnivalFactory() {
//whoosh
@@ -35,15 +40,36 @@ public class MapleCarnivalFactory {
return;
}
for (MapleData z : dataRoot.getData("MCSkill.img")) {
skills.put(Integer.parseInt(z.getName()), new MCSkill(MapleDataTool.getInt("spendCP", z, 0), MapleDataTool.getInt("mobSkillID", z, 0), MapleDataTool.getInt("level", z, 0), MapleDataTool.getInt("target", z, 1) > 1));
Integer id = Integer.parseInt(z.getName());
MCSkill ms = new MCSkill(MapleDataTool.getInt("spendCP", z, 0), MapleDataTool.getInt("mobSkillID", z, 0), MapleDataTool.getInt("level", z, 0), MapleDataTool.getInt("target", z, 1) > 1);
skills.put(id, ms);
if (ms.targetsAll) {
multiTargetedSkills.add(id);
} else {
singleTargetedSkills.add(id);
}
}
for (MapleData z : dataRoot.getData("MCGuardian.img")) {
guardians.put(Integer.parseInt(z.getName()), new MCSkill(MapleDataTool.getInt("spendCP", z, 0), MapleDataTool.getInt("mobSkillID", z, 0), MapleDataTool.getInt("level", z, 0), true));
}
}
private MCSkill randomizeSkill(boolean multi) {
if (multi) {
return skills.get(multiTargetedSkills.get((int) (Math.random() * multiTargetedSkills.size())));
} else {
return skills.get(multiTargetedSkills.get((int) (Math.random() * multiTargetedSkills.size())));
}
}
public MCSkill getSkill(final int id) {
return skills.get(id);
MCSkill skill = skills.get(id);
if (skill != null && skill.skillid <= 0) {
return randomizeSkill(skill.targetsAll);
} else {
return skill;
}
}
public MCSkill getGuardian(final int id) {
@@ -63,17 +89,14 @@ public class MapleCarnivalFactory {
}
public MobSkill getSkill() {
return getMobSkill(skillid);
return getMobSkill(skillid, level);
}
public static MobSkill getMobSkill(int skillid) {
return MobSkillFactory.getMobSkill(skillid, 1); //level?
public static MobSkill getMobSkill(int skillid, int level) {
return MobSkillFactory.getMobSkill(skillid, level);
}
public MapleDisease getDisease() {
if (skillid <= 0) {
return MapleDisease.getRandom();
}
return MapleDisease.getBySkill(skillid);
}
}
+38 -32
View File
@@ -29,7 +29,7 @@ public class MonsterCarnival {
private long startTime = 0;
private int summonsR = 8, summonsB = 8, room = 0;
private MapleCharacter leader1, leader2, Grupo1, Grupo2;
private int redCP, blueCP, redTotalCP, blueTotalCP;
private int redCP, blueCP, redTotalCP, blueTotalCP, redTimeupCP, blueTimeupCP;
private boolean cpq1;
public MonsterCarnival(MapleParty p1, MapleParty p2, int mapid, boolean cpq1, int room) {
@@ -42,6 +42,7 @@ public class MonsterCarnival {
p1.setEnemy(p2);
p2.setEnemy(p1);
map = cs.getMapFactory().getDisposableMap(mapid);
startTime = System.currentTimeMillis() + 10 * 60 * 1000;
int redPortal = 0;
int bluePortal = 0;
if (map.isPurpleCPQMap()) {
@@ -55,7 +56,7 @@ public class MonsterCarnival {
mc.setTeam(0);
mc.setFestivalPoints(0);
mc.forceChangeMap(map, map.getPortal(redPortal));
mc.dropMessage(6, LanguageConstants.Linguas(mc).CPQEntrada);
mc.dropMessage(6, LanguageConstants.Languages(mc).CPQEntry);
if (p1.getLeader().getId() == mc.getId()) {
leader1 = mc;
}
@@ -69,7 +70,7 @@ public class MonsterCarnival {
mc.setTeam(1);
mc.setFestivalPoints(0);
mc.forceChangeMap(map, map.getPortal(bluePortal));
mc.dropMessage(6, LanguageConstants.Linguas(mc).CPQEntrada);
mc.dropMessage(6, LanguageConstants.Languages(mc).CPQEntry);
if (p2.getLeader().getId() == mc.getId()) {
leader2 = mc;
}
@@ -78,16 +79,16 @@ public class MonsterCarnival {
}
if (Grupo1 == null || Grupo2 == null) {
for (MaplePartyCharacter mpc : p2.getMembers()) {
mpc.getPlayer().dropMessage(5, LanguageConstants.Linguas(mpc.getPlayer()).CPQErro);
mpc.getPlayer().dropMessage(5, LanguageConstants.Languages(mpc.getPlayer()).CPQError);
}
for (MaplePartyCharacter mpc : p2.getMembers()) {
mpc.getPlayer().dropMessage(5, LanguageConstants.Linguas(mpc.getPlayer()).CPQErro);
mpc.getPlayer().dropMessage(5, LanguageConstants.Languages(mpc.getPlayer()).CPQError);
}
return;
}
Grupo1.getClient().announce(MaplePacketCreator.startMonsterCarnival(Grupo1, 0, 1));
Grupo2.getClient().announce(MaplePacketCreator.startMonsterCarnival(Grupo2, 1, 0));
startTime = System.currentTimeMillis() + 60 * 10000;
// thanks Atoot, Vcoc for noting double CPQ functional being sent to players in CPQ start
timer = TimerManager.getInstance().schedule(new Runnable() {
@Override
public void run() {
@@ -106,12 +107,8 @@ public class MonsterCarnival {
respawn();
}
}, ServerConstants.RESPAWN_INTERVAL);
TimerManager.getInstance().schedule(new Runnable() {
@Override
public void run() {
map.addClock(60 * 10);
}
}, 2000);
cs.initMonsterCarnival(cpq1, room);
} catch (Exception e) {
e.printStackTrace();
}
@@ -140,18 +137,18 @@ public class MonsterCarnival {
String teamS = "";
switch (team) {
case 0:
teamS = LanguageConstants.Linguas(chrMap).CPQVermelho;
teamS = LanguageConstants.Languages(chrMap).CPQRed;
break;
case 1:
teamS = LanguageConstants.Linguas(chrMap).CPQAzul;
teamS = LanguageConstants.Languages(chrMap).CPQBlue;
break;
}
chrMap.dropMessage(5, teamS + LanguageConstants.Linguas(chrMap).CPQPlayerExit);
chrMap.dropMessage(5, teamS + LanguageConstants.Languages(chrMap).CPQPlayerExit);
}
earlyFinish();
}
public void earlyFinish() {
private void earlyFinish() {
dispose(true);
}
@@ -180,12 +177,12 @@ public class MonsterCarnival {
}
protected void dispose(boolean warpout) {
Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel());
Channel cs = map.getChannelServer();
MapleMap out;
if (!cpq1) { // cpq2
out = cs.getMapFactory().getMap(980030000);
out = cs.getMapFactory().getMap(980030010);
} else {
out = cs.getMapFactory().getMap(980000000);
out = cs.getMapFactory().getMap(980000010);
}
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
@@ -227,7 +224,8 @@ public class MonsterCarnival {
leader2.getParty().setEnemy(null);
map.dispose();
map = null;
cs.finishMonsterCarnival(cpq1, room);
}
public void exit() {
@@ -238,9 +236,9 @@ public class MonsterCarnival {
return this.timer;
}
public void finish(int winningTeam) {
private void finish(int winningTeam) {
try {
Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel());
Channel cs = map.getChannelServer();
if (winningTeam == 0) {
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
MapleCharacter mc = cs.getPlayerStorage().getCharacterById(mpc.getId());
@@ -306,9 +304,9 @@ public class MonsterCarnival {
}
}
public void timeUp() {
int cp1 = this.redTotalCP;
int cp2 = this.blueTotalCP;
private void timeUp() {
int cp1 = this.redTimeupCP;
int cp2 = this.blueTimeupCP;
if (cp1 == cp2) {
extendTime();
return;
@@ -328,11 +326,11 @@ public class MonsterCarnival {
return (int) (getTimeLeft() / 1000);
}
public void extendTime() {
private void extendTime() {
for (MapleCharacter chrMap : map.getAllPlayers()) {
chrMap.dropMessage(5, LanguageConstants.Linguas(chrMap).CPQTempoExtendido);
chrMap.dropMessage(5, LanguageConstants.Languages(chrMap).CPQExtendTime);
}
startTime = System.currentTimeMillis() + 3 * 1000;
startTime = System.currentTimeMillis() + 3 * 60 * 1000;
map.addClock(3 * 60);
timer = TimerManager.getInstance().schedule(new Runnable() {
@Override
@@ -345,12 +343,16 @@ public class MonsterCarnival {
public void run() {
complete();
}
}, 3 * 60 * 1000 - 10);
}, 3 * 60 * 1000 - 10 * 1000); // thanks Vcoc for noticing a time set issue here
}
public void complete() {
int cp1 = this.redTotalCP;
int cp2 = this.blueTotalCP;
this.redTimeupCP = cp1;
this.blueTimeupCP = cp2;
if (cp1 == cp2) {
return;
}
@@ -361,7 +363,7 @@ public class MonsterCarnival {
throw new RuntimeException("Os lideres estao em canais diferentes.");
}
Channel cs = Server.getInstance().getWorld(p1.getLeader().getWorld()).getChannel(p1.getLeader().getChannel());
Channel cs = map.getChannelServer();
map.killAllMonsters();
for (MaplePartyCharacter mpc : leader1.getParty().getMembers()) {
MapleCharacter mc;
@@ -508,4 +510,8 @@ public class MonsterCarnival {
public int getRoom() {
return this.room;
}
public MapleMap getEventMap() {
return this.map;
}
}
+14 -4
View File
@@ -4212,8 +4212,8 @@ public class MaplePacketCreator {
mplew.writeInt(reactor.getId());
mplew.write(reactor.getState());
mplew.writePos(pos);
mplew.writeShort(0);
mplew.write(0);
mplew.writeShort(0);
return mplew.getPacket();
}
@@ -4225,8 +4225,8 @@ public class MaplePacketCreator {
mplew.writeInt(reactor.getObjectId());
mplew.write(reactor.getState());
mplew.writePos(pos);
mplew.writeShort(stance);
mplew.write(0);
mplew.write(stance);
mplew.writeShort(0);
mplew.write(5); // frame delay, set to 5 since there doesn't appear to be a fixed formula for it
return mplew.getPacket();
}
@@ -4387,7 +4387,17 @@ public class MaplePacketCreator {
mplew.writeMapleAsciiString(charName);
return mplew.getPacket();
}
public static byte[] createGuildMessage(String masterName, String guildName) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.GUILD_OPERATION.getValue());
mplew.write(0x3);
mplew.writeInt(0);
mplew.writeMapleAsciiString(masterName);
mplew.writeMapleAsciiString(guildName);
return mplew.getPacket();
}
/**
* Gets a Heracle/guild message packet.
*
+2 -2
View File
@@ -125,9 +125,9 @@ public class Fishing {
public static int getRandomItem(){
int rand = (int)(100.0 * Math.random());
int[] commons = {1002851, 2002020, 2002020, 2000006, 2000018, 2002018, 2002024, 2002027, 2002027, 2000018, 2000018, 2000018 , 2000018, 2002030, 2002018, 2000016}; // filler' up
int[] commons = {1002851, 2002020, 2002020, 2000006, 2000018, 2002018, 2002024, 2002027, 2002027, 2000018, 2000018, 2000018, 2000018, 2002030, 2002018, 2000016}; // filler' up
int[] uncommons = {1000025, 1002662, 1002812, 1002850, 1002881, 1002880, 1012072, 4020009, 2043220, 2043022, 2040543, 2044420, 2040943, 2043713, 2044220, 2044120, 2040429, 2043220, 2040943}; // filler' uptoo
int[] rares = {1002859, 1002553, 01002762, 01002763, 01002764, 01002765, 01002766, 01002663, 1002788, 1002949, 2049100, 2340000, 2040822,2040822,2040822,2040822,2040822,2040822,2040822,2040822}; // filler' uplast
int[] rares = {1002859, 1002553, 1002762, 1002763, 1002764, 1002765, 1002766, 1002663, 1002788, 1002949, 2049100, 2340000, 2040822, 2040822, 2040822, 2040822}; // filler' uplast
if(rand >= 25){
return commons[(int)(commons.length * Math.random())];