Compare commits

...

8 Commits

Author SHA1 Message Date
Ponk
a8807f1ef0 Merge pull request #164 from P0nk/fix/custom-charset-string #patch
Fix writeString not fully respecting charset
2023-03-02 18:13:52 +01:00
P0nk
10945927c1 Fix writeString not fully respecting charset
The string would be cut short for charsets
with characters more than 1 byte.
2023-03-02 18:11:41 +01:00
Ponk
ab25f698da Merge pull request #160 from P0nk/bug/110/zenumist-portal #patch
Fix top portal in Zenumist Society (261000010) not working for GM
2023-02-17 00:48:33 +01:00
P0nk
b30e03ffb3 Fix portal in Zenumist society not working for GM chr 2023-02-17 00:42:33 +01:00
P0nk
82157c7bd1 Flatten ChangeMapHandler 2023-02-16 23:46:13 +01:00
Ponk
eb10f02ac3 Merge pull request #159 from P0nk/bug/158/id-command #patch
Fix !id command not working for certain types
2023-02-04 20:02:33 +01:00
P0nk
b1ef94ef60 Fix handbook file encoding
All handbook files are now UTF-8
2023-02-04 19:49:54 +01:00
P0nk
f89392b476 Refactor IdCommand 2023-02-04 19:46:09 +01:00
8 changed files with 243 additions and 195 deletions

View File

@@ -264,7 +264,7 @@
5160006 - Sparkling Eyes - On the KeyConfig, configure this expression on a button of your choice. Press the button and watch your character display sparkling eyes.
5160007 - Flaming - On the KeyConfig, configure this expression on a button of your choice. Press the button and watch your character display the look of rage.
5160008 - Ray - On the KeyConfig, configure this expression on a button of your choice. Press the button and watch your character display beaming eyes.
5160009 - Goo Goo - On the KeyConfig, configure this expression on a button of your choice. Press the button and watch your character display the look of awesome!!!
5160009 - Goo Goo - On the KeyConfig, configure this expression on a button of your choice. Press the button and watch your character display the look of <EFBFBD>awesome!!!<EFBFBD>
5160010 - Whoa Whoa - On the KeyConfig, configure this expression on a button of your choice. Press the button and watch your character display the look of being flustered.
5160011 - Constant Sigh - On the KeyConfig, configure this expression on a button of your choice. Press the button and watch your character display the thinking look.
5160012 - Drool - On the KeyConfig, configure this expression on a button of your choice. Press the button and watch your character act like falling asleep.
@@ -479,9 +479,9 @@
5610001 - Vega's Spell(60%) - This winning spell from Vega enables a 90% success rate on a 60% scroll. Please check the scroll description to confirm that Vega's Spell is available for the scroll you choose.
5590000 - High-Five Stamp - Can equip items that are 5 levels above your current level.
5021026 - Gift Box Throwing Stars - A gift box that can be freely thrown around. Using the #cThrowing Star# will create an orbital effect.\n\nThis item cannot be deleted.
5010073 - Miss Popular - Well, lookie here. Someones certainly become popular with the guys. Turn this effect on and off by assigning it to a shortcut key from the keyboard settings menu.
5010073 - Miss Popular - Well, lookie here. Someone<EFBFBD>s certainly become popular with the guys. Turn this effect on and off by assigning it to a shortcut key from the keyboard settings menu.
5010074 - Mr. Popular - Well, lookie here. Someones certainly become popular with the girls. Turn this effect on and off by assigning it to a shortcut key from the keyboard settings menu.
5010074 - Mr. Popular - Well, lookie here. Someone<EFBFBD>s certainly become popular with the girls. Turn this effect on and off by assigning it to a shortcut key from the keyboard settings menu.
5240027 - Golden Drumstick - A drumstick that can be consumed only by #cBaby Tiger#. It recovers hunger and #cincreases Closeness by 100.#
5390005 - Cute Tiger Messenger - Shout to everyone in the world your character is on with this megaphone. Now available with your avatar on the top of everyone's screen! Comes with a tiger background for your avatar.

View File

