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

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;

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 {

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;

View File

@@ -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());

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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.");
}
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}

View File

@@ -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.");
}
}
}
};
}
}

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];
}

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;

View File

@@ -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));

View File

@@ -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));

View File

@@ -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();

View File

@@ -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));

View File

@@ -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));

View File

@@ -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));

View File

@@ -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));

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);
}
}
}
}
}
}

View File

@@ -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";
}
}
}

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();