Revamped buff system + skill cd/buff schedule rework

Completely rearranged buff system (system can smartly check for the best
statup to take effect for it's duration, or the server can be flagged to
act as usual). Refactored scheduling system for buffs expiration and
cooldowns to use one single thread per player rather than one per
instance.
This commit is contained in:
ronancpl
2017-09-22 19:09:56 -03:00
parent 1ffcf47f79
commit 9c72ce1e3a
104 changed files with 1321 additions and 583 deletions
+44 -36
View File
@@ -1,6 +1,7 @@
MapleSolaxiaV2 # MapleSolaxiaV2
---
Freelance developer: Ronan C. P. Lana ## Freelancer developer: Ronan C. P. Lana
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. 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.
@@ -12,25 +13,28 @@ In this project, many gameplay-wise issues generated from either the original WZ
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. 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 ---- ---
### Download items
Server files: https://github.com/ronancpl/MapleSolaxiaV2 Server files: https://github.com/ronancpl/MapleSolaxiaV2
Client files & general tools: https://drive.google.com/drive/folders/0BzDsHSr-0V4MYVJ0TWIxd05hYUk Client files & general tools: https://drive.google.com/drive/folders/0BzDsHSr-0V4MYVJ0TWIxd05hYUk
---- Preparing the ambient ---- ---
### Preparing the ambient
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/ 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 start to 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: Firstly, install all the general tools required to run the server:
- WampServer2.0i.exe -> recipient of the server. * WampServer2.0i.exe -> recipient of the server.
- hamachi.msi -> used for establishing a tunnelling route for the server/client communication. * hamachi.msi -> used for establishing a tunnelling route for the server/client communication.
- mysql-workbench-gpl-5.2.39-win32 -> MySQL server component, will store the server's DB. * mysql-workbench-gpl-5.2.39-win32 -> MySQL server component, will store the server's DB.
Now install the Java 7 Development Kit: Now install the Java 7 Development Kit:
- jdk-7u79-windows-x64.exe * jdk-7u79-windows-x64.exe
- netbeans-8.0.2-javase-windows.exe -> It's a NetBeans project, use other IDE at your own risk. * netbeans-8.0.2-javase-windows.exe -> It's a NetBeans project, use other IDE at your own risk.
Overwrite whenever prompted with the JAR files under "jce_policy-7/UnlimitedJCEPolicy" in these Java folders: Overwrite whenever prompted with the JAR files under "jce_policy-7/UnlimitedJCEPolicy" in these Java folders:
C:\Program Files\Java\jre7\lib C:\Program Files\Java\jre7\lib
@@ -54,7 +58,8 @@ For Hamachi:
Try opening it. It's that simple. Try opening it. It's that simple.
Hamachi is optional, though. You don't have to install Hamachi if you want to make the server just for use on your own machine. However, if you want to let other players access your server, consider alternatively using port-forwarding methods. Hamachi is optional, though. You don't have to install Hamachi if you want to make the server just for use on your own machine. However, if you want to let other players access your server, consider alternatively using port-forwarding methods.
---- Installing the SERVER ---- ---
### Installing the SERVER
Set the "MapleSolaxia" folder on a place of your preference. It is recommended for use "C:\Nexon\MapleSolaxia". Set the "MapleSolaxia" folder on a place of your preference. It is recommended for use "C:\Nexon\MapleSolaxia".
@@ -62,11 +67,11 @@ Setting up the SQL: open MySQL Query Browser, and define these parameters at sta
Server Host: localhost Port: 3306 Username: root Server Host: localhost Port: 3306 Username: root
Now it must be done CAREFULLY: Now it must be done CAREFULLY:
- File -> Open Script... -> Browse for "C:\MapleSolaxia\sql" -> db_database.sql, and execute it. 1. 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. 2. 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. 3. 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. 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.
@@ -78,45 +83,47 @@ Inside the project, you may encounter some code errors. These happens because yo
Finally, select "Clean and Build project" to build the JAR file for the MapleStory server. Once done, make sure both WampServer and Hamachi are on and functioning, and then execute "launch.bat" on the root of the project. If no errors were raised from this action, your MapleStory server is now online. Finally, select "Clean and Build project" to build the JAR file for the MapleStory server. Once done, make sure both WampServer and Hamachi are on and functioning, and then execute "launch.bat" on the root of the project. If no errors were raised from this action, your MapleStory server is now online.
---- Installing the CLIENT ---- ---
### Installing the CLIENT
The client's set-up is quite straightforward: The client's set-up is quite straightforward:
- From "ManagerMsv83.exe", install MapleStory on your folder of preference (e.g. "C:\Nexon\MapleStory") and follow their instructions. 1. From "ManagerMsv83.exe", install MapleStory on your folder of preference (e.g. "C:\Nexon\MapleStory") and follow their instructions.
- Once done, erase these files: "HShield" (folder), "ASPLauncher.exe", "MapleStory.exe" and "patcher.exe". 2. Once done, erase these files: "HShield" (folder), "ASPLauncher.exe", "MapleStory.exe" and "patcher.exe".
- Extract into the client folder the "localhost.exe" from Localhostv83. 3. Extract into the client folder the "localhost.exe" from Localhostv83.
- Overwrite the original WZ files with the ones provided from "client_wz" folder on the Google Drive. 4. Overwrite the original WZ files with the ones provided from "client_wz" folder on the Google Drive.
If you are not using "localhost" as the target IP on the server's config file, you will need to HEX-EDIT "localhost.exe" to fetch your IP. Track down all IP locations by searching for "Text String" "127.0.0.1", and applying the changes wherever it fits. If you are not using "localhost" as the target IP on the server's config file, you will need to HEX-EDIT "localhost.exe" to fetch your IP. Track down all IP locations by searching for "Text String" "127.0.0.1", and applying the changes wherever it fits.
To hex-edit, install the Neo Hex Editor from "free-hex-editor-neo.exe" and follow their instructions. Once done, open "localhost.exe" for editing and overwrite the IP values under the 3 addresses. Save the changes and exit the editor. To hex-edit, install the Neo Hex Editor from "free-hex-editor-neo.exe" and follow their instructions. Once done, open "localhost.exe" for editing and overwrite the IP values under the 3 addresses. Save the changes and exit the editor.
Open the "localhost.exe" client. If by any means the program did not open, and checking que server log your ping has been listened and you are using Windows 8 or 10, it probably might be some compatibility issue. Extract "lolwut.exe" from "lolwut-v0.01.rar" and place it on the MapleStory client folder ("C:\Nexon\MapleStory"). Your "localhost.exe" property settings must follow these: Open the "localhost.exe" client. If by any means the program did not open, and checking que server log your ping has been listened and you are using Windows 8 or 10, it probably might be some compatibility issue. Extract "lolwut.exe" from "lolwut-v0.01.rar" and place it on the MapleStory client folder ("C:\Nexon\MapleStory"). Your "localhost.exe" property settings must follow these:
- Run in compatibility mode: Windows 7; * Run in compatibility mode: Windows 7;
- Unchecked reduced color mode; * Unchecked reduced color mode;
- 640 x 480 resolution; * 640 x 480 resolution;
- Unchecked disable display on high DPI settings; * Unchecked disable display on high DPI settings;
- Run as an administrator; * Run as an administrator;
- Opening "lolwut.exe", use Fraysa's method. * Opening "lolwut.exe", use Fraysa's method.
Important: should the client being refused to connect to the game server, it may be because firewall issues. Head to the end of this file to proceed to enabling this connection with the computer's firewall. Alternatively, one can deactivate the firewall and try opening the client again. Important: should the client being refused to connect to the game server, it may be because firewall issues. Head to the end of this file to proceed to enabling this connection with the computer's firewall. Alternatively, one can deactivate the firewall and try opening the client again.
---- Important note about CLIENT EDITING ---- ---
### Important note about CLIENT EDITING
DO NOT USE the server's XMLs for reimporting into the client's WZ, it WILL generate some kind of bugs afterwards. DO NOT USE the server's XMLs for reimporting into the client's WZ, it WILL generate some kind of bugs afterwards.
- Use instead the HaRepacker 4.2.4, encryption "GMS (old)". * Use instead the HaRepacker 4.2.4, encryption "GMS (old)".
- Open the desired WZ for editing and, USING THE UI, make the desired changes. * Open the desired WZ for editing and, USING THE UI, make the desired changes.
- Save the changed WZ, overwriting the original content at the client folder. * Save the changed WZ, overwriting the original content at the client folder.
- Finally, RE-EXPORT ("Private Server..." exporting option) the changed XMLs into the server's WZ.XML files, overwriting the old contents. * Finally, RE-EXPORT ("Private Server..." exporting option) the changed XMLs into the server's WZ.XML files, overwriting the old contents.
These steps are IMPORTANT to maintain synchronization between the server and client modules. These steps are IMPORTANT to maintain synchronization between the server and client modules.
As an example of client WZ editing, consider the MobBookUpdate project I developed, for updating all reported drop data of the mobs in the game based on the current drop data on the database: As an example of client WZ editing, consider the MobBookUpdate project I developed, for updating all reported drop data of the mobs in the game based on the current drop data on the database:
- Open the MobBookUpdate project on NetBeans, located at "C:\Nexon\MapleSolaxia\MobBookUpdate", and build it. * Open the MobBookUpdate project on NetBeans, located at "C:\Nexon\MapleSolaxia\MobBookUpdate", and build it.
- At the subfolder "lib", copy the file "MonsterBook.img.xml". This is from the original WZ v83. * At the subfolder "lib", copy the file "MonsterBook.img.xml". This is from the original WZ v83.
- Paste it on the "dist" subfolder. * Paste it on the "dist" subfolder.
- Inside "dist", open the command prompt by alt+right clicking there. * Inside "dist", open the command prompt by alt+right clicking there.
- Execute "java -jar MobBookUpdate.jar". It will generate a "MonsterBook_updated.img.xml" file. * Execute "java -jar MobBookUpdate.jar". It will generate a "MonsterBook_updated.img.xml" file.
- At last, overwrite the "MonsterBook.img.xml" on "C:\Nexon\MapleSolaxia\wz\String.wz" with this file, renaming it back to "MonsterBook.img.xml". * At last, overwrite the "MonsterBook.img.xml" on "C:\Nexon\MapleSolaxia\wz\String.wz" with this file, renaming it back to "MonsterBook.img.xml".
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". 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".
@@ -124,7 +131,8 @@ Take note that this is absolutely dangerous if done unwary. Once the MonsterBook
Save the changes and overwrite the older WZ on the MapleStory client folder. Save the changes and overwrite the older WZ on the MapleStory client folder.
---- Portforwarding the SERVER ---- ---
### Portforwarding the SERVER
To use portforward, you will need to have permission to change things on the LAN router. Access yor router using the Internet browser. URLs vary accordingly with the manufacturer. To discover it, open the command prompt and type "ipconfig" and search for the "default gateway" field. The IP shown there is the URL needed to access the router. Also, look for the IP given to your machine (aka "IPv4 address" field), which will be the server one. To use portforward, you will need to have permission to change things on the LAN router. Access yor router using the Internet browser. URLs vary accordingly with the manufacturer. To discover it, open the command prompt and type "ipconfig" and search for the "default gateway" field. The IP shown there is the URL needed to access the router. Also, look for the IP given to your machine (aka "IPv4 address" field), which will be the server one.
+1 -1
View File
@@ -1,4 +1,4 @@
#Fri, 15 Sep 2017 16:29:27 -0300 #Fri, 22 Sep 2017 18:20:17 -0300
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2= C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -22,7 +22,7 @@ PQs:
* CWKPQ as Expedition-based event 100%. * CWKPQ as Expedition-based event 100%.
* Expeditions: Scarga/Horntail/Showa/Zakum/Pinkbean 100%. * Expeditions: Scarga/Horntail/Showa/Zakum/Pinkbean 100%.
* GuildPQ 100% + Guild queue with multi-lobby systems available. * GuildPQ 100% + Guild queue with multi-lobby systems available.
* Brand-new PQ: Boss Rush PQ 100%. * Brand-new PQs: BossRushPQ, CafePQ 100%.
* Mu Lung Dojo 100%. * Mu Lung Dojo 100%.
* BalrogPQ semi-functional. * BalrogPQ semi-functional.
* Capt. Latanica remade as an event (parties can now fight the boss). * Capt. Latanica remade as an event (parties can now fight the boss).
@@ -41,7 +41,7 @@ Cash & Items:
* EXP/DROP/Cosmetic Coupons 100%. * EXP/DROP/Cosmetic Coupons 100%.
* EXP/DROP coupons now appears as a buff effect when on active time. * EXP/DROP coupons now appears as a buff effect when on active time.
* Great deal of cash items functional. * Great deal of cash items functional.
* New scroll: antibanish. Used only in cases where bosses send a player back to town. * New scroll: antibanish. For use only in cases where bosses send a player back to town.
PQ potentials: PQ potentials:
* Lobby system - Multiple PQ instances on same channel. * Lobby system - Multiple PQ instances on same channel.
+11 -1
View File
@@ -534,4 +534,14 @@ Explorer mount quest como evento, com timeout e expulsa o player se o hog morre.
14 - 15 Setembro 2017, 14 - 15 Setembro 2017,
Adicionado AmoriaPQ. Adicionado AmoriaPQ.
Consertado um problema em Inventory Sort que lançava exceção caso tivesse que ordenar vetores vazios. Consertado um problema em Inventory Sort que lançava exceção caso tivesse que ordenar vetores vazios.
16 Setembro 2017,
Refatorado sistema de schedules para hired merchants. Agora o server passa a instanciar as chamadas às funções que fecham as hired merchants, ao invés de instanciar uma task para cada.
18 - 21 Setembro 2017,
Refatorado sistema de schedules para skill cooldowns e buff expiretimes.
Completamente reestruturado sistema de buffs. Nova flag permite permanência de buffs mais fortes mesmo que novos buffs surjam.
22 Setembro 2017,
Adicionado buffs para GPQ.
+4
View File
@@ -365,6 +365,10 @@
2022453 - Fireworks - The fireworks for celebrating MV's defeat. Speed +5, Physical & Magic Attack +5 for 20 min. 2022453 - Fireworks - The fireworks for celebrating MV's defeat. Speed +5, Physical & Magic Attack +5 for 20 min.
2022454 - Cygnus's Blessing - Once I completed Cygnus' Book, the spirit's power covered me and blessed me. It increased my Attack Rate by 10, Physical Defense Rate by 80 and Speed by 5 for 10 minutes. 2022454 - Cygnus's Blessing - Once I completed Cygnus' Book, the spirit's power covered me and blessed me. It increased my Attack Rate by 10, Physical Defense Rate by 80 and Speed by 5 for 10 minutes.
2022538 - Red Easter Egg - A freshly boiled egg colored in red. Recovers 400 HP and MP. 2022538 - Red Easter Egg - A freshly boiled egg colored in red. Recovers 400 HP and MP.
2023000 - Sharenian Grounds : Fortitude - From the ancient remains, an unknown blessing grants you fortitude. Increases Weapon Attack & Weapon Defense.
2023001 - Sharenian Grounds : Intellect - From the ancient remains, an unknown blessing grants you intellect. Increases Magic Attack & Magic Defense.
2023002 - Sharenian Grounds : Endurance - From the ancient remains, an unknown blessing grants you endurance. Increases Weapon Defense & Magic Defense.
2023003 - Sharenian Grounds : Swiftness - From the ancient remains, an unknown blessing grants you swiftness. Increases Accuracy & Avoidability.
2030000 - Return Scroll - Nearest Town - Returns you to the nearest town. 2030000 - Return Scroll - Nearest Town - Returns you to the nearest town.
2030001 - Return Scroll to Lith Harbor - Returns you to Lith Harbor. 2030001 - Return Scroll to Lith Harbor - Returns you to Lith Harbor.
2030002 - Return Scroll to Ellinia - Returns you to Ellinia. 2030002 - Return Scroll to Ellinia - Returns you to Ellinia.
+13 -4
View File
@@ -166,19 +166,23 @@ function setup(level, lobbyid) {
return eim; return eim;
} }
/*
function isTeamAllJobs(eim) { function isTeamAllJobs(eim) {
var eventJobs = eim.getEventPlayersJobs(); var eventJobs = eim.getEventPlayersJobs();
var rangeJobs = parseInt('111110', 2); var rangeJobs = parseInt('111110', 2);
return ((eventJobs & rangeJobs) == rangeJobs); return ((eventJobs & rangeJobs) == rangeJobs);
} }
*/
function afterSetup(eim) { function afterSetup(eim) {
var leader = em.getChannelServer().getPlayerStorage().getCharacterById(eim.getLeaderId()); var leader = em.getChannelServer().getPlayerStorage().getCharacterById(eim.getLeaderId());
if(leader != null) if(leader != null) {
eim.setProperty("guild", "" + leader.getGuildId()); eim.setProperty("guild", "" + leader.getGuildId());
}
if(isTeamAllJobs(eim)) {
var rnd = Math.floor(Math.random() * 4);
eim.applyEventPlayersItemBuff(2023000 + rnd);
}
} }
function respawnStages(eim) {} function respawnStages(eim) {}
@@ -209,7 +213,12 @@ function scheduledTimeout(eim) {
} }
} }
function playerUnregistered(eim, player) {} function playerUnregistered(eim, player) {
player.cancelEffect(2023000);
player.cancelEffect(2023001);
player.cancelEffect(2023002);
player.cancelEffect(2023003);
}
function playerExit(eim, player) { function playerExit(eim, player) {
eim.unregisterPlayer(player); eim.unregisterPlayer(player);
+2 -2
View File
@@ -26,8 +26,8 @@
*/ */
var status = 0; var status = 0;
var mhair = Array(30040, 30050, 30100, 30130, 30180, 30220, 30260, 30330, 30350, 30580); var mhair = Array(30100, 30850, 30890);
var fhair = Array(31020, 31160, 31180, 31220, 31290, 31330, 31420, 31440, 31480, 31590); var fhair = Array(31180, 31420, 31870, 31400, 31880, 31820, 31860, 31420, 31940, 34000, 31890);
var hairnew = Array(); var hairnew = Array();
function start() { function start() {
+1 -1
View File
@@ -92,7 +92,7 @@ function writeSolaxiaCommandsLv4() { //SuperGM
addCommand("pap", ""); addCommand("pap", "");
addCommand("pianus", ""); addCommand("pianus", "");
addCommand("cake", ""); addCommand("cake", "");
addCommand("playernpc", ""); //addCommand("playernpc", "");
} }
function writeSolaxiaCommandsLv3() { //GM function writeSolaxiaCommandsLv3() { //GM
+9 -4
View File
@@ -17893,10 +17893,14 @@ USE `maplesolaxia`;
(9400121, 1332022, 1, 1, 0, 40000), (9400121, 1332022, 1, 1, 0, 40000),
(9400121, 1332027, 1, 1, 0, 40000), (9400121, 1332027, 1, 1, 0, 40000),
(9400121, 1472033, 1, 1, 0, 40000), (9400121, 1472033, 1, 1, 0, 40000),
(9400590, 1122059, 1, 1, 0, 40000), (9400590, 1122059, 1, 1, 0, 8000),
(9400591, 1122059, 1, 1, 0, 40000), (9400590, 1012076, 1, 1, 0, 20000),
(9400592, 1122059, 1, 1, 0, 40000), (9400591, 1122059, 1, 1, 0, 8000),
(9400593, 1122059, 1, 1, 0, 40000), (9400591, 1412040, 1, 1, 0, 20000),
(9400592, 1122059, 1, 1, 0, 8000),
(9400592, 1022082, 1, 1, 0, 20000),
(9400593, 1122059, 1, 1, 0, 8000),
(9400593, 1122015, 1, 1, 0, 20000),
(8200012, 4000458, 1, 1, 0, 200000), (8200012, 4000458, 1, 1, 0, 200000),
(8200012, 4000459, 1, 1, 0, 200000), (8200012, 4000459, 1, 1, 0, 200000),
(8200012, 4130012, 1, 1, 0, 3000), (8200012, 4130012, 1, 1, 0, 3000),
@@ -21121,6 +21125,7 @@ USE `maplesolaxia`;
DELETE FROM `drop_data` WHERE itemid=4000435; DELETE FROM `drop_data` WHERE itemid=4000435;
DELETE FROM `drop_data` WHERE itemid=4032192; DELETE FROM `drop_data` WHERE itemid=4032192;
DELETE FROM `drop_data` WHERE itemid=8143000; DELETE FROM `drop_data` WHERE itemid=8143000;
DELETE FROM `drop_data` WHERE itemid=2094101;
# delete all unused content on reactor drop data # delete all unused content on reactor drop data
DELETE FROM `reactordrops` WHERE itemid=1102260; DELETE FROM `reactordrops` WHERE itemid=1102260;
+2 -1
View File
@@ -221,4 +221,5 @@ INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `position`) VALUES
(1337, 2044025, 1, 80), (1337, 2044025, 1, 80),
(1337, 2043712, 1, 81), (1337, 2043712, 1, 81),
(1337, 2340000, 1, 82), (1337, 2340000, 1, 82),
(1337, 2040807, 1, 83); (1337, 2040807, 1, 83),
(1337, 2210032, 1, 84);
+1 -1
View File
@@ -48,7 +48,7 @@ public enum MapleBuffStat {
AURA(0x40000L), AURA(0x40000L),
CONFUSE(0x80000L), CONFUSE(0x80000L),
// ---- COUPON feature (was unused anyway) ---- // ------ COUPON feature ------
COUPON_EXP1(0x100000L), COUPON_EXP1(0x100000L),
COUPON_EXP2(0x200000L), COUPON_EXP2(0x200000L),
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -1307,7 +1307,9 @@ public class MapleClient {
} }
} }
server.getPlayerBuffStorage().addBuffsToStorage(player.getId(), player.getAllBuffs()); server.getPlayerBuffStorage().addBuffsToStorage(player.getId(), player.getAllBuffs());
player.cancelBuffEffects(); player.cancelAllBuffs(true);
player.cancelBuffExpireTask();
player.cancelSkillCooldownTask();
//Cancelling magicdoor? Nope //Cancelling magicdoor? Nope
//Cancelling mounts? Noty //Cancelling mounts? Noty
if (player.getBuffedValue(MapleBuffStat.PUPPET) != null) { if (player.getBuffedValue(MapleBuffStat.PUPPET) != null) {
+9 -4
View File
@@ -1252,9 +1252,12 @@ public class Commands {
} }
} }
if(player.getJob().isA(MapleJob.ARAN1)) { if(player.getJob().isA(MapleJob.ARAN1) || player.getJob().isA(MapleJob.LEGEND)) {
skill = SkillFactory.getSkill(5001005); skill = SkillFactory.getSkill(5001005);
player.changeSkillLevel(skill, (byte) -1, -1, -1); player.changeSkillLevel(skill, (byte) -1, -1, -1);
} else {
skill = SkillFactory.getSkill(21001001);
player.changeSkillLevel(skill, (byte) -1, -1, -1);
} }
player.yellowMessage("Skills maxed out."); player.yellowMessage("Skills maxed out.");
@@ -1664,7 +1667,7 @@ public class Commands {
case "givems": case "givems":
if (sub.length < 3){ if (sub.length < 3){
player.yellowMessage("Syntax: !givems <playername> <gainmx>"); player.yellowMessage("Syntax: !givems <playername> <gainms>");
break; break;
} }
@@ -2051,7 +2054,7 @@ public class Commands {
try { try {
if (sub.length == 2) { if (sub.length == 2) {
int itemId = Integer.parseInt(sub[1]); int itemId = Integer.parseInt(sub[1]);
if(!(itemId >= 30000 && itemId < 32000) || MapleItemInformationProvider.getInstance().getName(itemId) == null) { if(!(itemId >= 30000 && itemId < 35000) || MapleItemInformationProvider.getInstance().getName(itemId) == null) {
player.yellowMessage("Hair id '" + sub[1] + "' does not exist."); player.yellowMessage("Hair id '" + sub[1] + "' does not exist.");
break; break;
} }
@@ -2061,7 +2064,7 @@ public class Commands {
player.equipChanged(); player.equipChanged();
} else { } else {
int itemId = Integer.parseInt(sub[2]); int itemId = Integer.parseInt(sub[2]);
if(!(itemId >= 30000 && itemId < 32000) || MapleItemInformationProvider.getInstance().getName(itemId) == null) { if(!(itemId >= 30000 && itemId < 35000) || MapleItemInformationProvider.getInstance().getName(itemId) == null) {
player.yellowMessage("Hair id '" + sub[2] + "' does not exist."); player.yellowMessage("Hair id '" + sub[2] + "' does not exist.");
break; break;
} }
@@ -2278,6 +2281,7 @@ public class Commands {
player.getMap().spawnMonsterOnGroundBelow(monster, player.getPosition()); player.getMap().spawnMonsterOnGroundBelow(monster, player.getPosition());
break; break;
/*
case "playernpc": case "playernpc":
if (sub.length < 3){ if (sub.length < 3){
player.yellowMessage("Syntax: !playernpc <playername> <npcid>"); player.yellowMessage("Syntax: !playernpc <playername> <npcid>");
@@ -2285,6 +2289,7 @@ public class Commands {
} }
player.playerNPC(c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]), Integer.parseInt(sub[2])); player.playerNPC(c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]), Integer.parseInt(sub[2]));
break; break;
*/
default: default:
return false; return false;
+3 -3
View File
@@ -487,11 +487,11 @@ public class Equip extends Item {
// from level 1 to 2 is killing about 100~200 mobs of the same level range, on a 1x EXP rate scenario. // from level 1 to 2 is killing about 100~200 mobs of the same level range, on a 1x EXP rate scenario.
if(reqLevel >= 78) { if(reqLevel >= 78) {
return Math.max(ServerConstants.EQUIP_EXPERIENCE_MOD * (10413.648 * Math.exp(reqLevel * 0.03275)), 15); return Math.max(ServerConstants.EQUIP_EXP_RATE * (10413.648 * Math.exp(reqLevel * 0.03275)), 15);
} else if(reqLevel >= 38) { } else if(reqLevel >= 38) {
return Math.max(ServerConstants.EQUIP_EXPERIENCE_MOD * ( 4985.818 * Math.exp(reqLevel * 0.02007)), 15); return Math.max(ServerConstants.EQUIP_EXP_RATE * ( 4985.818 * Math.exp(reqLevel * 0.02007)), 15);
} else { } else {
return Math.max(ServerConstants.EQUIP_EXPERIENCE_MOD * ( 248.219 * Math.exp(reqLevel * 0.11093)), 15); return Math.max(ServerConstants.EQUIP_EXP_RATE * ( 248.219 * Math.exp(reqLevel * 0.11093)), 15);
} }
} }
-2
View File
@@ -36,8 +36,6 @@ public final class ItemConstants {
public final static int KARMA = 0x10; public final static int KARMA = 0x10;
public final static int PET_COME = 0x80; public final static int PET_COME = 0x80;
public final static int ACCOUNT_SHARING = 0x100; public final static int ACCOUNT_SHARING = 0x100;
public final static float ITEM_ARMOR_EXP = 1 / 350000;
public static final float ITEM_WEAPON_EXP = 1 / 700000;
public final static boolean EXPIRING_ITEMS = true; public final static boolean EXPIRING_ITEMS = true;
+8 -5
View File
@@ -33,7 +33,7 @@ public class ServerConstants {
//Server Flags //Server Flags
public static final boolean USE_CUSTOM_KEYSET = true; //Enables auto-setup of the MapleSolaxiaV2's custom keybindings when creating characters. public static final boolean USE_CUSTOM_KEYSET = true; //Enables auto-setup of the MapleSolaxiaV2's custom keybindings when creating characters.
public static final boolean USE_MAXRANGE_ECHO_OF_HERO = true; public static final boolean USE_MAXRANGE_ECHO_OF_HERO = true;
public static final boolean USE_MAXRANGE = true; //Will send and receive packets from all events of a map, rather than those of only view range. public static final boolean USE_MAXRANGE = true; //Will send and receive packets from all events on a map, rather than those of only view range.
public static final boolean USE_DEBUG = false; //Will enable some text prints on the client, oriented for debugging purposes. public static final boolean USE_DEBUG = false; //Will enable some text prints on the client, oriented for debugging purposes.
public static final boolean USE_DEBUG_SHOW_RCVD_PACKET = false; //Prints on the cmd all received packet ids. public static final boolean USE_DEBUG_SHOW_RCVD_PACKET = false; //Prints on the cmd all received packet ids.
public static final boolean USE_DEBUG_SHOW_INFO_EQPEXP = false; //Prints on the cmd all equip exp gain info. public static final boolean USE_DEBUG_SHOW_INFO_EQPEXP = false; //Prints on the cmd all equip exp gain info.
@@ -45,20 +45,23 @@ public class ServerConstants {
public static final boolean USE_PARTY_SEARCH = false; public static final boolean USE_PARTY_SEARCH = false;
public static final boolean USE_AUTOBAN = false; //Commands the server to detect infractors automatically. public static final boolean USE_AUTOBAN = false; //Commands the server to detect infractors automatically.
public static final boolean USE_AUTOSAVE = true; //Enables server autosaving feature (saves characters to DB each 1 hour). public static final boolean USE_AUTOSAVE = true; //Enables server autosaving feature (saves characters to DB each 1 hour).
public static final boolean USE_SERVER_AUTOASSIGNER = true; //Server-builtin autoassigner, uses algorithm based on distributing AP accordingly to required secondary stat on equipments. public static final boolean USE_SERVER_AUTOASSIGNER = true; //Server-builtin autoassigner, uses algorithm based on distributing AP accordingly with required secondary stat on equipments.
public static final boolean USE_REFRESH_RANK_MOVE = true; public static final boolean USE_REFRESH_RANK_MOVE = true;
public static final boolean USE_ENFORCE_MDOOR_POSITION = true; //Forces mystic door to be spawned near spawnpoints. (since things bugs out other way, and this helps players to locate the door faster) public static final boolean USE_ENFORCE_MDOOR_POSITION = true; //Forces mystic door to be spawned near spawnpoints. (since things bugs out other way, and this helps players to locate the door faster)
public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped. public static final boolean USE_ERASE_UNTRADEABLE_DROP = true; //Forces flagged untradeable items to disappear when dropped.
public static final boolean USE_BUFF_MOST_SIGNIFICANT = true; //When applying buffs, the player will stick with the highest stat boost among the listed, rather than overwriting stats.
//Server Rates And Experience //Server Rates And Experience
public static final int EXP_RATE = 10; public static final int EXP_RATE = 10;
public static final int MESO_RATE = 10; public static final int MESO_RATE = 10;
public static final int DROP_RATE = 10; public static final int DROP_RATE = 10;
public static final int BOSS_DROP_RATE = 20; public static final int BOSS_DROP_RATE = 20;
public static final int PARTY_EXPERIENCE_MOD = 1; //Change for event stuff. public static final double EQUIP_EXP_RATE = 10.0; //Rate for equipment exp gain, grows linearly. Set 1.0 for default (about 100~200 same-level range mobs killed to pass equip from level 1 to 2).
public static final double EQUIP_EXPERIENCE_MOD = 10.0; //Rate for equipment exp needed, grows linearly. Set 1.0 for default (about 100~200 same-level range mobs killed to pass equip from level 1 to 2).
public static final int PARTY_EXPERIENCE_MOD = 1; //Change for event stuff.
public static final double PQ_BONUS_EXP_MOD = 0.5; public static final double PQ_BONUS_EXP_MOD = 0.5;
public static final byte MAX_MONITORED_BUFFSTATS = 5; //Limits accounting for "dormant" buff effects, that should take place when stronger stat buffs expires.
public static final int MAX_AP = 32767; //Max AP allotted on the auto-assigner. public static final int MAX_AP = 32767; //Max AP allotted on the auto-assigner.
public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system. public static final int MAX_EVENT_LEVELS = 8; //Event has different levels of rewarding system.
public static final long BLOCK_NPC_RACE_CONDT = (long)(0.5 * 1000); //Time the player client must wait before reopening a conversation with an NPC. public static final long BLOCK_NPC_RACE_CONDT = (long)(0.5 * 1000); //Time the player client must wait before reopening a conversation with an NPC.
@@ -91,7 +94,7 @@ public class ServerConstants {
//Equipment Configuration //Equipment Configuration
public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up. public static final boolean USE_EQUIPMNT_LVLUP_SLOTS = true;//Equips can upgrade slots at level up.
public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stats upgrades at equip level up. public static final boolean USE_EQUIPMNT_LVLUP_POWER = true;//Enable more powerful stat upgrades at equip level up.
public static final boolean USE_SPIKES_AVOID_BANISH = true; //Shoes equipped with spikes prevents mobs from banishing wearer. public static final boolean USE_SPIKES_AVOID_BANISH = true; //Shoes equipped with spikes prevents mobs from banishing wearer.
public static final boolean USE_CHAIR_EXTRAHEAL = true; //Enable map chairs to further recover player's HP and MP. public static final boolean USE_CHAIR_EXTRAHEAL = true; //Enable map chairs to further recover player's HP and MP.
public static final int MAX_EQUIPMNT_LVLUP_STAT_UP = 10000; //Max stat upgrade an equipment can have on a levelup. public static final int MAX_EQUIPMNT_LVLUP_STAT_UP = 10000; //Max stat upgrade an equipment can have on a levelup.
+2
View File
@@ -21,6 +21,8 @@
*/ */
package net.server; package net.server;
import net.server.worker.CouponWorker;
import net.server.worker.RankingWorker;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@@ -41,6 +41,8 @@ public final class CancelBuffHandler extends AbstractMaplePacketHandler implemen
@Override @Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
int sourceid = slea.readInt(); int sourceid = slea.readInt();
if(sourceid < 0) sourceid = -sourceid; //oh my...
switch (sourceid) { switch (sourceid) {
case FPArchMage.BIG_BANG: case FPArchMage.BIG_BANG:
case ILArchMage.BIG_BANG: case ILArchMage.BIG_BANG:
@@ -32,7 +32,6 @@ import tools.Pair;
import tools.data.input.SeekableLittleEndianAccessor; import tools.data.input.SeekableLittleEndianAccessor;
import client.MapleBuffStat; import client.MapleBuffStat;
import client.MapleCharacter; import client.MapleCharacter;
import client.MapleCharacter.CancelCooldownAction;
import client.MapleClient; import client.MapleClient;
import client.MapleJob; import client.MapleJob;
import client.MapleStat; import client.MapleStat;
@@ -175,7 +174,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
return; return;
} else { } else {
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown())); c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000)); player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
} }
} }
} }
@@ -50,7 +50,9 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
mc.closePlayerInteractions(); mc.closePlayerInteractions();
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs()); Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
mc.cancelBuffEffects(); mc.cancelAllBuffs(true);
mc.cancelBuffExpireTask();
mc.cancelSkillCooldownTask();
mc.cancelExpirationTask(); mc.cancelExpirationTask();
c.announce(MaplePacketCreator.openCashShop(c, false)); c.announce(MaplePacketCreator.openCashShop(c, false));
@@ -59,6 +59,9 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
} }
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs()); Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
chr.cancelAllBuffs(true);
chr.cancelBuffExpireTask();
chr.cancelSkillCooldownTask();
chr.cancelExpirationTask(); chr.cancelExpirationTask();
chr.saveToDB(); chr.saveToDB();
chr.getMap().removePlayer(c.getPlayer()); chr.getMap().removePlayer(c.getPlayer());
@@ -27,7 +27,6 @@ import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor; import tools.data.input.SeekableLittleEndianAccessor;
import client.MapleBuffStat; import client.MapleBuffStat;
import client.MapleCharacter; import client.MapleCharacter;
import client.MapleCharacter.CancelCooldownAction;
import client.MapleClient; import client.MapleClient;
import client.Skill; import client.Skill;
import client.SkillFactory; import client.SkillFactory;
@@ -76,7 +75,7 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
return; return;
} else { } else {
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown())); c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000)); player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
} }
} }
applyAttack(attack, player, effect.getAttackCount()); applyAttack(attack, player, effect.getAttackCount());
@@ -32,6 +32,7 @@ import constants.ItemConstants;
import java.util.Arrays; import java.util.Arrays;
import net.AbstractMaplePacketHandler; import net.AbstractMaplePacketHandler;
import net.server.Server;
import server.MapleInventoryManipulator; import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider; import server.MapleItemInformationProvider;
import server.MapleMiniGame; import server.MapleMiniGame;
@@ -172,6 +173,7 @@ public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
} else { } else {
HiredMerchant merchant = new HiredMerchant(chr, itemId, desc); HiredMerchant merchant = new HiredMerchant(chr, itemId, desc);
chr.setHiredMerchant(merchant); chr.setHiredMerchant(merchant);
c.getWorldServer().registerHiredMerchant(merchant);
chr.getClient().getChannelServer().addHiredMerchant(chr.getId(), merchant); chr.getClient().getChannelServer().addHiredMerchant(chr.getId(), merchant);
chr.announce(MaplePacketCreator.getHiredMerchant(chr, merchant, true)); chr.announce(MaplePacketCreator.getHiredMerchant(chr, merchant, true));
} }
@@ -256,6 +256,8 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
c.announce(MaplePacketCreator.enableReport()); c.announce(MaplePacketCreator.enableReport());
player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1); player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1);
player.checkBerserk(player.isHidden()); player.checkBerserk(player.isHidden());
player.buffExpireTask();
player.skillCooldownTask();
player.expirationTask(); player.expirationTask();
if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) { if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) {
player.createDragon(); player.createDragon();
@@ -30,7 +30,6 @@ import tools.Randomizer;
import tools.data.input.SeekableLittleEndianAccessor; import tools.data.input.SeekableLittleEndianAccessor;
import client.MapleBuffStat; import client.MapleBuffStat;
import client.MapleCharacter; import client.MapleCharacter;
import client.MapleCharacter.CancelCooldownAction;
import client.MapleClient; import client.MapleClient;
import client.Skill; import client.Skill;
import client.SkillFactory; import client.SkillFactory;
@@ -208,7 +207,7 @@ public final class RangedAttackHandler extends AbstractDealDamageHandler {
return; return;
} else { } else {
c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown())); c.announce(MaplePacketCreator.skillCooldown(attack.skill, effect_.getCooldown()));
player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000, TimerManager.getInstance().schedule(new CancelCooldownAction(player, attack.skill), effect_.getCooldown() * 1000)); player.addCooldown(attack.skill, System.currentTimeMillis(), effect_.getCooldown() * 1000);
} }
} }
} }
@@ -32,7 +32,6 @@ import tools.FilePrinter;
import tools.MaplePacketCreator; import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor; import tools.data.input.SeekableLittleEndianAccessor;
import client.MapleCharacter; import client.MapleCharacter;
import client.MapleCharacter.CancelCooldownAction;
import client.autoban.AutobanFactory; import client.autoban.AutobanFactory;
import client.MapleClient; import client.MapleClient;
import client.MapleStat; import client.MapleStat;
@@ -84,8 +83,7 @@ public final class SpecialMoveHandler extends AbstractMaplePacketHandler {
return; return;
} else if (skillid != Corsair.BATTLE_SHIP) { } else if (skillid != Corsair.BATTLE_SHIP) {
c.announce(MaplePacketCreator.skillCooldown(skillid, effect.getCooldown())); c.announce(MaplePacketCreator.skillCooldown(skillid, effect.getCooldown()));
ScheduledFuture<?> timer = TimerManager.getInstance().schedule(new CancelCooldownAction(c.getPlayer(), skillid), effect.getCooldown() * 1000); chr.addCooldown(skillid, System.currentTimeMillis(), effect.getCooldown() * 1000);
chr.addCooldown(skillid, System.currentTimeMillis(), effect.getCooldown() * 1000, timer);
} }
} }
if (skillid == Hero.MONSTER_MAGNET || skillid == Paladin.MONSTER_MAGNET || skillid == DarkKnight.MONSTER_MAGNET) { // Monster Magnet if (skillid == Hero.MONSTER_MAGNET || skillid == Paladin.MONSTER_MAGNET || skillid == DarkKnight.MONSTER_MAGNET) { // Monster Magnet
+39
View File
@@ -0,0 +1,39 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation version 3 as published by
the Free Software Foundation. You may not use, modify or distribute
this program under any other version of the GNU Affero General Public
License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.server.worker;
import net.server.world.World;
/**
* @author Ronan
*/
public class BaseWorker implements Runnable {
protected World wserv;
@Override
public void run() {}
public BaseWorker(World world) {
wserv = world;
}
}
@@ -20,17 +20,17 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package net.server; package net.server.worker;
import net.server.world.World; import net.server.world.World;
import client.MapleCharacter; import client.MapleCharacter;
import constants.ServerConstants; import constants.ServerConstants;
import net.server.PlayerStorage;
/** /**
* @author Ronan * @author Ronan
*/ */
public class CharacterAutosaverWorker implements Runnable { public class CharacterAutosaverWorker extends BaseWorker implements Runnable {
private World wserv;
@Override @Override
public void run() { public void run() {
@@ -45,6 +45,6 @@ public class CharacterAutosaverWorker implements Runnable {
} }
public CharacterAutosaverWorker(World world) { public CharacterAutosaverWorker(World world) {
wserv = world; super(world);
} }
} }
@@ -20,9 +20,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package net.server; package net.server.worker;
import java.sql.SQLException; import java.sql.SQLException;
import net.server.Server;
import tools.FilePrinter; import tools.FilePrinter;
/** /**
@@ -0,0 +1,40 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation version 3 as published by
the Free Software Foundation. You may not use, modify or distribute
this program under any other version of the GNU Affero General Public
License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.server.worker;
import net.server.world.World;
/**
* @author Ronan
*/
public class HiredMerchantWorker extends BaseWorker implements Runnable {
@Override
public void run() {
wserv.runHiredMerchantSchedule();
}
public HiredMerchantWorker(World world) {
super(world);
}
}
@@ -20,15 +20,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package net.server; package net.server.worker;
import net.server.world.World; import net.server.world.World;
/** /**
* @author Ronan * @author Ronan
*/ */
public class MountTirednessWorker implements Runnable { public class MountTirednessWorker extends BaseWorker implements Runnable {
private World wserv;
@Override @Override
public void run() { public void run() {
@@ -36,6 +35,6 @@ public class MountTirednessWorker implements Runnable {
} }
public MountTirednessWorker(World world) { public MountTirednessWorker(World world) {
wserv = world; super(world);
} }
} }
@@ -20,15 +20,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package net.server; package net.server.worker;
import net.server.world.World; import net.server.world.World;
/** /**
* @author Ronan * @author Ronan
*/ */
public class PetFullnessWorker implements Runnable { public class PetFullnessWorker extends BaseWorker implements Runnable {
private World wserv;
@Override @Override
public void run() { public void run() {
@@ -36,6 +35,6 @@ public class PetFullnessWorker implements Runnable {
} }
public PetFullnessWorker(World world) { public PetFullnessWorker(World world) {
wserv = world; super(world);
} }
} }
@@ -19,7 +19,7 @@
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package net.server; package net.server.worker;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@@ -28,6 +28,7 @@ import java.sql.SQLException;
import client.MapleJob; import client.MapleJob;
import tools.DatabaseConnection; import tools.DatabaseConnection;
import constants.ServerConstants; import constants.ServerConstants;
import net.server.Server;
/** /**
* @author Matze * @author Matze
+50 -3
View File
@@ -45,9 +45,10 @@ import java.util.HashSet;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import server.TimerManager; import server.TimerManager;
import net.server.CharacterAutosaverWorker; import server.maps.HiredMerchant;
import net.server.MountTirednessWorker; import net.server.worker.CharacterAutosaverWorker;
import net.server.PetFullnessWorker; import net.server.worker.MountTirednessWorker;
import net.server.worker.PetFullnessWorker;
import net.server.PlayerStorage; import net.server.PlayerStorage;
import net.server.Server; import net.server.Server;
import net.server.channel.Channel; import net.server.channel.Channel;
@@ -84,6 +85,10 @@ public class World {
private ScheduledFuture<?> mountsSchedule; private ScheduledFuture<?> mountsSchedule;
private long mountUpdate; private long mountUpdate;
private Map<HiredMerchant, Byte> activeMerchants = new LinkedHashMap<>();
private ScheduledFuture<?> MerchantsSchedule;
private long merchantUpdate;
private ScheduledFuture<?> charactersSchedule; private ScheduledFuture<?> charactersSchedule;
public World(int world, int flag, String eventmsg, int exprate, int droprate, int mesorate, int bossdroprate) { public World(int world, int flag, String eventmsg, int exprate, int droprate, int mesorate, int bossdroprate) {
@@ -773,6 +778,48 @@ public class World {
} }
} }
} }
public void registerHiredMerchant(HiredMerchant hm) {
synchronized(activeMerchants) {
byte initProc;
if(System.currentTimeMillis() - merchantUpdate > 5 * 60 * 1000) initProc = 1;
else initProc = 0;
activeMerchants.put(hm, initProc);
}
}
public void unregisterHiredMerchant(HiredMerchant hm) {
synchronized(activeMerchants) {
activeMerchants.remove(hm);
}
}
public void runHiredMerchantSchedule() {
Map<HiredMerchant, Byte> deployedMerchants;
synchronized(activeMerchants) {
merchantUpdate = System.currentTimeMillis();
deployedMerchants = Collections.unmodifiableMap(activeMerchants);
}
for(Map.Entry<HiredMerchant, Byte> dm: deployedMerchants.entrySet()) {
byte timeOn = dm.getValue();
if(timeOn <= 144) { // 1440 minutes == 24hrs
synchronized(activeMerchants) {
activeMerchants.put(dm.getKey(), (byte)(timeOn + 1));
}
} else {
HiredMerchant hm = dm.getKey();
hm.forceClose();
this.getChannel(hm.getChannel()).removeHiredMerchant(hm.getOwnerId());
synchronized(activeMerchants) {
activeMerchants.remove(dm.getKey());
}
}
}
}
public void setServerMessage(String msg) { public void setServerMessage(String msg) {
for (Channel ch : channels) { for (Channel ch : channels) {
+1 -1
View File
@@ -523,7 +523,7 @@ public class MapleInventoryManipulator {
return; return;
} }
int itemId = source.getItemId(); int itemId = source.getItemId();
if (itemId >= 5000000 && itemId <= 5000102) { if (ItemConstants.isPet(itemId)) {
return; return;
} }
if (type == MapleInventoryType.EQUIPPED && itemId == 1122017) { if (type == MapleInventoryType.EQUIPPED && itemId == 1122017) {
+12 -3
View File
@@ -110,6 +110,7 @@ public class MapleItemInformationProvider {
protected Map<Integer, Boolean> consumeOnPickupCache = new HashMap<>(); protected Map<Integer, Boolean> consumeOnPickupCache = new HashMap<>();
protected Map<Integer, Boolean> isQuestItemCache = new HashMap<>(); protected Map<Integer, Boolean> isQuestItemCache = new HashMap<>();
protected Map<Integer, String> equipmentSlotCache = new HashMap<>(); protected Map<Integer, String> equipmentSlotCache = new HashMap<>();
protected Map<Integer, Boolean> noCancelMouseCache = new HashMap<>();
private MapleItemInformationProvider() { private MapleItemInformationProvider() {
loadCardIdData(); loadCardIdData();
@@ -246,7 +247,7 @@ public class MapleItemInformationProvider {
} else if (itemId >= 1080000 && itemId < 1090000) { } else if (itemId >= 1080000 && itemId < 1090000) {
theData = eqpStringData; theData = eqpStringData;
cat = "Eqp/Glove"; cat = "Eqp/Glove";
} else if (itemId >= 30000 && itemId < 32000) { } else if (itemId >= 30000 && itemId < 35000) {
theData = eqpStringData; theData = eqpStringData;
cat = "Eqp/Hair"; cat = "Eqp/Hair";
} else if (itemId >= 1050000 && itemId < 1060000) { } else if (itemId >= 1050000 && itemId < 1060000) {
@@ -278,7 +279,7 @@ public class MapleItemInformationProvider {
cat = "Etc"; cat = "Etc";
} else if (itemId >= 3000000 && itemId < 4000000) { } else if (itemId >= 3000000 && itemId < 4000000) {
theData = insStringData; theData = insStringData;
} else if (itemId >= 5000000 && itemId < 5010000) { } else if (ItemConstants.isPet(itemId)) {
theData = petStringData; theData = petStringData;
} else { } else {
return null; return null;
@@ -291,11 +292,19 @@ public class MapleItemInformationProvider {
} }
public boolean noCancelMouse(int itemId) { public boolean noCancelMouse(int itemId) {
if (noCancelMouseCache.containsKey(itemId)) {
return noCancelMouseCache.get(itemId);
}
MapleData item = getItemData(itemId); MapleData item = getItemData(itemId);
if (item == null) { if (item == null) {
noCancelMouseCache.put(itemId, false);
return false; return false;
} }
return MapleDataTool.getIntConvert("info/noCancelMouse", item, 0) == 1;
boolean blockMouse = MapleDataTool.getIntConvert("info/noCancelMouse", item, 0) == 1;
noCancelMouseCache.put(itemId, blockMouse);
return blockMouse;
} }
private MapleData getItemData(int itemId) { private MapleData getItemData(int itemId) {
+1 -1
View File
@@ -132,7 +132,7 @@ public class MapleShop {
int cardreduce = value - cost; int cardreduce = value - cost;
int diff = cardreduce + c.getPlayer().getMeso(); int diff = cardreduce + c.getPlayer().getMeso();
if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) { if (MapleInventoryManipulator.checkSpace(c, itemId, quantity, "")) {
if (itemId >= 5000000 && itemId <= 5000100) { if (ItemConstants.isPet(itemId)) {
int petid = MaplePet.createPet(itemId); int petid = MaplePet.createPet(itemId);
MapleInventoryManipulator.addById(c, itemId, quantity, null, petid, -1); MapleInventoryManipulator.addById(c, itemId, quantity, null, petid, -1);
} else { } else {
+33 -12
View File
@@ -565,8 +565,8 @@ public class MapleStatEffect {
case Crusader.ARMOR_CRASH: case Crusader.ARMOR_CRASH:
case DragonKnight.POWER_CRASH: case DragonKnight.POWER_CRASH:
case WhiteKnight.MAGIC_CRASH: case WhiteKnight.MAGIC_CRASH:
monsterStatus.put(MonsterStatus.SEAL_SKILL, Integer.valueOf(1)); monsterStatus.put(MonsterStatus.SEAL_SKILL, Integer.valueOf(1));
break; break;
case Rogue.DISORDER: case Rogue.DISORDER:
monsterStatus.put(MonsterStatus.WATK, Integer.valueOf(ret.x)); monsterStatus.put(MonsterStatus.WATK, Integer.valueOf(ret.x));
monsterStatus.put(MonsterStatus.WDEF, Integer.valueOf(ret.y)); monsterStatus.put(MonsterStatus.WDEF, Integer.valueOf(ret.y));
@@ -842,7 +842,6 @@ public class MapleStatEffect {
} else { } else {
MapleInventoryManipulator.removeById(applyto.getClient(), MapleInventoryType.USE, projectile, 200, false, true); MapleInventoryManipulator.removeById(applyto.getClient(), MapleInventoryType.USE, projectile, 200, false, true);
} }
} }
SummonMovementType summonMovementType = getSummonMovementType(); SummonMovementType summonMovementType = getSummonMovementType();
if (overTime || isCygnusFA() || summonMovementType != null) { if (overTime || isCygnusFA() || summonMovementType != null) {
@@ -983,9 +982,12 @@ public class MapleStatEffect {
public void silentApplyBuff(MapleCharacter chr, long starttime) { public void silentApplyBuff(MapleCharacter chr, long starttime) {
int localDuration = duration; int localDuration = duration;
localDuration = alchemistModifyVal(chr, localDuration, false); localDuration = alchemistModifyVal(chr, localDuration, false);
CancelEffectAction cancelAction = new CancelEffectAction(chr, this, starttime); //CancelEffectAction cancelAction = new CancelEffectAction(chr, this, starttime);
ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + localDuration) - System.currentTimeMillis())); //ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + localDuration) - System.currentTimeMillis()));
chr.registerEffect(this, starttime, schedule);
if(starttime + localDuration <= System.currentTimeMillis()) return;
chr.registerEffect(this, starttime, (starttime + localDuration), true);
SummonMovementType summonMovementType = getSummonMovementType(); SummonMovementType summonMovementType = getSummonMovementType();
if (summonMovementType != null) { if (summonMovementType != null) {
final MapleSummon tosummon = new MapleSummon(chr, sourceid, chr.getPosition(), summonMovementType); final MapleSummon tosummon = new MapleSummon(chr, sourceid, chr.getPosition(), summonMovementType);
@@ -1006,7 +1008,18 @@ public class MapleStatEffect {
final long starttime = System.currentTimeMillis(); final long starttime = System.currentTimeMillis();
// final CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime); // final CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
// final ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + 99999) - System.currentTimeMillis())); // final ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, ((starttime + 99999) - System.currentTimeMillis()));
applyto.registerEffect(this, starttime, null); applyto.registerEffect(this, starttime, Long.MAX_VALUE, false);
}
public void updateBuffEffect(MapleCharacter target, List<Pair<MapleBuffStat, Integer>> activeStats, long starttime) {
int localDuration = duration;
localDuration = alchemistModifyVal(target, localDuration, false);
long leftDuration = (starttime + localDuration) - System.currentTimeMillis();
if(leftDuration > 0) {
byte[] buff = MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), (int)leftDuration, activeStats);
target.getClient().announce(buff);
}
} }
private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary) { private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary) {
@@ -1107,11 +1120,7 @@ public class MapleStatEffect {
List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.MORPH, Integer.valueOf(getMorph(applyto)))); List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.MORPH, Integer.valueOf(getMorph(applyto))));
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), stat); mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), stat);
} }
long starttime = System.currentTimeMillis();
CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, localDuration);
applyto.registerEffect(this, starttime, schedule);
if (buff != null) { if (buff != null) {
if (!hasNoIcon()) { //Thanks flav for such a simple release! :) if (!hasNoIcon()) { //Thanks flav for such a simple release! :)
applyto.getClient().announce(buff); applyto.getClient().announce(buff);
@@ -1120,6 +1129,12 @@ public class MapleStatEffect {
System.out.println("<Error> NO buff icon for id " + sourceid); System.out.println("<Error> NO buff icon for id " + sourceid);
} }
} }
long starttime = System.currentTimeMillis();
//CancelEffectAction cancelAction = new CancelEffectAction(applyto, this, starttime);
//ScheduledFuture<?> schedule = TimerManager.getInstance().schedule(cancelAction, localDuration);
applyto.registerEffect(this, starttime, starttime + localDuration, false);
if (mbuff != null) { if (mbuff != null) {
applyto.getMap().broadcastMessage(applyto, mbuff, false); applyto.getMap().broadcastMessage(applyto, mbuff, false);
} }
@@ -1511,11 +1526,16 @@ public class MapleStatEffect {
public int getSourceId() { public int getSourceId() {
return sourceid; return sourceid;
} }
public int getBuffSourceId() {
return skill ? sourceid : -sourceid;
}
public boolean makeChanceResult() { public boolean makeChanceResult() {
return prop == 1.0 || Math.random() < prop; return prop == 1.0 || Math.random() < prop;
} }
/*
private static class CancelEffectAction implements Runnable { private static class CancelEffectAction implements Runnable {
private MapleStatEffect effect; private MapleStatEffect effect;
@@ -1536,6 +1556,7 @@ public class MapleStatEffect {
} }
} }
} }
*/
public short getHp() { public short getHp() {
return hp; return hp;

Some files were not shown because too many files have changed in this diff Show More