@@ -1779,8 +1779,8 @@
4032103 - The Lost Treasure - The lost treasure that was stolen by the Master of Disguise who brazenly entered Ereve. Let's take it back to Irena.
4032104 - The Lost Treasure - The lost treasure that was stolen by the Master of Disguise who brazenly entered Ereve. Let's take it back to Eckhart.
4032105 - The Lost Treasure - The lost treasure that was stolen by the Master of Disguise who brazenly entered Ereve. Let's take it back to Hawkeye.
4000209 - Co-ke Slimes Bell - The bell of Co-ke Slime that has been taken off.
4000210 - Co-ke Pigs Ribbon - A piece of Co-ke Pigs ribbon.
4000209 - Co-ke Slime<EFBFBD>s Bell - The bell of Co-ke Slime that has been taken off.
4000210 - Co-ke Pig<EFBFBD>s Ribbon - A piece of Co-ke Pig<EFBFBD>s ribbon.
4000211 - Coca-Cola Cube - A cube with a drawing of a Coca-Cola bottle on it.
4000212 - CokePLAY Cube - A cube with the CokePLAY symbol.
4000213 - Coca-Cola Card - A card with a drawing of Coca-Cola.
@@ -1802,10 +1802,10 @@
4001151 - Happy Valley - Happy Valley
4001152 - Ariant - Ariant
4001153 - Magatia - Magatia
4031832 - Sophelias Portrait - A portrait of Sophelia.
4031832 - Sophelia<EFBFBD>s Portrait - A portrait of Sophelia.
4031833 - Pumpkin Juice - A juice made with pumpkin. It is very fragrant.
4031834 - Perfect Tool - The most perfect tool for making dolls.
4031835 - Lyudmillas Earring - The earrings that Lyudmilla lost. They shine with brilliance.
4031835 - Lyudmilla<EFBFBD>s Earring - The earrings that Lyudmilla lost. They shine with brilliance.
4031836 - Score - The score that Lyudmilla asked for. No one knows what kind of music is in it.
4031837 - Dumped Doll - A doll that Sophelia used to cherish a long time ago. She threw it away when she got a new doll.
4031838 - Piece of Cloth - A small piece of cloth. If you drag and drop it onto the rag doll, the doll will be completed bit by bit.
@@ -1893,26 +1893,26 @@
4032127 - Proof of Ability - The Proof of Ability that is required to learn a new skill. This proof signifies that you are ready to learn a new skill.
4032128 - Proof of Ability - The Proof of Ability that is required to learn a new skill. This proof signifies that you are ready to learn a new skill.
4032129 - Proof of Ability - The Proof of Ability that is required to learn a new skill. This proof signifies that you are ready to learn a new skill.
4032130 - Pig Doll - An adorable doll that resembles a pig. However, something doesn't seem right
4032131 - Pig Doll - An adorable doll that resembles a pig. However, something doesn't seem right
4032130 - Pig Doll - An adorable doll that resembles a pig. However, something doesn't seem right<EFBFBD>
4032131 - Pig Doll - An adorable doll that resembles a pig. However, something doesn't seem right<EFBFBD>
4032132 - Roca's Mission Report - A mission report written by Roca, the Agent for Henesys. This compiles a list of events that have taken place recently.
4032136 - Bubbling Doll - An adorable doll that was designed based on Bubbling, but something doesn't seem right. The way it smiles just seems a bit off, as if it has hidden agenda.
4032137 - Bubbling Doll - An adorable doll that was designed based on Bubbling, but something doesn't seem right. The way it smiles just seems a bit off, as if it has hidden agenda.
4032138 - Bubbling Doll - An adorable doll that was designed based on Bubbling, but something doesn't seem right. It's intears.
4032138 - Bubbling Doll - An adorable doll that was designed based on Bubbling, but something doesn't seem right. It's in<EFBFBD>tears.
4032139 - Old Key - An old, rusty key that Mr. Pickall has been looking for.
4032140 - Bubbling Doll - An adorable doll that was designed based on Bubbling, but something doesn't seem right. It's intears.
4032140 - Bubbling Doll - An adorable doll that was designed based on Bubbling, but something doesn't seem right. It's in<EFBFBD>tears.
4032141 - Mattias' Mission Report - A mission report written by Roca, the Agent for Kerning City. This compiles a list of events that have taken place recently.
4032142 - Clear Tree Sap - A clear tree sap that can only be found at the very top of the skyscraping trees. Accompanied by the freshest green scent.
4032143 - Fruit - A fruit picked from plants near Henesys.
4032144 - Hersha's Mission Report - A mission report written by Hersha, the Agent for Ellinia. This compiles a list of events that have taken place recently.
4032145 - Detector - A detector made to detect any forces of darkness. Take this to the 10 Boogies.
4032146 - Wooden Mask Doll - An adorable doll modeled after the Wooden Mask, but something doesn't seem right
4032147 - Rocky Mask Doll - An adorable doll modeled after the Stone Mask, but something doesn't seem right
4032146 - Wooden Mask Doll - An adorable doll modeled after the Wooden Mask, but something doesn't seem right<EFBFBD>
4032147 - Rocky Mask Doll - An adorable doll modeled after the Stone Mask, but something doesn't seem right<EFBFBD>
4032148 - Detector - A detector created with the sole purpose of detecting the Puppeteer's movements. We put it to good use, so let's return it to Neinheart.
4032149 - 10 Boogies' Mission Report - A mission report written by 10 Boogies, the Agents for Perion. This compiles a list of events that have taken place recently.
4032178 - Hack Attempt - A record that shows that Chief Grays tried to hack into the system.
4032179 - Ereve Investigation Permit - A permitt that allows one to investigate every part of Ereve. When the Red Alert is on, this permit is the only way you can roam freely around Ereve.
4032190 - Orange Mushroom Doll - An adorable doll modeled after the Orange Mushroom, but something doesn't seem right
4032190 - Orange Mushroom Doll - An adorable doll modeled after the Orange Mushroom, but something doesn't seem right<EFBFBD>
4032196 - Concentrated Formula: Step 1 - A formula concentrated with effective and potent ingredients. The first formula used to raise Mimiana and Mimio
4032197 - Concentrated Formula: Step 2 - A formula concentrated with effective and potent ingredients. The second formula used to raise Mimiana and Mimio.
4032198 - Concentrated Formula: Step 3 - A formula concentrated with effective and potent ingredients. The third formula used to raise Mimiana and Mimio.
@@ -2048,16 +2048,16 @@
4032270 - Glistening Sunlight - Glistening sunlight filled with the feeling of spring.
4032271 - Pure Small Sprout - A fragrant new sprout filled with the energies of spring. Used as an ingredient for Pure Perfume.
4032272 - Stationery of Longing - Pink stationary that's rumored to return a favorable response if used to send a letter to a secret crush.
4032273 - Pencil of Courage X 10 - A pencil that's used to write things you dont have the courage to say.
4032273 - Pencil of Courage X 10 - A pencil that's used to write things you don<EFBFBD>t have the courage to say.
4032275 - Pure Normal Sprout - A fragrant new sprout filled with the energies of spring. Used as an ingredient for Pure Perfume.
4032276 - Pure Sprout - A fragrant new sprout filled with the energies of spring. Used as an ingredient for Pure Perfume.
4032277 - Pure Large Sprout - A fragrant new sprout filled with the energies of spring. Used as an ingredient for Pure Perfume.
4032278 - Stationery of Deep Longing - Pink stationary that's rumored to return a favorable response if used to send a letter to a secret crush.
4032279 - Stationary of Hope and Longing - Pink stationary that's rumored to return a favorable response if used to send a letter to a secret crush.
4032280 - Letter of Love and Longing - Pink stationary that's rumored to return a favorable response if used to send a letter to a secret crush.
4032281 - Pencil of Courage X 100 - A pencil that's used to write things you dont have the courage to say.
4032282 - Pencil of Courage X 1000 - AA pencil that's used to write things you dont have the courage to say.
4032283 - Pencil of Courage X 10000 - A pencil that's used to write things you dont have the courage to say.
4032281 - Pencil of Courage X 100 - A pencil that's used to write things you don<EFBFBD>t have the courage to say.
4032282 - Pencil of Courage X 1000 - AA pencil that's used to write things you don<EFBFBD>t have the courage to say.
4032283 - Pencil of Courage X 10000 - A pencil that's used to write things you don<EFBFBD>t have the courage to say.
4032284 - Child's Broken Toy - A toy stolen from a child by a monster. It's broken and cannot be used.
4032285 - Child's Broken Toy - A toy stolen from a child by a monster. It's broken and cannot be used.
4032286 - Child's Broken Toy - A toy stolen from a child by a monster. It's broken and cannot be used.

