Mystic Doors review + Togglable SrvMessage-BossHP + Map-Event patch
Reviewed Mystic Doors. Fixed several issues showing up on Duey in uncommon scenarios. Fixed a concurrency issue with XMLDomMapleData. Scheduled forward the "lock disposal" action within the source. Now, it's expected that, after a set while, no method should require usage of a disposed lock and, during that while, a supposed "disposed lock" is still available to run (although no new processes is expected to require use of these locks). Fixed concurrency issues with player's current event instance, generating several inconsistencies when swiftly registering/unregistering from events. Implemented a mutually exclusive approach for server message - Boss HPbar. Fixed item-making Kage requiring lv71~80 ETC instead of the expected 81~90. Removed the possibility to buy cosmetic coupons with mesos through the NPCs. Sleepywood JQ's no longer gives cash items when they finish the quest repeatedly. Added Duey trucks in several maps lacking it. Added NPC Duey in New Leaf City. Fixed scripted quests not calculating QUEST_RATE (if applied) when rewarding experience and meso.
This commit is contained in:
@@ -261,7 +261,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private Map<Integer, MapleSummon> summons = new LinkedHashMap<>();
|
||||
private Map<Integer, MapleCoolDownValueHolder> coolDowns = new LinkedHashMap<>();
|
||||
private EnumMap<MapleDisease, Pair<MapleDiseaseValueHolder, MobSkill>> diseases = new EnumMap<>(MapleDisease.class);
|
||||
private Map<Integer, MapleDoor> doors = new LinkedHashMap<>();
|
||||
private MapleDoor pdoor = null;
|
||||
private Map<MapleQuest, Long> questExpirations = new LinkedHashMap<>();
|
||||
private ScheduledFuture<?> dragonBloodSchedule;
|
||||
private ScheduledFuture<?> hpDecreaseTask;
|
||||
@@ -277,6 +277,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
private ScheduledFuture<?> pendantOfSpirit = null; //1122017
|
||||
private Lock chrLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_CHR, true);
|
||||
private Lock effLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_EFF, true);
|
||||
private Lock evtLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_EVT, true);
|
||||
private Lock petLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_PET, true); // for quest tasks as well
|
||||
private Lock prtLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CHARACTER_PRT);
|
||||
private Map<Integer, Set<Integer>> excluded = new LinkedHashMap<>();
|
||||
@@ -343,7 +344,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
quests = new LinkedHashMap<>();
|
||||
setPosition(new Point(0, 0));
|
||||
|
||||
petLootCd = System.currentTimeMillis();
|
||||
petLootCd = Server.getInstance().getCurrentTime();
|
||||
}
|
||||
|
||||
private static MapleJob getJobStyleInternal(int jobid, byte opt) {
|
||||
@@ -586,25 +587,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
return pts;
|
||||
}
|
||||
|
||||
public void addDoor(Integer owner, MapleDoor door) {
|
||||
chrLock.lock();
|
||||
try {
|
||||
doors.put(owner, door);
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeDoor(Integer owner) {
|
||||
chrLock.lock();
|
||||
try {
|
||||
doors.remove(owner);
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void addFame(int famechange) {
|
||||
this.fame += famechange;
|
||||
}
|
||||
@@ -889,13 +872,13 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
this.loggedIn = true;
|
||||
c.setAccountName(this.client.getAccountName());//No null's for accountName
|
||||
this.client = c;
|
||||
this.map = c.getChannelServer().getMapFactory().getMap(getMapId());
|
||||
MaplePortal portal = map.findClosestPlayerSpawnpoint(getPosition());
|
||||
if (portal == null) {
|
||||
portal = map.getPortal(0);
|
||||
}
|
||||
this.setPosition(portal.getPosition());
|
||||
this.initialSpawnPoint = portal.getId();
|
||||
this.map = c.getChannelServer().getMapFactory().getMap(getMapId());
|
||||
}
|
||||
|
||||
public String getMedalText() {
|
||||
@@ -1352,9 +1335,13 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
public void changeMap(MapleMap to) {
|
||||
changeMap(to, to.getPortal(0));
|
||||
changeMap(to, 0);
|
||||
}
|
||||
|
||||
public void changeMap(MapleMap to, int portal) {
|
||||
changeMap(to, to.getPortal(portal));
|
||||
}
|
||||
|
||||
public void changeMap(final MapleMap target, final MaplePortal pto) {
|
||||
canWarpCounter++;
|
||||
|
||||
@@ -1437,7 +1424,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return lastVisited;
|
||||
}
|
||||
|
||||
public void updateMapDropsUponPartyOperation(List<MapleCharacter> exPartyMembers) {
|
||||
public void partyOperationUpdate(MapleParty party, List<MapleCharacter> exPartyMembers) {
|
||||
List<WeakReference<MapleMap>> mapids;
|
||||
|
||||
petLock.lock();
|
||||
@@ -1468,6 +1455,84 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
mapObj.updatePlayerItemDrops(partyId, id, partyMembers, partyLeaver);
|
||||
}
|
||||
}
|
||||
|
||||
updatePartyTownDoors(party, this, partyLeaver, partyMembers);
|
||||
}
|
||||
|
||||
private static void addPartyPlayerDoor(MapleCharacter target) {
|
||||
MapleDoor targetDoor = target.getPlayerDoor();
|
||||
if(targetDoor != null) {
|
||||
target.applyPartyDoor(targetDoor, true);
|
||||
}
|
||||
}
|
||||
|
||||
private static void removePartyPlayerDoor(MapleParty party, MapleCharacter target) {
|
||||
target.removePartyDoor(party);
|
||||
}
|
||||
|
||||
private static void updatePartyTownDoors(MapleParty party, MapleCharacter target, MapleCharacter partyLeaver, List<MapleCharacter> partyMembers) {
|
||||
if(partyLeaver != null) {
|
||||
removePartyPlayerDoor(party, target);
|
||||
} else {
|
||||
addPartyPlayerDoor(target);
|
||||
}
|
||||
|
||||
Map<Integer, MapleDoor> partyDoors = null;
|
||||
if(!partyMembers.isEmpty()) {
|
||||
partyDoors = party.getDoors();
|
||||
|
||||
for(MapleCharacter pchr : partyMembers) {
|
||||
MapleDoor door = partyDoors.get(pchr.getId());
|
||||
if(door != null) {
|
||||
door.updateDoorPortal(pchr);
|
||||
}
|
||||
}
|
||||
|
||||
for(MapleDoor door : partyDoors.values()) {
|
||||
for(MapleCharacter pchar : partyMembers) {
|
||||
door.getTownDoor().sendDestroyData(pchar.getClient(), true);
|
||||
}
|
||||
}
|
||||
|
||||
if(partyLeaver != null) {
|
||||
Collection<MapleDoor> leaverDoors = partyLeaver.getDoors();
|
||||
for(MapleDoor door : leaverDoors) {
|
||||
for(MapleCharacter pchar : partyMembers) {
|
||||
door.getTownDoor().sendDestroyData(pchar.getClient(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Integer> histMembers = party.getMembersSortedByHistory();
|
||||
for(Integer chrid : histMembers) {
|
||||
MapleDoor door = partyDoors.get(chrid);
|
||||
|
||||
if(door != null) {
|
||||
for(MapleCharacter pchar : partyMembers) {
|
||||
door.getTownDoor().sendSpawnData(pchar.getClient());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(partyLeaver != null) {
|
||||
Collection<MapleDoor> leaverDoors = partyLeaver.getDoors();
|
||||
|
||||
if(partyDoors != null) {
|
||||
for(MapleDoor door : partyDoors.values()) {
|
||||
door.getTownDoor().sendDestroyData(partyLeaver.getClient(), true);
|
||||
}
|
||||
}
|
||||
|
||||
for(MapleDoor door : leaverDoors) {
|
||||
door.getTownDoor().sendDestroyData(partyLeaver.getClient(), true);
|
||||
}
|
||||
|
||||
for(MapleDoor door : leaverDoors) {
|
||||
door.updateDoorPortal(partyLeaver);
|
||||
door.getTownDoor().sendSpawnData(partyLeaver.getClient());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Integer getVisitedMapIndex(MapleMap map) {
|
||||
@@ -2238,10 +2303,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
public void dispel() {
|
||||
List<MapleBuffStatValueHolder> mbsvhList = getAllStatups();
|
||||
for (MapleBuffStatValueHolder mbsvh : mbsvhList) {
|
||||
if (mbsvh.effect.isSkill()) {
|
||||
cancelEffect(mbsvh.effect, false, mbsvh.startTime);
|
||||
if(!(ServerConstants.USE_UNDISPEL_HOLY_SHIELD && this.isActiveBuffedValue(Bishop.HOLY_SHIELD))) {
|
||||
List<MapleBuffStatValueHolder> mbsvhList = getAllStatups();
|
||||
for (MapleBuffStatValueHolder mbsvh : mbsvhList) {
|
||||
if (mbsvh.effect.isSkill()) {
|
||||
cancelEffect(mbsvh.effect, false, mbsvh.startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3376,14 +3443,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
if (effect.isMagicDoor()) {
|
||||
MapleDoor destroyDoor;
|
||||
|
||||
chrLock.lock();
|
||||
try {
|
||||
destroyDoor = doors.remove(this.getId());
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
}
|
||||
MapleDoor destroyDoor = removePartyDoor(false);
|
||||
|
||||
if (destroyDoor != null) {
|
||||
destroyDoor.getTarget().removeMapObject(destroyDoor.getAreaDoor());
|
||||
@@ -3392,21 +3452,18 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
for (MapleCharacter chr : destroyDoor.getTarget().getCharacters()) {
|
||||
destroyDoor.getAreaDoor().sendDestroyData(chr.getClient());
|
||||
}
|
||||
for (MapleCharacter chr : destroyDoor.getTown().getCharacters()) {
|
||||
|
||||
Collection<MapleCharacter> townChars = destroyDoor.getTown().getCharacters();
|
||||
for (MapleCharacter chr : townChars) {
|
||||
destroyDoor.getTownDoor().sendDestroyData(chr.getClient());
|
||||
}
|
||||
|
||||
prtLock.lock();
|
||||
try {
|
||||
if (party != null) {
|
||||
for (MaplePartyCharacter partyMembers : party.getMembers()) {
|
||||
partyMembers.getPlayer().removeDoor(this.getId());
|
||||
partyMembers.removeDoor(this.getId());
|
||||
if(destroyDoor.getTownPortal().getId() == 0x80) {
|
||||
for (MapleCharacter chr : townChars) {
|
||||
MapleDoor door = chr.getMainTownDoor();
|
||||
if(door != null) {
|
||||
destroyDoor.getTownDoor().sendSpawnData(chr.getClient());
|
||||
}
|
||||
silentPartyUpdateInternal();
|
||||
}
|
||||
} finally {
|
||||
prtLock.unlock();
|
||||
}
|
||||
}
|
||||
} else if (effect.isMapChair()) {
|
||||
@@ -3994,21 +4051,86 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
return dojoStage;
|
||||
}
|
||||
|
||||
public Map<Integer, MapleDoor> getDoors() {
|
||||
chrLock.lock();
|
||||
public Collection<MapleDoor> getDoors() {
|
||||
prtLock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableMap(doors);
|
||||
return (party != null ? Collections.unmodifiableCollection(party.getDoors().values()) : (pdoor != null ? Collections.singleton(pdoor) : new LinkedHashSet<MapleDoor>()));
|
||||
} finally {
|
||||
chrLock.unlock();
|
||||
prtLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public MapleDoor getPlayerDoor() {
|
||||
prtLock.lock();
|
||||
try {
|
||||
return pdoor;
|
||||
} finally {
|
||||
prtLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public MapleDoor getMainTownDoor() {
|
||||
for (MapleDoor door : getDoors()) {
|
||||
if (door.getTownPortal().getId() == 0x80) {
|
||||
return door;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void applyPartyDoor(MapleDoor door, boolean partyUpdate) {
|
||||
prtLock.lock();
|
||||
try {
|
||||
if (!partyUpdate) {
|
||||
pdoor = door;
|
||||
}
|
||||
|
||||
if (party != null) {
|
||||
party.addDoor(id, door);
|
||||
silentPartyUpdateInternal();
|
||||
}
|
||||
} finally {
|
||||
prtLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private MapleDoor removePartyDoor(boolean partyUpdate) {
|
||||
MapleDoor ret = null;
|
||||
|
||||
prtLock.lock();
|
||||
try {
|
||||
if (party != null) {
|
||||
party.removeDoor(id);
|
||||
silentPartyUpdateInternal();
|
||||
}
|
||||
|
||||
if (!partyUpdate) {
|
||||
ret = pdoor;
|
||||
pdoor = null;
|
||||
}
|
||||
} finally {
|
||||
prtLock.unlock();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void removePartyDoor(MapleParty formerParty) { // player is no longer registered at this party
|
||||
formerParty.removeDoor(id);
|
||||
}
|
||||
|
||||
public int getEnergyBar() {
|
||||
return energybar;
|
||||
}
|
||||
|
||||
public EventInstanceManager getEventInstance() {
|
||||
return eventInstance;
|
||||
evtLock.lock();
|
||||
try {
|
||||
return eventInstance;
|
||||
} finally {
|
||||
evtLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void resetExcluded(int petId) {
|
||||
@@ -4499,23 +4621,14 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
public void resetPlayerAggro() {
|
||||
if(client.getWorldServer().unregisterDisabledServerMessage(id)) {
|
||||
client.announceServerMessage();
|
||||
}
|
||||
|
||||
setTargetHpBarHash(0);
|
||||
setTargetHpBarTime(0);
|
||||
}
|
||||
|
||||
public int getDoorSlot() {
|
||||
if(doorSlot == -1) {
|
||||
prtLock.lock();
|
||||
try {
|
||||
doorSlot = (party == null) ? 0 : party.getPartyDoor(this.getId());
|
||||
} finally {
|
||||
prtLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
return doorSlot;
|
||||
}
|
||||
|
||||
public MapleMiniGame getMiniGame() {
|
||||
return miniGame;
|
||||
}
|
||||
@@ -4750,7 +4863,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
merchant.saveItems(false);
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
System.out.println("Error while saving Hired Merchant items.");
|
||||
FilePrinter.printError(FilePrinter.EXCEPTION_CAUGHT, "Error while saving " + name + "'s Hired Merchant items.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5895,9 +6008,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
ret.jobRank = rs.getInt("jobRank");
|
||||
ret.jobRankMove = rs.getInt("jobRankMove");
|
||||
|
||||
MapleInventory inv = ret.inventory[MapleInventoryType.EQUIPPED.ordinal()];
|
||||
for (Item item : equipped) {
|
||||
inv.addItemFromDB(item);
|
||||
if(equipped != null) { // players can have no equipped items at all, ofc
|
||||
MapleInventory inv = ret.inventory[MapleInventoryType.EQUIPPED.ordinal()];
|
||||
for (Item item : equipped) {
|
||||
inv.addItemFromDB(item);
|
||||
}
|
||||
}
|
||||
} catch (SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
@@ -6641,10 +6756,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
if (party != null) {
|
||||
int channel = client.getChannel();
|
||||
int mapId = getMapId();
|
||||
World wserv = Server.getInstance().getWorld(world);
|
||||
|
||||
for (MaplePartyCharacter partychar : party.getMembers()) {
|
||||
if (partychar.getMapId() == mapId && partychar.getChannel() == channel) {
|
||||
MapleCharacter other = Server.getInstance().getWorld(world).getChannel(channel).getPlayerStorage().getCharacterByName(partychar.getName());
|
||||
MapleCharacter other = wserv.getChannel(channel).getPlayerStorage().getCharacterById(partychar.getId());
|
||||
if (other != null) {
|
||||
client.announce(MaplePacketCreator.updatePartyMemberHP(other.getId(), other.getHp(), other.getMaxHpEquipped()));
|
||||
}
|
||||
@@ -7498,7 +7614,12 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
}
|
||||
|
||||
public void setEventInstance(EventInstanceManager eventInstance) {
|
||||
this.eventInstance = eventInstance;
|
||||
evtLock.lock();
|
||||
try {
|
||||
this.eventInstance = eventInstance;
|
||||
} finally {
|
||||
evtLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setExp(int amount) {
|
||||
@@ -7806,7 +7927,22 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getDoorSlot() {
|
||||
if(doorSlot != -1) return doorSlot;
|
||||
return fetchDoorSlot();
|
||||
}
|
||||
|
||||
public int fetchDoorSlot() {
|
||||
prtLock.lock();
|
||||
try {
|
||||
doorSlot = (party == null) ? 0 : party.getPartyDoor(this.getId());
|
||||
return doorSlot;
|
||||
} finally {
|
||||
prtLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setParty(MapleParty p) {
|
||||
prtLock.lock();
|
||||
try {
|
||||
@@ -8917,11 +9053,17 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
|
||||
events = null;
|
||||
party = null;
|
||||
family = null;
|
||||
client = null;
|
||||
map = null;
|
||||
|
||||
Server.getInstance().getWorld(world).registerTimedMapObject(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client = null; // clients still triggers handlers a few times after disconnecting
|
||||
map = null;
|
||||
}
|
||||
}, 5 * 60 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void logOff() {
|
||||
this.loggedIn = false;
|
||||
}
|
||||
|
||||
@@ -112,6 +112,7 @@ public class MapleClient {
|
||||
private static final Lock loginLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.CLIENT_LOGIN, true);
|
||||
private int votePoints;
|
||||
private int voteTime = -1;
|
||||
private int visibleWorlds;
|
||||
private long lastNpcClick;
|
||||
private long sessionId;
|
||||
|
||||
@@ -1268,6 +1269,16 @@ public class MapleClient {
|
||||
}
|
||||
}
|
||||
|
||||
private void announceDisableServerMessage() {
|
||||
if(!this.getWorldServer().registerDisabledServerMessage(player.getId())) {
|
||||
announce(MaplePacketCreator.serverMessage(""));
|
||||
}
|
||||
}
|
||||
|
||||
public void announceServerMessage() {
|
||||
announce(MaplePacketCreator.serverMessage(this.getChannelServer().getServerMessage()));
|
||||
}
|
||||
|
||||
public synchronized void announceBossHpBar(MapleMonster mm, final int mobHash, final byte[] packet) {
|
||||
long timeNow = System.currentTimeMillis();
|
||||
int targetHash = player.getTargetHpBarHash();
|
||||
@@ -1275,12 +1286,14 @@ public class MapleClient {
|
||||
if(mobHash != targetHash) {
|
||||
if(timeNow - player.getTargetHpBarTime() >= 5 * 1000) {
|
||||
// is there a way to INTERRUPT this annoying thread running on the client that drops the boss bar after some time at every attack?
|
||||
announceDisableServerMessage();
|
||||
announce(packet);
|
||||
|
||||
player.setTargetHpBarHash(mobHash);
|
||||
player.setTargetHpBarTime(timeNow);
|
||||
}
|
||||
} else {
|
||||
announceDisableServerMessage();
|
||||
announce(packet);
|
||||
|
||||
player.setTargetHpBarTime(timeNow);
|
||||
@@ -1311,10 +1324,8 @@ public class MapleClient {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] socket;
|
||||
try {
|
||||
socket = Server.getInstance().getIP(getWorld(), channel).split(":");
|
||||
} catch (Exception e) {
|
||||
String[] socket = Server.getInstance().getInetSocket(getWorld(), channel);
|
||||
if(socket == null) {
|
||||
announce(MaplePacketCreator.serverNotice(1, "Channel " + channel + " is currently disabled. Try another channel."));
|
||||
announce(MaplePacketCreator.enableActions());
|
||||
return;
|
||||
@@ -1387,6 +1398,15 @@ public class MapleClient {
|
||||
lastNpcClick = 0;
|
||||
}
|
||||
|
||||
public int getVisibleWorlds(){
|
||||
return visibleWorlds;
|
||||
}
|
||||
|
||||
public void requestedServerlist(int worlds) {
|
||||
visibleWorlds = worlds;
|
||||
setClickedNPC();
|
||||
}
|
||||
|
||||
public void closePlayerScriptInteractions() {
|
||||
this.removeClickedNPC();
|
||||
NPCScriptManager.getInstance().dispose(this);
|
||||
|
||||
@@ -2755,7 +2755,7 @@ public class Commands {
|
||||
}
|
||||
|
||||
public static boolean executeHeavenMsCommandLv6(Channel cserv, Server srv, MapleClient c, String[] sub) { //Admin
|
||||
MapleCharacter player = c.getPlayer();
|
||||
final MapleCharacter player = c.getPlayer();
|
||||
MapleCharacter victim;
|
||||
|
||||
switch(sub[0]) {
|
||||
@@ -2788,16 +2788,20 @@ public class Commands {
|
||||
byte worldb = Byte.parseByte(sub[1]);
|
||||
if (worldb <= (server.getWorldsSize() - 1)) {
|
||||
try {
|
||||
String[] socket = server.getIP(worldb, c.getChannel()).split(":");
|
||||
c.getWorldServer().removePlayer(player);
|
||||
player.getMap().removePlayer(player);//LOL FORGOT THIS ><
|
||||
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
|
||||
player.setWorld(worldb);
|
||||
player.saveCharToDB();//To set the new world :O (true because else 2 player instances are created, one in both worlds)
|
||||
c.announce(MaplePacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1])));
|
||||
String[] socket = server.getInetSocket(worldb, c.getChannel());
|
||||
if(socket != null) {
|
||||
c.getWorldServer().removePlayer(player);
|
||||
player.getMap().removePlayer(player);//LOL FORGOT THIS ><
|
||||
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
|
||||
player.setWorld(worldb);
|
||||
player.saveCharToDB();//To set the new world :O (true because else 2 player instances are created, one in both worlds)
|
||||
c.announce(MaplePacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1])));
|
||||
} else {
|
||||
player.message("Error when trying to change worlds, are you sure the world you are trying to warp to has the same amount of channels?");
|
||||
}
|
||||
} catch (UnknownHostException | NumberFormatException ex) {
|
||||
ex.printStackTrace();
|
||||
player.message("Error when trying to change worlds, are you sure the world you are trying to warp to has the same amount of channels?");
|
||||
player.message("Unexpected error when changing worlds, are you sure the world you are trying to warp to has the same amount of channels?");
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -2863,37 +2867,51 @@ public class Commands {
|
||||
break;
|
||||
}
|
||||
|
||||
int worldid = Integer.parseInt(sub[1]);
|
||||
final int worldid = Integer.parseInt(sub[1]);
|
||||
|
||||
int chid = Server.getInstance().addChannel(worldid);
|
||||
if(chid >= 0) {
|
||||
player.dropMessage(5, "NEW Channel " + chid + " successfully deployed on world " + worldid + ".");
|
||||
} else {
|
||||
if(chid == -3) {
|
||||
player.dropMessage(5, "Invalid worldid detected. Channel creation aborted.");
|
||||
} else if(chid == -2) {
|
||||
player.dropMessage(5, "Reached channel limit on worldid " + worldid + ". Channel creation aborted.");
|
||||
} else if(chid == -1) {
|
||||
player.dropMessage(5, "Error detected when loading the 'world.ini' file. Channel creation aborted.");
|
||||
} else {
|
||||
player.dropMessage(5, "NEW Channel failed to be deployed. Check if the needed port is already in use or other limitations are taking place.");
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int chid = Server.getInstance().addChannel(worldid);
|
||||
if(player.isLoggedinWorld()) {
|
||||
if(chid >= 0) {
|
||||
player.dropMessage(5, "NEW Channel " + chid + " successfully deployed on world " + worldid + ".");
|
||||
} else {
|
||||
if(chid == -3) {
|
||||
player.dropMessage(5, "Invalid worldid detected. Channel creation aborted.");
|
||||
} else if(chid == -2) {
|
||||
player.dropMessage(5, "Reached channel limit on worldid " + worldid + ". Channel creation aborted.");
|
||||
} else if(chid == -1) {
|
||||
player.dropMessage(5, "Error detected when loading the 'world.ini' file. Channel creation aborted.");
|
||||
} else {
|
||||
player.dropMessage(5, "NEW Channel failed to be deployed. Check if the needed port is already in use or other limitations are taking place.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
break;
|
||||
|
||||
case "addworld":
|
||||
int wid = Server.getInstance().addWorld();
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int wid = Server.getInstance().addWorld();
|
||||
|
||||
if(wid >= 0) {
|
||||
player.dropMessage(5, "NEW World " + wid + " successfully deployed.");
|
||||
} else {
|
||||
if(wid == -2) {
|
||||
player.dropMessage(5, "Error detected when loading the 'world.ini' file. World creation aborted.");
|
||||
} else {
|
||||
player.dropMessage(5, "NEW World failed to be deployed. Check if needed ports are already in use or maximum world count has been reached.");
|
||||
if(player.isLoggedinWorld()) {
|
||||
if(wid >= 0) {
|
||||
player.dropMessage(5, "NEW World " + wid + " successfully deployed.");
|
||||
} else {
|
||||
if(wid == -2) {
|
||||
player.dropMessage(5, "Error detected when loading the 'world.ini' file. World creation aborted.");
|
||||
} else {
|
||||
player.dropMessage(5, "NEW World failed to be deployed. Check if needed ports are already in use or maximum world count has been reached.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
break;
|
||||
|
||||
@@ -2903,31 +2921,50 @@ public class Commands {
|
||||
break;
|
||||
}
|
||||
|
||||
int worldId = Integer.parseInt(sub[1]);
|
||||
if(Server.getInstance().removeChannel(worldId)) {
|
||||
player.dropMessage(5, "Successfully removed a channel on World " + worldId + ". Current channel count: " + Server.getInstance().getWorld(worldId).getChannelsSize() + ".");
|
||||
} else {
|
||||
player.dropMessage(5, "Failed to remove last Channel on world " + worldId + ". Check if either that world exists or there are people currently playing there.");
|
||||
}
|
||||
final int worldId = Integer.parseInt(sub[1]);
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(Server.getInstance().removeChannel(worldId)) {
|
||||
if(player.isLoggedinWorld()) {
|
||||
player.dropMessage(5, "Successfully removed a channel on World " + worldId + ". Current channel count: " + Server.getInstance().getWorld(worldId).getChannelsSize() + ".");
|
||||
}
|
||||
} else {
|
||||
if(player.isLoggedinWorld()) {
|
||||
player.dropMessage(5, "Failed to remove last Channel on world " + worldId + ". Check if either that world exists or there are people currently playing there.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
break;
|
||||
|
||||
case "removeworld":
|
||||
int rwid = Server.getInstance().getWorldsSize() - 1;
|
||||
final int rwid = Server.getInstance().getWorldsSize() - 1;
|
||||
if(rwid <= 0) {
|
||||
player.dropMessage(5, "Unable to remove world 0.");
|
||||
break;
|
||||
}
|
||||
|
||||
if(Server.getInstance().removeWorld()) {
|
||||
player.dropMessage(5, "Successfully removed a world. Current world count: " + Server.getInstance().getWorldsSize() + ".");
|
||||
} else {
|
||||
if(rwid < 0) {
|
||||
player.dropMessage(5, "No registered worlds to remove.");
|
||||
} else {
|
||||
player.dropMessage(5, "Failed to remove world " + rwid + ". Check if there are people currently playing there.");
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(Server.getInstance().removeWorld()) {
|
||||
if(player.isLoggedinWorld()) {
|
||||
player.dropMessage(5, "Successfully removed a world. Current world count: " + Server.getInstance().getWorldsSize() + ".");
|
||||
}
|
||||
} else {
|
||||
if(player.isLoggedinWorld()) {
|
||||
if(rwid < 0) {
|
||||
player.dropMessage(5, "No registered worlds to remove.");
|
||||
} else {
|
||||
player.dropMessage(5, "Failed to remove world " + rwid + ". Check if there are people currently playing there.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -222,7 +222,6 @@ public class MaplePet extends Item {
|
||||
}
|
||||
|
||||
owner.getMap().broadcastMessage(MaplePacketCreator.commandResponse(owner.getId(), slot, type, enjoyed));
|
||||
if(owner.getMount() != null) owner.getMap().broadcastMessage(MaplePacketCreator.updateMount(owner.getId(), owner.getMount(), false));
|
||||
saveToDb();
|
||||
|
||||
Item petz = owner.getInventory(MapleInventoryType.CASH).getItem(getPosition());
|
||||
|
||||
@@ -355,63 +355,66 @@ public class DueyProcessor {
|
||||
c.disconnect(true, false);
|
||||
return;
|
||||
}
|
||||
|
||||
int finalcost = mesos + fee;
|
||||
boolean send = false;
|
||||
if (c.getPlayer().getMeso() >= finalcost) {
|
||||
int accid = getAccIdFromCNAME(recipient, true);
|
||||
if (accid != -1) {
|
||||
if (accid != c.getAccID()) {
|
||||
send = true;
|
||||
} else {
|
||||
if (accid == c.getAccID()) {
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_SAMEACC_ERROR.getCode()));
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_NAME_DOES_NOT_EXIST.getCode()));
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_NOT_ENOUGH_MESOS.getCode()));
|
||||
}
|
||||
|
||||
MapleClient rClient = null;
|
||||
|
||||
int channel = c.getWorldServer().find(recipient);
|
||||
if (channel > -1) {
|
||||
Channel rcserv = c.getWorldServer().getChannel(channel);
|
||||
rClient = rcserv.getPlayerStorage().getCharacterByName(recipient).getClient();
|
||||
}
|
||||
|
||||
if (send) {
|
||||
if (inventId > 0) {
|
||||
MapleInventoryType inv = MapleInventoryType.getByType(inventId);
|
||||
Item item = c.getPlayer().getInventory(inv).getItem(itemPos);
|
||||
if (item != null && c.getPlayer().getItemQuantity(item.getItemId(), false) >= amount) {
|
||||
c.getPlayer().gainMeso(-finalcost, false);
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_SUCCESSFULLY_SENT.getCode()));
|
||||
|
||||
if (ItemConstants.isRechargeable(item.getItemId())) {
|
||||
MapleInventoryManipulator.removeFromSlot(c, inv, itemPos, item.getQuantity(), true);
|
||||
} else {
|
||||
MapleInventoryManipulator.removeFromSlot(c, inv, itemPos, amount, true, false);
|
||||
}
|
||||
|
||||
MapleKarmaManipulator.toggleKarmaFlagToUntradeable(item);
|
||||
addItemToDB(item, amount, mesos - getFee(mesos), c.getPlayer().getName(), getAccIdFromCNAME(recipient, false));
|
||||
} else {
|
||||
if (item != null) {
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_INCORRECT_REQUEST.getCode()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_NAME_DOES_NOT_EXIST.getCode()));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_NOT_ENOUGH_MESOS.getCode()));
|
||||
return;
|
||||
}
|
||||
|
||||
MapleClient rClient = null;
|
||||
int channel = c.getWorldServer().find(recipient);
|
||||
if (channel > -1) {
|
||||
Channel rcserv = c.getWorldServer().getChannel(channel);
|
||||
if(rcserv != null) {
|
||||
MapleCharacter rChr = rcserv.getPlayerStorage().getCharacterByName(recipient);
|
||||
if(rChr != null) {
|
||||
rClient = rChr.getClient();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inventId > 0) {
|
||||
MapleInventoryType inv = MapleInventoryType.getByType(inventId);
|
||||
Item item = c.getPlayer().getInventory(inv).getItem(itemPos);
|
||||
if (item != null && c.getPlayer().getItemQuantity(item.getItemId(), false) >= amount) {
|
||||
c.getPlayer().gainMeso(-finalcost, false);
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_SUCCESSFULLY_SENT.getCode()));
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_SUCCESSFULLY_SENT.getCode()));
|
||||
|
||||
addMesoToDB(mesos - getFee(mesos), c.getPlayer().getName(), getAccIdFromCNAME(recipient, false));
|
||||
}
|
||||
if (ItemConstants.isRechargeable(item.getItemId())) {
|
||||
MapleInventoryManipulator.removeFromSlot(c, inv, itemPos, item.getQuantity(), true);
|
||||
} else {
|
||||
MapleInventoryManipulator.removeFromSlot(c, inv, itemPos, amount, true, false);
|
||||
}
|
||||
|
||||
if (rClient != null && rClient.isLoggedIn() && !rClient.getPlayer().isAwayFromWorld()) {
|
||||
showDueyNotification(rClient, rClient.getPlayer());
|
||||
MapleKarmaManipulator.toggleKarmaFlagToUntradeable(item);
|
||||
addItemToDB(item, amount, mesos - getFee(mesos), c.getPlayer().getName(), getAccIdFromCNAME(recipient, false));
|
||||
} else {
|
||||
if (item != null) {
|
||||
c.announce(MaplePacketCreator.sendDueyMSG(DueyProcessor.Actions.TOCLIENT_SEND_INCORRECT_REQUEST.getCode()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
|
||||
if (rClient != null && rClient.isLoggedIn() && !rClient.getPlayer().isAwayFromWorld()) {
|
||||
showDueyNotification(rClient, rClient.getPlayer());
|
||||
}
|
||||
} finally {
|
||||
c.unlockClient();
|
||||
|
||||
Reference in New Issue
Block a user