diff --git a/README.txt b/README.txt
index 0d5ee42075..0e7af8572f 100644
--- a/README.txt
+++ b/README.txt
@@ -2,12 +2,16 @@ MapleSolaxiaV2
Freelance developer: Ronan C. P. Lana
-Credits are to be given to the original MapleSolaxia staff and other colaborators, as just some minor changes/patches on the game were applied by myself, in which some of them diverged from the original v83 patch contents.
+Credits are to be given too to Nexon(Duh!), the original MapleSolaxia staff, and other colaborators, as just some changes/patches on the game were applied by myself, in which some of them diverged from the original v83 patch contents.
+
+Regarding distributability and usage of the code presented here: like it was before, this MapleStory server is open-source. By that, it is meant that anyone is free to install, use, modify and redistribute the contents, as long as there is no kind of commercial trading involved and the credits to the original creators are maintained within the codes.
This is a NetBeans 8.0.2 Project. This means that it's easier to install the project via opening the server project folder inside NetBeans' IDE. Once installed, build this project on your machine and run the server using the "launch.bat" application.
In this project, many gameplay-wise issues generated from either the original WZ files and the server sources have been partially or completely solved. From now on, considering the use of some of this system's edited WZ and server-side files should be a great asset for new private server instances. My opinion, though! Refer to "README_wzchanges.txt" for more information on what have been changed from Nexon's v83 WZ files.
+The main objective of this project is to try as best as possible to recreate what once was the original MapleStory v83, while adding up some flavors that spices up the gameplay. In other words, to aim to get the best of the MapleStory of that era.
+
---- Download items ----
Server files: https://github.com/ronancpl/MapleSolaxiaV2
@@ -17,7 +21,7 @@ Client files & general tools: https://drive.google.com/drive/folders/0BzDsHSr-0V
The following link teaches on how to install a MapleStory v83 private server, however IT DIFFERS on what is used here: http://forum.ragezone.com/f428/maplestory-private-server-v83-741739/
-Use that link ONLY AS AN ORIENTATION on where here things become ambiguous.
+Use that link ONLY AS AN ORIENTATION on where here things start to become ambiguous.
Firstly, install all the general tools required to run the server:
- WampServer2.0i.exe -> recipient of the server.
@@ -61,8 +65,7 @@ Now it must be done CAREFULLY:
- File -> Open Script... -> Browse for "C:\MapleSolaxia\sql" -> db_database.sql, and execute it.
- File -> Open Script... -> Browse for "C:\MapleSolaxia\sql" -> db_drops.sql, and execute it.
-Now it is OPTIONAL, you don't need to run it if you don't want, as it will simply change some NPC shops to set
-some new goods, not present in the original MapleStory, to sell:
+Now it is OPTIONAL, you don't need to run it if you don't want, as it will simply change some NPC shops to set some new goods, not present in the original MapleStory, to sell:
- File -> Open Script... -> Browse for "C:\MapleSolaxia\sql" -> db_shopupdate.sql, and execute it.
At the end of the execution of these SQLs, you should have installed a database schema named "maplesolaxia". REGISTER YOUR FIRST ACCOUNT to be used in-game by creating manually a entry on the table "accounts" at that database with a login and a password.
@@ -120,7 +123,7 @@ As an example of client WZ editing, consider the MobBookUpdate project I develop
At this point, the server-side Monster Book has been updated with the current state of the database's drop data. Then, open HaRepacker 4.2.2 and load "String.wz" from "C:\Nexon\MapleStory". Drop the "MonsterBook.img" node by removing it from the hierarchy tree, then (CONTRARY TO WHAT SHOULD BE DONE NORMALLY!) import the server's "MonsterBook.img.xml".
-Take note that this is absolutely dangerous if done unwary. Once the MonsterBook does not hold client specific data in it's node contents, importing the XML causes no harm at all. However, try not to remove/reimport nodes from WZ files, as it may cause data losses. Use the HaRepacker's UI instead to make the changes.
+Take note that this is absolutely dangerous if done unwary. Once the MonsterBook.img does not hold client specific data in it's node contents, importing the XML causes no harm at all. However, try not to remove/reimport nodes from WZ files, as it may cause data losses. Use the HaRepacker's UI instead to make the changes.
Save the changes and overwrite the older WZ on the MapleStory client folder.
diff --git a/mychanges_ptbr.txt b/mychanges_ptbr.txt
index 5385b8ae22..9fc8206cda 100644
--- a/mychanges_ptbr.txt
+++ b/mychanges_ptbr.txt
@@ -178,4 +178,7 @@ Nova PQ: Boss Rush PQ.
Correção de situações nas PQs Ellin e Pirate.
26 Abril 2017,
-Adição de Happyville, via Rooney.
\ No newline at end of file
+Adição de Happyville, via Rooney.
+Correção: mapas com "everlast" fazendo os itens dropados sumirem.
+Correção: itens dropados na área dos NPCs Snowman não podem ser pegos por outros jogadores.
+Correção: bug no par de comandos unban/ban não permitindo IP de cliente voltar a reconectar ao jogo.
\ No newline at end of file
diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
index 497fc6e88e..e4eefaaf95 100644
--- a/nbproject/private/private.xml
+++ b/nbproject/private/private.xml
@@ -3,16 +3,11 @@
- file:/C:/Nexon/MapleSolaxia/scripts/npc/world0/2002000.js
- file:/C:/Nexon/MapleSolaxia/scripts/npc/world0/1022101.js
- file:/C:/Nexon/MapleSolaxia/src/server/maps/MapleMapItem.java
- file:/C:/Nexon/MapleSolaxia/scripts/npc/world0/9000020.js
- file:/C:/Nexon/MapleSolaxia/src/server/maps/SavedLocationType.java
- file:/C:/Nexon/MapleSolaxia/sql/db_database.sql
+ file:/C:/Nexon/MapleSolaxia/scripts/npc/world0/2133000.js
file:/C:/Nexon/MapleSolaxia/src/client/MapleCharacter.java
- file:/C:/Nexon/MapleSolaxia/src/net/server/channel/handlers/ItemPickupHandler.java
- file:/C:/Nexon/MapleSolaxia/src/server/maps/MapleMap.java
- file:/C:/Nexon/MapleSolaxia/src/server/MapleInventoryManipulator.java
+ file:/C:/Nexon/MapleSolaxia/scripts/npc/world0/9020000.js
+ file:/C:/Nexon/MapleSolaxia/src/constants/ServerConstants.java
+ file:/C:/Nexon/MapleSolaxia/src/server/maps/MapleReactor.java
diff --git a/scripts/npc/world0/9000036.js b/scripts/npc/world0/9000036.js
index afeb6c1842..5b2fb31306 100644
--- a/scripts/npc/world0/9000036.js
+++ b/scripts/npc/world0/9000036.js
@@ -42,7 +42,7 @@ var maxEqp = 0;
function start() {
cm.getPlayer().setCS(true);
- var selStr = "Hello, I am the #bAccessory NPC Crafter#k! My works are widely recognized to be too fine, to the point which all my items mimic not only the appearance but too the attributes of them! Everything I charge is some 'ingredients' to make them and, of course, a fee for my services. On what kind of equipment will you take a look?#b";
+ var selStr = "Hello, I am the #bAccessory NPC Crafter#k! My works are widely recognized to be too fine, up to the point at which all my items mimic not only the appearance but too the attributes of them! Everything I charge is some 'ingredients' to make them and, of course, a fee for my services. On what kind of equipment are you interessed?#b";
var options = ["Pendants","Face accessories","Eye accessories","Belts & medals","Rings","#t4032496#"];
for (var i = 0; i < options.length; i++)
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
diff --git a/scripts/npc/world0/9020000.js b/scripts/npc/world0/9020000.js
index 041df3cbac..dc2044a2cd 100644
--- a/scripts/npc/world0/9020000.js
+++ b/scripts/npc/world0/9020000.js
@@ -32,7 +32,7 @@
var status;
var minLevel = 21;
var maxLevel = 255;
-var minPlayers = 3;
+var minPlayers = 1;
var maxPlayers = 6;
function start() {
diff --git a/scripts/npc/world0/9201023.js b/scripts/npc/world0/9201023.js
index 51a52a113a..640434c8ac 100644
--- a/scripts/npc/world0/9201023.js
+++ b/scripts/npc/world0/9201023.js
@@ -23,120 +23,43 @@
*9201023 - Nana(K)
*@author Jvlaple
*/
-var status = -1;
-
-
+
function start() {
- cm.sendOk("Your skills have been added!");
- action(1, 0, 0);
+ cm.sendOk("Hi, I'm Nana the love fairy... Hows it going?");
+ cm.dispose();
}
-
-function action(mode, type, selection) {
- if (mode == -1) {
- cm.dispose();
- } else {
- if (mode == 0 && status == 0) {
- cm.dispose();
- return;
- }
- if (mode == 1)
- status++;
- else
- status--;
- if (cm.getPlayer().getJob().getId() > 2000) {
- if (cm.getPlayer().getSkillLevel(21001003) < 1)
- cm.teachSkill(21001003, 0, 20,-1); // Pole Arm Booster
- if (cm.getPlayer().getSkillLevel(21100004) < 1)
- cm.teachSkill(21100004,0, 20,-1); // Combo Smash
- if (cm.getPlayer().getSkillLevel(21100005) < 1)
- cm.teachSkill(21100005,0, 20,-1); // Combo Drain
- if (cm.getPlayer().getSkillLevel(21100000) < 1)
- cm.teachSkill(21100000,0, 20,-1); // Pole Arm Mastery
- if (cm.getPlayer().getSkillLevel(21100002) < 1)
- cm.teachSkill(21100002,0, 30,-1); // Final Charge
- if (cm.getPlayer().getSkillLevel(21110002) < 1)
- cm.teachSkill(21110002,0, 20,-1); // Full Swing
- if (cm.getPlayer().getSkillLevel(21110002) > 1)
- cm.teachSkill(21110007, cm.getPlayer().getSkillLevel(21110002), 20,-1); // Full Swing
- if (cm.getPlayer().getSkillLevel(21110002) > 1)
- cm.teachSkill(21110008, cm.getPlayer().getSkillLevel(21110002), 20,-1); // Full Swing
- } else if (cm.getPlayer().getJob().getId() == 232) {
- if (cm.getPlayer().getSkillLevel(2321008) < 1)
- cm.teachSkill(2321008, 0, 10,-1); // Genesis
- if (cm.getPlayer().getSkillLevel(2321006) < 1)
- cm.teachSkill(2321006, 0, 10,-1); // res
- } else if (cm.getPlayer().getJob().getId() == 112) {
- if (cm.getPlayer().getSkillLevel(1121006) < 1)
- cm.teachSkill(1121006, 0, 10,-1); // pali rush
- if (cm.getPlayer().getSkillLevel(1121002) < 1)
- cm.teachSkill(1121002, 0, 10,-1); // power stance
- } else if (cm.getPlayer().getJob().getId() == 122) {
- if (cm.getPlayer().getSkillLevel(1221007) < 1)
- cm.teachSkill(1221007, 0, 10,-1); // hero rush
- if (cm.getPlayer().getSkillLevel(1221002) < 1)
- cm.teachSkill(1221002, 0, 10,-1); // power stance
- } else if (cm.getPlayer().getJob().getId() == 132) {
- if (cm.getPlayer().getSkillLevel(1320006) < 1)
- cm.teachSkill(1320006, 0, 10,-1); // Berzerk
- if (cm.getPlayer().getSkillLevel(1321003) < 1)
- cm.teachSkill(1321003, 0, 10,-1); // DrK Rush
- if (cm.getPlayer().getSkillLevel(1321002) < 1)
- cm.teachSkill(1321002, 0, 10,-1); // power stance
- } else if (cm.getPlayer().getJob().getId() == 312) {
- if (cm.getPlayer().getSkillLevel(3121008) < 1)
- cm.teachSkill(3121008, 0, 10,-1); // Concentrate
- } else if (cm.getPlayer().getJob().getId() == 512) {
- if (cm.getPlayer().getSkillLevel(5121003) < 1)
- cm.teachSkill(5121003, 0, 10,-1); // super transformation
- if (cm.getPlayer().getSkillLevel(5121004) < 1)
- cm.teachSkill(5121004, 0, 10,-1); // demo
- if (cm.getPlayer().getSkillLevel(5121005) < 1)
- cm.teachSkill(5121005, 0, 10,-1); // snatch
- } else if (cm.getPlayer().getJob().getId() == 522) {
- if (cm.getPlayer().getSkillLevel(5221006) < 1)
- cm.teachSkill(5221006, 0, 10,-1); // ship
- if (cm.getPlayer().getSkillLevel(5221007) < 1)
- cm.teachSkill(5221007, 0, 10,-1); // cannon
- if (cm.getPlayer().getSkillLevel(5221008) < 1)
- cm.teachSkill(5221008, 0, 10,-1); // torpedo
- if (cm.getPlayer().getSkillLevel(5221009) < 1)
- cm.teachSkill(5221009, 0, 10,-1); // hypno
- if (cm.getPlayer().getSkillLevel(5221003) < 1)
- cm.teachSkill(5221003, 0, 10,-1); // air strike
- } else if (cm.getPlayer().getJob().getId() == 422) {
- if (cm.getPlayer().getSkillLevel(4221001) < 1)
- cm.teachSkill(4221001, 0, 10,-1); // assassinate
- if (cm.getPlayer().getSkillLevel(4221006) < 1)
- cm.teachSkill(4221006, 0, 10,-1); // smoke screen
- } else if (cm.getPlayer().getJob().getId() == 222) {
- if (cm.getPlayer().getSkillLevel(2221007) < 1)
- cm.teachSkill(2221007, 0, 10,-1); // blizzard
- } else if (cm.getPlayer().getJob().getId() == 212) {
- if (cm.getPlayer().getSkillLevel(2121007) < 1)
- cm.teachSkill(2121007, 0, 10,-1); // meteor
-
- }
- cm.dispose();
- /*
- if (cm.getPlayer().getMarriageQuestLevel() == 1 || cm.getPlayer().getMarriageQuestLevel() == 52) {
- if (!cm.haveItem(4000015, 40)) {
- if (status == 0) {
- cm.sendNext("Hey, you look like you need proofs of love? I can get them for you.");
- } else if (status == 1) {
- cm.sendNext("All you have to do is bring me 40 #bHorned Mushroom Caps#k.");
- cm.dispose();
- }
- } else {
- if (status == 0) {
- cm.sendNext("Wow, you were quick! Heres the proof of love...");
- cm.gainItem(4000015, -40)
- cm.gainItem(4031367, 1);
- cm.dispose();
- }
- }
- } else {
- cm.sendOk("Hi, I'm Nana the love fairy... Hows it going?");
- cm.dispose();
- }*/
- }
-}
\ No newline at end of file
+//
+//function action(mode, type, selection) {
+// if (mode == -1) {
+// cm.dispose();
+// } else {
+// if (mode == 0 && status == 0) {
+// cm.dispose();
+// return;
+// }
+// if (mode == 1)
+// status++;
+// else
+// status--;
+// if (cm.getPlayer().getMarriageQuestLevel() == 1 || cm.getPlayer().getMarriageQuestLevel() == 52) {
+// if (!cm.haveItem(4000083, 20)) {
+// if (status == 0) {
+// cm.sendNext("Hey, you look like you need proofs of love? I can get them for you.");
+// } else if (status == 1) {
+// cm.sendNext("All you have to do is bring me 20 #bJr. Sentinel Pieces.#k.");
+// cm.dispose();
+// }
+// } else {
+// if (status == 0) {
+// cm.sendNext("Wow, you were quick! Heres the proof of love...");
+// cm.gainItem(4000083, -20)
+// cm.gainItem(4031369, 1);
+// cm.dispose();
+// }
+// }
+// } else {
+// cm.sendOk("Hi, I'm Nana the love fairy... Hows it going?");
+// cm.dispose();
+// }
+// }
+//}
\ No newline at end of file
diff --git a/sql/db_database.sql b/sql/db_database.sql
index c9579cd9fa..754ed2c808 100644
--- a/sql/db_database.sql
+++ b/sql/db_database.sql
@@ -12990,6 +12990,7 @@ CREATE TABLE IF NOT EXISTS `inventoryitems` (
CREATE TABLE IF NOT EXISTS `ipbans` (
`ipbanid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(40) NOT NULL DEFAULT '',
+ `aid` varchar(40) DEFAULT NULL,
PRIMARY KEY (`ipbanid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
@@ -13015,6 +13016,7 @@ CREATE TABLE IF NOT EXISTS `keymap` (
CREATE TABLE IF NOT EXISTS `macbans` (
`macbanid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`mac` varchar(30) NOT NULL,
+ `aid` varchar(40) DEFAULT NULL,
PRIMARY KEY (`macbanid`),
UNIQUE KEY `mac_2` (`mac`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
diff --git a/src/client/MapleCharacter.java b/src/client/MapleCharacter.java
index 314a09233e..8457f2bf60 100644
--- a/src/client/MapleCharacter.java
+++ b/src/client/MapleCharacter.java
@@ -615,7 +615,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
if (ps != null && !ps.isClosed()) {
ps.close();
}
- if (rs != null && !rs.isClosed()) {
+ if (rs != null && !rs.isClosed()) {
rs.close();
}
} catch (SQLException e) {
@@ -2030,6 +2030,27 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
return id;
}
+ public static int getAccountIdByName(String name) {
+ try {
+ int id;
+ try (PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT accountid FROM characters WHERE name = ?")) {
+ ps.setString(1, name);
+ try (ResultSet rs = ps.executeQuery()) {
+ if (!rs.next()) {
+ rs.close();
+ ps.close();
+ return -1;
+ }
+ id = rs.getInt("accountid");
+ }
+ }
+ return id;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return -1;
+ }
+
public static int getIdByName(String name) {
try {
int id;
diff --git a/src/client/MapleClient.java b/src/client/MapleClient.java
index b90159a091..5f7da28688 100644
--- a/src/client/MapleClient.java
+++ b/src/client/MapleClient.java
@@ -366,7 +366,7 @@ public class MapleClient {
filtered.add(rs.getString("filter"));
}
}
- try (PreparedStatement ps = con.prepareStatement("INSERT INTO macbans (mac) VALUES (?)")) {
+ try (PreparedStatement ps = con.prepareStatement("INSERT INTO macbans (mac, aid) VALUES (?, ?)")) {
for (String mac : macs) {
boolean matched = false;
for (String filter : filtered) {
@@ -377,6 +377,7 @@ public class MapleClient {
}
if (!matched) {
ps.setString(1, mac);
+ ps.setString(2, String.valueOf(getAccID()));
ps.executeUpdate();
}
}
diff --git a/src/client/command/Commands.java b/src/client/command/Commands.java
index 4ea8a5e8df..10d1261b65 100644
--- a/src/client/command/Commands.java
+++ b/src/client/command/Commands.java
@@ -1266,9 +1266,17 @@ public class Commands {
player.updateSingleStat(MapleStat.LUK, x);
} else if (sub[0].equals("unban")) {
try {
- try (PreparedStatement p = DatabaseConnection.getConnection().prepareStatement("UPDATE accounts SET banned = -1 WHERE id = " + MapleCharacter.getIdByName(sub[1]))) {
- p.executeUpdate();
- }
+ Connection con = DatabaseConnection.getConnection();
+ int aid = MapleCharacter.getAccountIdByName(sub[1]);
+
+ PreparedStatement p = con.prepareStatement("UPDATE accounts SET banned = -1 WHERE id = " + aid);
+ p.executeUpdate();
+
+ p = con.prepareStatement("DELETE FROM ipbans WHERE aid = " + aid);
+ p.executeUpdate();
+
+ p = con.prepareStatement("DELETE FROM macbans WHERE aid = " + aid);
+ p.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
player.message("Failed to unban " + sub[1]);
@@ -1291,8 +1299,10 @@ public class Commands {
try {
Connection con = DatabaseConnection.getConnection();
if (ip.matches("/[0-9]{1,3}\\..*")) {
- ps = con.prepareStatement("INSERT INTO ipbans VALUES (DEFAULT, ?)");
+ ps = con.prepareStatement("INSERT INTO ipbans VALUES (DEFAULT, ?, ?)");
ps.setString(1, ip);
+ ps.setString(2, String.valueOf(target.getClient().getAccID()));
+
ps.executeUpdate();
ps.close();
}
diff --git a/src/constants/ServerConstants.java b/src/constants/ServerConstants.java
index 66c22d74d1..c268cee21f 100644
--- a/src/constants/ServerConstants.java
+++ b/src/constants/ServerConstants.java
@@ -49,7 +49,7 @@ public class ServerConstants {
//public static final boolean USE_ULTRA_THREE_SNAILS = true;
public static final boolean USE_ADD_SLOTS_BY_LEVEL = true; //slots are added each 20 levels.
public static final boolean USE_ADD_RATES_BY_LEVEL = true; //rates are added each 20 levels.
- public static final int USE_EQUIPMNT_LVLUP = 7; //all equips lvlup at max level as N, set 0 to disable.
+ public static final int USE_EQUIPMNT_LVLUP = 7; //Nope, not working yet. //all equips lvlup at max level as N, set 0 to disable.
public static final int FAME_GAIN_BY_QUEST = 4; //fame gain each N quest completes, set 0 to disable.
public static final int SCROLL_CHANCE_RATE = 10; //number of tries for success on a scroll, set 0 for default.
diff --git a/src/net/server/channel/handlers/NPCTalkHandler.java b/src/net/server/channel/handlers/NPCTalkHandler.java
index e2e961bb00..889da416d0 100644
--- a/src/net/server/channel/handlers/NPCTalkHandler.java
+++ b/src/net/server/channel/handlers/NPCTalkHandler.java
@@ -21,7 +21,6 @@
*/
package net.server.channel.handlers;
-import net.server.channel.handlers.DueyHandler;
import client.MapleClient;
import constants.ServerConstants;
import net.AbstractMaplePacketHandler;
@@ -43,6 +42,8 @@ public final class NPCTalkHandler extends AbstractMaplePacketHandler {
MapleMapObject obj = c.getPlayer().getMap().getMapObject(oid);
if (obj instanceof MapleNPC) {
MapleNPC npc = (MapleNPC) obj;
+ if(ServerConstants.USE_DEBUG == true) c.getPlayer().dropMessage(5, "Talking to NPC " + npc.getId());
+
if (npc.getId() == 9010009) { //is duey
if(System.currentTimeMillis() - c.getPlayer().getDuey() < ServerConstants.BLOCK_DUEY_RACE_COND)
return;