View File

@@ -1565,9 +1565,9 @@ ossyria
200090057 - Empress' Road - To Ellinia
200090058 - Empress' Road - To Ereve
200090059 - Empress' Road - To Ellinia
200010303 - Hidden Street - Elizas Garden
211040102 - Hidden Street - Snow Souls Resting Place
209000100 - Happy Village - Cliffs Hut
200010303 - Hidden Street - Eliza<EFBFBD>s Garden
211040102 - Hidden Street - Snow Soul<EFBFBD>s Resting Place
209000100 - Happy Village - Cliff<EFBFBD>s Hut
219000000 - Hidden Street - Coke Town
219000001 - Hidden Street - Coke Town Sundry Goods Shop
219000002 - Hidden Street - House of Pouch
@@ -2863,7 +2863,7 @@ etc
980027000 - Goldrich's Maze - Maze of Erosion
980027100 - Goldrich's Maze - Maze of Erosion
980027200 - Goldrich's Maze - Maze of Erosion
980027300 - Goldrich's Maze - Beginning of the Maze
980027300 - Goldrich's Maze - Beginning of the Maze<EFBFBD>
980027400 - Goldrich's Maze - Monster's Maze
980027500 - Goldrich's Maze - Monster's Maze
980027600 - Goldrich's Maze - Monster's Maze
@@ -2944,7 +2944,7 @@ etc
980027001 - Goldrich's Maze - Maze of Erosion
980027101 - Goldrich's Maze - Maze of Erosion
980027201 - Goldrich's Maze - Maze of Erosion
980027301 - Goldrich's Maze - Beginning of the Maze
980027301 - Goldrich's Maze - Beginning of the Maze<EFBFBD>
980027401 - Goldrich's Maze - Monster's Maze
980027501 - Goldrich's Maze - Monster's Maze
980027601 - Goldrich's Maze - Monster's Maze
@@ -3025,7 +3025,7 @@ etc
980027002 - Goldrich's Maze - Maze of Erosion
980027102 - Goldrich's Maze - Maze of Erosion
980027202 - Goldrich's Maze - Maze of Erosion
980027302 - Goldrich's Maze - Beginning of the Maze
980027302 - Goldrich's Maze - Beginning of the Maze<EFBFBD>
980027402 - Goldrich's Maze - Monster's Maze
980027502 - Goldrich's Maze - Monster's Maze
980027602 - Goldrich's Maze - Monster's Maze
@@ -3349,7 +3349,7 @@ etc
913040007 - Opening - Cygnus Knights
913040008 - Opening - Cygnus Knights
913040009 - Opening - Cygnus Knights
920020000 - Hidden Street - Elizas Garden
920020000 - Hidden Street - Eliza<EFBFBD>s Garden
922020300 - Hidden Street - Origin of the Clock Tower
922220000 - Hidden Street - Gloomy Forest
922230000 - Hidden Street - Lunar World

