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:
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public enum MapleJob {
|
||||
|
||||
final int jobid;
|
||||
final static int maxId = 22; // maxId = (EVAN / 100);
|
||||
|
||||
|
||||
private MapleJob(int id) {
|
||||
jobid = id;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -550,4 +550,12 @@ public class MapleInventory implements Iterable<Item> {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void lockInventory() {
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
public void unlockInventory() {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user