Implemented Kites, PlayerNPCs and C. Shop Surprise & Tweaked login

Added code support for Kites.
Reviewed concurrent access issues with pet autopot.
Addressed PlayerStorage issue where characters would not be properly deregistered from channel PlayerStorage in certain situations.
Implemented harp quest (questid 3314) because of reasons.
Added SFX to signalize KC/NLC subway departing/approaching.
Changed traveling time values to work similarly to GMS.
Properly developed the PlayerNPC feature in the source.
Added autodeployable PlayerNPC system and Hall of Fame.
Solved a glitch with NLC mayor's quiz questline that would allow a player to restart the quiz as many times one would see fit.
Added a custom server flag that allows overwriting the ToT 999 mobs to a new value (technically it doesn't overwrite, rather sets the player at quest start with 999 - n credited mobs).
Fixed permanent pets expiring after a while.
Added code support for Cash Shop Surprise item.
Reviewed login handler system as a whole, protecting many exposed flaws.
Solved a bug with ULTRA_THREE_SNAILS sometimes taking wrong etc shell from inventory.
This commit is contained in:
ronancpl
2018-05-19 14:28:06 -03:00
parent 80b1776ad3
commit fca7b2adaa
5747 changed files with 225411 additions and 12868 deletions

View File

@@ -94,7 +94,7 @@ import server.maps.MapleMiniGame;
import server.maps.MaplePlayerShop;
import server.maps.MaplePlayerShopItem;
import server.maps.MapleSummon;
import server.maps.PlayerNPCs;
import server.life.MaplePlayerNPC;
import server.maps.SavedLocation;
import server.maps.SavedLocationType;
import server.partyquest.MonsterCarnival;
@@ -313,7 +313,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
private int banishMap = -1;
private int banishSp = -1;
private long banishTime = 0;
private MapleCharacter() {
useCS = false;
@@ -5111,6 +5111,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
maxmp = Math.min(30000, maxmp);
if (level == 200) {
exp.set(0);
if(ServerConstants.PLAYERNPC_AUTODEPLOY) MaplePlayerNPC.spawnPlayerNPC(GameConstants.getHallOfFameMapid(job), this);
}
recalcLocalStats();
hp = localmaxhp;
@@ -5226,11 +5227,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
} else if (level == 80) {
yellowMessage("You think you are powerful enough? Try facing horntail!");
} else if (level == 85) {
yellowMessage("Did you know? The majority of people who hit level 85 in Solaxia don't live to be 85 years old?");
yellowMessage("Did you know? The majority of people who hit level 85 in HeavenMS don't live to be 85 years old?");
} else if (level == 90) {
yellowMessage("Hey do you like the amusement park? I heard Spooky World is the best theme park around. I heard they sell cute teddy-bears.");
} else if (level == 95) {
yellowMessage("100% of people who hit level 95 in Solaxia don't live to be 95 years old.");
yellowMessage("100% of people who hit level 95 in HeavenMS don't live to be 95 years old.");
} else if (level == 100) {
yellowMessage("Mid-journey so far... You just reached level 100! Now THAT's such a feat, however to manage the 200 you will need even more passion and determination than ever! Good hunting!");
} else if (level == 105) {
@@ -5923,65 +5924,6 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
maplemount = new MapleMount(this, id, skillid);
}
public void playerNPC(MapleCharacter v, int scriptId) {
int npcId;
try {
Connection con = DatabaseConnection.getConnection();
PreparedStatement ps = con.prepareStatement("SELECT id FROM playernpcs WHERE ScriptId = ?");
ps.setInt(1, scriptId);
ResultSet rs = ps.executeQuery();
if (!rs.next()) {
rs.close();
ps = con.prepareStatement("INSERT INTO playernpcs (name, hair, face, skin, x, cy, map, ScriptId, Foothold, rx0, rx1) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
ps.setString(1, v.getName());
ps.setInt(2, v.getHair());
ps.setInt(3, v.getFace());
ps.setInt(4, v.getSkinColor().getId());
ps.setInt(5, getPosition().x);
ps.setInt(6, getPosition().y);
ps.setInt(7, getMapId());
ps.setInt(8, scriptId);
ps.setInt(9, getMap().getFootholds().findBelow(getPosition()).getId());
ps.setInt(10, getPosition().x + 50);
ps.setInt(11, getPosition().x - 50);
ps.executeUpdate();
rs = ps.getGeneratedKeys();
rs.next();
npcId = rs.getInt(1);
ps.close();
ps = con.prepareStatement("INSERT INTO playernpcs_equip (NpcId, equipid, equippos) VALUES (?, ?, ?)");
ps.setInt(1, npcId);
for (Item equip : getInventory(MapleInventoryType.EQUIPPED)) {
int position = Math.abs(equip.getPosition());
if ((position < 12 && position > 0) || (position > 100 && position < 112)) {
ps.setInt(2, equip.getItemId());
ps.setInt(3, equip.getPosition());
ps.addBatch();
}
}
ps.executeBatch();
ps.close();
rs.close();
ps = con.prepareStatement("SELECT * FROM playernpcs WHERE ScriptId = ?");
ps.setInt(1, scriptId);
rs = ps.executeQuery();
rs.next();
PlayerNPCs pn = new PlayerNPCs(rs);
for (Channel channel : Server.getInstance().getChannelsFromWorld(world)) {
MapleMap m = channel.getMapFactory().getMap(getMapId());
m.broadcastMessage(MaplePacketCreator.spawnPlayerNPC(pn));
m.broadcastMessage(MaplePacketCreator.getPlayerNPC(pn));
m.addMapObject(pn);
}
}
ps.close();
rs.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void playerDead() {
cancelAllBuffs(false);
dispelDebuffs();
@@ -6840,7 +6782,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
}
public void sendPolice(int greason, String reason, int duration) {
announce(MaplePacketCreator.sendPolice(String.format("You have been blocked by the#b %s Police for %s.#k", "Solaxia", reason)));
announce(MaplePacketCreator.sendPolice(String.format("You have been blocked by the#b %s Police for %s.#k", "HeavenMS", reason)));
this.isbanned = true;
TimerManager.getInstance().schedule(new Runnable() {
@Override
@@ -7966,7 +7908,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
public void autoban(String reason) {
this.ban(reason);
announce(MaplePacketCreator.sendPolice(String.format("You have been blocked by the#b %s Police for HACK reason.#k", "Solaxia")));
announce(MaplePacketCreator.sendPolice(String.format("You have been blocked by the#b %s Police for HACK reason.#k", "HeavenMS")));
TimerManager.getInstance().schedule(new Runnable() {
@Override
public void run() {

View File

@@ -112,7 +112,7 @@ public class MapleClient {
private long lastNpcClick;
private long sessionId;
public MapleClient(MapleAESOFB send, MapleAESOFB receive, IoSession session) {
public MapleClient(MapleAESOFB send, MapleAESOFB receive, IoSession session) {
this.send = send;
this.receive = receive;
this.session = session;
@@ -914,10 +914,9 @@ public class MapleClient {
} catch (final Exception e) {
FilePrinter.printError(FilePrinter.ACCOUNT_STUCK, e);
} finally {
getChannelServer().removePlayer(player);
if (!this.serverTransition) {
worlda.removePlayer(player);
//getChannelServer().removePlayer(player); already being done
player.saveCooldowns();
player.saveToDB(true);
@@ -925,10 +924,11 @@ public class MapleClient {
player.empty(false);
}
player.logOff();
}
else {
player.saveCooldowns();
player.saveToDB();
} else {
getChannelServer().removePlayer(player);
player.saveCooldowns();
player.saveToDB();
}
player = null;
}

View File

@@ -64,7 +64,7 @@ public enum MapleJob {
final int jobid;
final static int maxId = 22; // maxId = (EVAN / 100);
private MapleJob(int id) {
jobid = id;
}

View File

@@ -142,7 +142,7 @@ public class MapleQuestStatus {
}
public void setProgress(int id, String pr) {
progress.put(id, pr);
progress.put(id, pr);
}
public boolean madeProgress() {

View File

@@ -68,6 +68,7 @@ import server.life.MapleLifeFactory;
import server.life.MapleMonster;
import server.life.MapleMonsterInformationProvider;
import server.life.MapleNPC;
import server.life.MaplePlayerNPC;
import server.life.MobSkill;
import server.life.MobSkillFactory;
import server.life.MonsterDropEntry;
@@ -350,6 +351,22 @@ public class Commands {
MapleCharacter player = c.getPlayer();
switch(sub[0]) {
case "wow":
MaplePlayerNPC.multicastSpawnPlayerNPC(player.getMapId(), player.getWorld());
break;
case "out":
MaplePlayerNPC.removeAllPlayerNPC();
break;
case "er":
MaplePlayerNPC.spawnPlayerNPC(player.getMapId(), player);
break;
case "re":
MaplePlayerNPC.removePlayerNPC(player);
break;
case "help":
case "commands":
case "playercommands":
@@ -369,7 +386,7 @@ public class Commands {
case "time":
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone(ServerConstants.TIMEZONE));
player.yellowMessage("Solaxia Server Time: " + dateFormat.format(new Date()));
player.yellowMessage("HeavenMS Server Time: " + dateFormat.format(new Date()));
break;
case "credits":
@@ -2069,10 +2086,6 @@ public class Commands {
}
break;
case "energy":
System.out.println(c.getPlayer().getDojoEnergy());
break;
case "maxenergy":
c.getPlayer().setDojoEnergy(10000);
c.announce(MaplePacketCreator.getEnergy("energy", 10000));
@@ -2599,16 +2612,15 @@ public class Commands {
player.getMap().spawnMonsterOnGroundBelow(monster, player.getPosition());
break;
/*
case "playernpc":
if (sub.length < 3){
player.yellowMessage("Syntax: !playernpc <playername> <npcid>");
player.yellowMessage("Syntax: !playernpc <playername>");
break;
}
player.playerNPC(c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]), Integer.parseInt(sub[2]));
MaplePlayerNPC.spawnPlayerNPC(player.getMapId(), player.getPosition(), c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]));
break;
*/
default:
return false;
@@ -2930,7 +2942,7 @@ public class Commands {
else return true;
}
public static boolean executeSolaxiaPlayerCommand(MapleClient c, String[] sub, char heading) {
public static boolean executeHeavenMSPlayerCommand(MapleClient c, String[] sub, char heading) {
Channel cserv = c.getChannelServer();
Server srv = Server.getInstance();

View File

@@ -26,6 +26,7 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import server.MapleItemInformationProvider;
public class Item implements Comparable<Item> {
@@ -153,7 +154,7 @@ public class Item implements Comparable<Item> {
}
public void setExpiration(long expire) {
this.expiration = expire;
this.expiration = !ItemConstants.isPermanentItem(id) ? expire : ItemConstants.isPet(id) ? Long.MAX_VALUE : -1;
}
public int getSN() {

View File

@@ -550,4 +550,12 @@ public class MapleInventory implements Iterable<Item> {
lock.unlock();
}
}
public void lockInventory() {
lock.lock();
}
public void unlockInventory() {
lock.unlock();
}
}