View File

@@ -192,7 +192,7 @@
3010058 - WorldEnd - You will recover 50 HP every 10 seconds. Perhaps, as you recline, you will find the answer to many of life's questions.
3010057 - BloodyRose - You will recover 50 HP every 10 seconds. You will experience the might of a conqueror after recovery.
3010060 - Noblesse Chair - A chair makes you feel like you're sitting in the lap of luxury. Also recovers 50 HP every 10 seconds.
3010061 - Underneath the Maple Tree - A white chair created to celebrate Maple Story's 6th Anniversary. Sit on it to restore 35 HP and 10 MP every 10 seconds.
3010061 - Underneath the Maple Tree<EFBFBD> - A white chair created to celebrate Maple Story's 6th Anniversary. Sit on it to restore 35 HP and 10 MP every 10 seconds.
3010062 - Bamboo Chair - A chair that restores HP every 10 seconds when used. It's very strong since it was made from bamboo grown on Rien.
3010063 - Moon and Star Cushion - A pretty cushion shaped like a moon. Recovers 60 HP every 10 seconds.
3010064 - Male Desert Rabbit Cushion - 60 HP is restored every 10 seconds if you lean back on this cute Male Desert Rabbit Cushion.

View File

@@ -3,68 +3,121 @@ package client.command.commands.gm2;
import client.Character;
import client.Client;
import client.command.Command;
import constants.game.NpcChat;
import constants.id.NpcId;
import server.ThreadManager;
import tools.exceptions.IdTypeNotSupportedException;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class IdCommand extends Command {
{
setDescription("Search in handbook.");
}
private final static int MAX_SEARCH_HITS = 100;
private final Map<String, String> handbookDirectory = typeFilePaths();
private final Map<String, HandbookFileItems> typeItems = new ConcurrentHashMap<>();
private final Map<String, String> handbookDirectory = new HashMap<>();
private final Map<String, HashMap<String, String>> itemMap = new HashMap<>();
private Map<String, String> typeFilePaths() {
return Map.ofEntries(
Map.entry("map", "handbook/Map.txt"),
Map.entry("etc", "handbook/Etc.txt"),
Map.entry("npc", "handbook/NPC.txt"),
Map.entry("use", "handbook/Use.txt"),
Map.entry("weapon", "handbook/Equip/Weapon.txt") // TODO add more into this
);
}
public IdCommand() {
handbookDirectory.put("map", "handbook/Map.txt");
handbookDirectory.put("etc", "handbook/Etc.txt");
handbookDirectory.put("npc", "handbook/NPC.txt");
handbookDirectory.put("use", "handbook/Use.txt");
handbookDirectory.put("weapon", "handbook/Equip/Weapon.txt"); // TODO add more into this
private static class HandbookFileItems {
private final List<HandbookItem> items;
public HandbookFileItems(List<String> fileLines) {
this.items = fileLines.stream()
.map(this::parseLine)
.filter(Predicate.not(Objects::isNull))
.toList();
}
private HandbookItem parseLine(String line) {
if (line == null) {
return null;
}
String[] splitLine = line.split(" - ", 2);
if (splitLine.length < 2 || splitLine[1].isBlank()) {
return null;
}
return new HandbookItem(splitLine[0], splitLine[1]);
}
public List<HandbookItem> search(String query) {
if (query == null || query.isBlank()) {
return Collections.emptyList();
}
return items.stream()
.filter(item -> item.matches(query))
.toList();
}
}
private record HandbookItem(String id, String name) {
public HandbookItem {
Objects.requireNonNull(id);
Objects.requireNonNull(name);
}
public boolean matches(String query) {
if (query == null) {
return false;
}
return this.name.toLowerCase().contains(query.toLowerCase());
}
}
@Override
public void execute(Client client, final String[] params) {
final Character player = client.getPlayer();
final Character chr = client.getPlayer();
if (params.length < 2) {
player.yellowMessage("Syntax: !id <type> <query>");
chr.yellowMessage("Syntax: !id <type> <query>");
return;
}
final String queryItem = joinStringArr(Arrays.copyOfRange(params, 1, params.length), " ");
player.yellowMessage("Querying for entry... May take some time... Please try to refine your search.");
final String type = params[0].toLowerCase();
final String[] queryItems = Arrays.copyOfRange(params, 1, params.length);
final String query = String.join(" ", queryItems);
chr.yellowMessage("Querying for entry... May take some time... Please try to refine your search.");
Runnable queryRunnable = () -> {
try {
populateIdMap(params[0].toLowerCase());
populateIdMap(type);
Map<String, String> resultList = fetchResults(itemMap.get(params[0]), queryItem);
StringBuilder sb = new StringBuilder();
final HandbookFileItems handbookFileItems = typeItems.get(type);
if (handbookFileItems == null) {
return;
}
final List<HandbookItem> searchHits = handbookFileItems.search(query);
if (resultList.size() > 0) {
int count = 0;
for (Map.Entry<String, String> entry : resultList.entrySet()) {
sb.append(String.format("Id for %s is: #b%s#k", entry.getKey(), entry.getValue()) + "\r\n");
if (++count > 100) {
break;
}
}
sb.append(String.format("Results found: #r%d#k | Returned: #b%d#k/100 | Refine search query to improve time.", resultList.size(), count) + "\r\n");
player.getAbstractPlayerInteraction().npcTalk(NpcId.MAPLE_ADMINISTRATOR, sb.toString());
if (!searchHits.isEmpty()) {
String searchHitsText = searchHits.stream()
.limit(MAX_SEARCH_HITS)
.map(item -> "Id for %s is: #b%s#k".formatted(item.name, item.id))
.collect(Collectors.joining(NpcChat.NEW_LINE));
int hitsCount = Math.min(searchHits.size(), MAX_SEARCH_HITS);
String summaryText = "Results found: #r%d#k | Returned: #b%d#k/100 | Refine search query to improve time.".formatted(searchHits.size(), hitsCount);
String fullText = searchHitsText + NpcChat.NEW_LINE + summaryText;
chr.getAbstractPlayerInteraction().npcTalk(NpcId.MAPLE_ADMINISTRATOR, fullText);
} else {
player.yellowMessage(String.format("Id not found for item: %s, of type: %s.", queryItem, params[0]));
chr.yellowMessage(String.format("Id not found for item: %s, of type: %s.", query, type));
}
} catch (IdTypeNotSupportedException e) {
player.yellowMessage("Your query type is not supported.");
chr.yellowMessage("Your query type is not supported.");
} catch (IOException e) {
player.yellowMessage("Error reading file, please contact your administrator.");
chr.yellowMessage("Error reading file, please contact your administrator.");
}
};
@@ -72,40 +125,15 @@ public class IdCommand extends Command {
}
private void populateIdMap(String type) throws IdTypeNotSupportedException, IOException {
if (!handbookDirectory.containsKey(type)) {
final String filePath = handbookDirectory.get(type);
if (filePath == null) {
throw new IdTypeNotSupportedException();
}
itemMap.put(type, new HashMap<>());
try (BufferedReader reader = Files.newBufferedReader(Path.of(handbookDirectory.get(type)))) {
String line;
while ((line = reader.readLine()) != null) {
String[] row = line.split(" - ", 2);
if (row.length == 2) {
itemMap.get(type).put(row[1].toLowerCase(), row[0]);
}
}
if (typeItems.containsKey(type)) {
return;
}
}
private String joinStringArr(String[] arr, String separator) {
if (null == arr || 0 == arr.length) {
return "";
}
StringBuilder sb = new StringBuilder(256);
sb.append(arr[0]);
for (int i = 1; i < arr.length; i++) {
sb.append(separator).append(arr[i]);
}
return sb.toString();
}
private Map<String, String> fetchResults(Map<String, String> queryMap, String queryItem) {
Map<String, String> results = new HashMap<>();
for (String item : queryMap.keySet()) {
if (item.indexOf(queryItem) != -1) {
results.put(item, queryMap.get(item));
}
}
return results;
final List<String> fileLines = Files.readAllLines(Path.of(filePath));
typeItems.put(type, new HandbookFileItems(fileLines));
}
}

View File

@@ -0,0 +1,8 @@
package constants.game;
public final class NpcChat {
public static final String NEW_LINE = "\r\n";
private NpcChat() {}
}

View File

@@ -71,8 +71,9 @@ public class ByteBufOutPacket implements OutPacket {
@Override
public void writeString(String value) {
writeShort((short) value.length());
writeBytes(value.getBytes(CharsetConstants.CHARSET));
byte[] bytes = value.getBytes(CharsetConstants.CHARSET);
writeShort(bytes.length);
writeBytes(bytes);
}
@Override

View File

@@ -58,126 +58,137 @@ public final class ChangeMapHandler extends AbstractPacketHandler {
if (chr.getTrade() != null) {
Trade.cancelTrade(chr, Trade.TradeResult.UNSUCCESSFUL_ANOTHER_MAP);
}
if (p.available() == 0) { //Cash Shop :)
if (!chr.getCashShop().isOpened()) {
c.disconnect(false, false);
return;
boolean enteringMapFromCashShop = p.available() == 0;
if (enteringMapFromCashShop) {
enterFromCashShop(c);
return;
}
if (chr.getCashShop().isOpened()) {
c.disconnect(false, false);
return;
}
try {
p.readByte(); // 1 = from dying 0 = regular portals
int targetMapId = p.readInt();
String portalName = p.readString();
Portal portal = chr.getMap().getPortal(portalName);
p.readByte();
boolean wheel = p.readByte() > 0;
boolean chasing = p.readByte() == 1 && chr.isGM() && p.available() == 2 * Integer.BYTES;
if (chasing) {
chr.setChasing(true);
chr.setPosition(new Point(p.readInt(), p.readInt()));
}
String[] socket = c.getChannelServer().getIP().split(":");
chr.getCashShop().open(false);
chr.setSessionTransitionState();
try {
c.sendPacket(PacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1])));
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
} else {
if (chr.getCashShop().isOpened()) {
c.disconnect(false, false);
return;
}
try {
p.readByte(); // 1 = from dying 0 = regular portals
int targetid = p.readInt();
String startwp = p.readString();
Portal portal = chr.getMap().getPortal(startwp);
p.readByte();
boolean wheel = p.readByte() > 0;
if (targetMapId != -1) {
if (!chr.isAlive()) {
MapleMap map = chr.getMap();
if (wheel && chr.haveItemWithId(ItemId.WHEEL_OF_FORTUNE, false)) {
// thanks lucasziron (lziron) for showing revivePlayer() triggering by Wheel
boolean chasing = p.readByte() == 1 && chr.isGM();
if (chasing) {
chr.setChasing(true);
chr.setPosition(new Point(p.readInt(), p.readInt()));
}
InventoryManipulator.removeById(c, InventoryType.CASH, ItemId.WHEEL_OF_FORTUNE, 1, true, false);
chr.sendPacket(PacketCreator.showWheelsLeft(chr.getItemQuantity(ItemId.WHEEL_OF_FORTUNE, false)));
if (targetid != -1) {
if (!chr.isAlive()) {
MapleMap map = chr.getMap();
if (wheel && chr.haveItemWithId(ItemId.WHEEL_OF_FORTUNE, false)) {
// thanks lucasziron (lziron) for showing revivePlayer() triggering by Wheel
InventoryManipulator.removeById(c, InventoryType.CASH, ItemId.WHEEL_OF_FORTUNE, 1, true, false);
chr.sendPacket(PacketCreator.showWheelsLeft(chr.getItemQuantity(ItemId.WHEEL_OF_FORTUNE, false)));
chr.updateHp(50);
chr.changeMap(map, map.findClosestPlayerSpawnpoint(chr.getPosition()));
} else {
boolean executeStandardPath = true;
if (chr.getEventInstance() != null) {
executeStandardPath = chr.getEventInstance().revivePlayer(chr);
chr.updateHp(50);
chr.changeMap(map, map.findClosestPlayerSpawnpoint(chr.getPosition()));
} else {
boolean executeStandardPath = true;
if (chr.getEventInstance() != null) {
executeStandardPath = chr.getEventInstance().revivePlayer(chr);
}
if (executeStandardPath) {
chr.respawn(map.getReturnMapId());
}
}
} else {
if (chr.isGM()) {
MapleMap to = chr.getWarpMap(targetMapId);
chr.changeMap(to, to.getPortal(0));
} else {
final int divi = chr.getMapId() / 100;
boolean warp = false;
if (divi == 0) {
if (targetMapId == 10000) {
warp = true;
}
if (executeStandardPath) {
chr.respawn(map.getReturnMapId());
} else if (divi == 20100) {
if (targetMapId == MapId.LITH_HARBOUR) {
c.sendPacket(PacketCreator.lockUI(false));
c.sendPacket(PacketCreator.disableUI(false));
warp = true;
}
} else if (divi == 9130401) { // Only allow warp if player is already in Intro map, or else = hack
if (targetMapId == MapId.EREVE || targetMapId / 100 == 9130401) { // Cygnus introduction
warp = true;
}
} else if (divi == 9140900) { // Aran Introduction
if (targetMapId == MapId.ARAN_TUTO_2 || targetMapId == MapId.ARAN_TUTO_3 || targetMapId == MapId.ARAN_TUTO_4 || targetMapId == MapId.ARAN_INTRO) {
warp = true;
}
} else if (divi / 10 == 1020) { // Adventurer movie clip Intro
if (targetMapId == 1020000) {
warp = true;
}
} else if (divi / 10 >= 980040 && divi / 10 <= 980045) {
if (targetMapId == MapId.WITCH_TOWER_ENTRANCE) {
warp = true;
}
}
} else {
if (chr.isGM()) {
MapleMap to = chr.getWarpMap(targetid);
if (warp) {
final MapleMap to = chr.getWarpMap(targetMapId);
chr.changeMap(to, to.getPortal(0));
} else {
final int divi = chr.getMapId() / 100;
boolean warp = false;
if (divi == 0) {
if (targetid == 10000) {
warp = true;
}
} else if (divi == 20100) {
if (targetid == MapId.LITH_HARBOUR) {
c.sendPacket(PacketCreator.lockUI(false));
c.sendPacket(PacketCreator.disableUI(false));
warp = true;
}
} else if (divi == 9130401) { // Only allow warp if player is already in Intro map, or else = hack
if (targetid == MapId.EREVE || targetid / 100 == 9130401) { // Cygnus introduction
warp = true;
}
} else if (divi == 9140900) { // Aran Introduction
if (targetid == MapId.ARAN_TUTO_2 || targetid == MapId.ARAN_TUTO_3 || targetid == MapId.ARAN_TUTO_4 || targetid == MapId.ARAN_INTRO) {
warp = true;
}
} else if (divi / 10 == 1020) { // Adventurer movie clip Intro
if (targetid == 1020000) {
warp = true;
}
} else if (divi / 10 >= 980040 && divi / 10 <= 980045) {
if (targetid == MapId.WITCH_TOWER_ENTRANCE) {
warp = true;
}
}
if (warp) {
final MapleMap to = chr.getWarpMap(targetid);
chr.changeMap(to, to.getPortal(0));
}
}
}
}
}
if (portal != null && !portal.getPortalStatus()) {
c.sendPacket(PacketCreator.blockedMessage(1));
if (portal != null && !portal.getPortalStatus()) {
c.sendPacket(PacketCreator.blockedMessage(1));
c.sendPacket(PacketCreator.enableActions());
return;
}
if (chr.getMapId() == MapId.FITNESS_EVENT_LAST) {
chr.getFitness().resetTimes();
} else if (chr.getMapId() == MapId.OLA_EVENT_LAST_1 || chr.getMapId() == MapId.OLA_EVENT_LAST_2) {
chr.getOla().resetTimes();
}
if (portal != null) {
if (portal.getPosition().distanceSq(chr.getPosition()) > 400000) {
c.sendPacket(PacketCreator.enableActions());
return;
}
if (chr.getMapId() == MapId.FITNESS_EVENT_LAST) {
chr.getFitness().resetTimes();
} else if (chr.getMapId() == MapId.OLA_EVENT_LAST_1 || chr.getMapId() == MapId.OLA_EVENT_LAST_2) {
chr.getOla().resetTimes();
}
if (portal != null) {
if (portal.getPosition().distanceSq(chr.getPosition()) > 400000) {
c.sendPacket(PacketCreator.enableActions());
return;
}
portal.enterPortal(c);
} else {
c.sendPacket(PacketCreator.enableActions());
}
} catch (Exception e) {
e.printStackTrace();
portal.enterPortal(c);
} else {
c.sendPacket(PacketCreator.enableActions());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void enterFromCashShop(Client c) {
final Character chr = c.getPlayer();
if (!chr.getCashShop().isOpened()) {
c.disconnect(false, false);
return;
}
String[] socket = c.getChannelServer().getIP().split(":");
chr.getCashShop().open(false);
chr.setSessionTransitionState();
try {
c.sendPacket(PacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1])));
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
}
}