Compare commits
336 Commits
v0.15.0
...
feat/postg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9d2da1f35 | ||
|
|
9101cd189c | ||
|
|
196e3efec7 | ||
|
|
7adce5e2af | ||
|
|
c9aa049874 | ||
|
|
58d6603946 | ||
|
|
bfd9f68805 | ||
|
|
44c2b77595 | ||
|
|
5148d76f9f | ||
|
|
45bfc395be | ||
|
|
8052814028 | ||
|
|
1eeb2483bf | ||
|
|
2aabeb378c | ||
|
|
7054d37b58 | ||
|
|
64b20aa659 | ||
|
|
42bb664add | ||
|
|
97ed3d2da5 | ||
|
|
e2ac5e448b | ||
|
|
2365458b78 | ||
|
|
c807c1e54f | ||
|
|
6d647e8010 | ||
|
|
1dce65d146 | ||
|
|
8ceb60329d | ||
|
|
f240c7e98b | ||
|
|
f5c17768f4 | ||
|
|
d08e1c4567 | ||
|
|
e7d94ee4fb | ||
|
|
89dfc37551 | ||
|
|
02f45397ce | ||
|
|
82e377f39a | ||
|
|
7227be3189 | ||
|
|
cad04a4725 | ||
|
|
a2d6b88cde | ||
|
|
81ab3e685d | ||
|
|
c43e833fbd | ||
|
|
3d39cce181 | ||
|
|
9bbcf8c3ed | ||
|
|
669f214bd8 | ||
|
|
72c1a249e6 | ||
|
|
f94925d1fe | ||
|
|
9383608f68 | ||
|
|
2d7e82ceac | ||
|
|
7e4bbef888 | ||
|
|
cd12d2bc9a | ||
|
|
7ab52d0ccb | ||
|
|
c85ac4f5d9 | ||
|
|
1e4e284924 | ||
|
|
a5a1de5362 | ||
|
|
76d8a4b985 | ||
|
|
9f99aeacda | ||
|
|
20399f5a87 | ||
|
|
5e24a09ffe | ||
|
|
11ed85abe0 | ||
|
|
dcd777faca | ||
|
|
c52d82c6f2 | ||
|
|
74aa5fc572 | ||
|
|
10882a09b0 | ||
|
|
97c22055ac | ||
|
|
f38fb34c3a | ||
|
|
871a47ad26 | ||
|
|
c6823f5186 | ||
|
|
58e54c88af | ||
|
|
994612d15f | ||
|
|
5ff522123a | ||
|
|
84f1989256 | ||
|
|
cd0efcf2b6 | ||
|
|
1f5a38d9cf | ||
|
|
df83326a6f | ||
|
|
49bc1c9b3d | ||
|
|
6ce9d42ae4 | ||
|
|
7e45cd6dab | ||
|
|
003efa9c8a | ||
|
|
2ab7b11b46 | ||
|
|
bdf1e52f70 | ||
|
|
636fb5fd53 | ||
|
|
fba0dbf8e3 | ||
|
|
f0be1bae4c | ||
|
|
c81c298dfe | ||
|
|
58644a1cd2 | ||
|
|
7c2833e73b | ||
|
|
8ca935753b | ||
|
|
ab8ddc767f | ||
|
|
7607e3d4b6 | ||
|
|
1504da67f6 | ||
|
|
d6d8560d23 | ||
|
|
325f3b54a6 | ||
|
|
bfe174c242 | ||
|
|
4747d88f40 | ||
|
|
af1878c3a0 | ||
|
|
a365d20fd8 | ||
|
|
8c0350b16c | ||
|
|
c384d31827 | ||
|
|
8533d52c7a | ||
|
|
c08003a436 | ||
|
|
e9598d407b | ||
|
|
0e7c5358e2 | ||
|
|
5da87f7b22 | ||
|
|
6e9ff7fb34 | ||
|
|
7f149d56f0 | ||
|
|
bfcadc0691 | ||
|
|
d6ad68d537 | ||
|
|
be98a7ab47 | ||
|
|
469c70d1d7 | ||
|
|
099275c5a3 | ||
|
|
419f5d92b4 | ||
|
|
05ca945145 | ||
|
|
543cbafd0b | ||
|
|
131379e39e | ||
|
|
150754a74b | ||
|
|
d4c65ed690 | ||
|
|
295144758d | ||
|
|
ad63aaad44 | ||
|
|
b05e952268 | ||
|
|
193257c25b | ||
|
|
111c4f2677 | ||
|
|
84c5216b8f | ||
|
|
0921396c57 | ||
|
|
8b76a28458 | ||
|
|
fc0075831a | ||
|
|
4f0182621a | ||
|
|
9e4ea4a474 | ||
|
|
8ca2720ec1 | ||
|
|
c7137954fe | ||
|
|
b410832a81 | ||
|
|
da17490dbc | ||
|
|
371ed4efff | ||
|
|
e51dd82bdb | ||
|
|
66567fa595 | ||
|
|
92db70159f | ||
|
|
11cbf2a475 | ||
|
|
3367b58e39 | ||
|
|
8f7068c55b | ||
|
|
c28182c5a2 | ||
|
|
7bc946934a | ||
|
|
476ec0f0fe | ||
|
|
f8f67e61fa | ||
|
|
e9f24b4ae0 | ||
|
|
503c76ed34 | ||
|
|
307cb71023 | ||
|
|
e6bfdbba6a | ||
|
|
9275802466 | ||
|
|
ed01c6a54b | ||
|
|
ddfac919cb | ||
|
|
33e5ea5bdf | ||
|
|
2559879aaa | ||
|
|
630e56651b | ||
|
|
fb0ae8b080 | ||
|
|
203f4bf34f | ||
|
|
be1ba7229c | ||
|
|
37e6b16656 | ||
|
|
38233b39c2 | ||
|
|
d095179d6c | ||
|
|
1e583e21cc | ||
|
|
75d5aad0b6 | ||
|
|
b5eb5dc0b9 | ||
|
|
431eced76a | ||
|
|
ac1f4c85b5 | ||
|
|
ee8758e63b | ||
|
|
76e114c9f2 | ||
|
|
bb16165c51 | ||
|
|
78e994402e | ||
|
|
67ab800205 | ||
|
|
afb04b0d80 | ||
|
|
e4430a3860 | ||
|
|
a5b572023b | ||
|
|
380e4284ee | ||
|
|
16ff5a6f54 | ||
|
|
cced80991f | ||
|
|
f2b8ced976 | ||
|
|
a4f8086da1 | ||
|
|
e295a24d98 | ||
|
|
64f99a29c6 | ||
|
|
40425ac4e1 | ||
|
|
2b6ef9feb5 | ||
|
|
e38344ceae | ||
|
|
5d81e05458 | ||
|
|
af02f8b744 | ||
|
|
7661cd0f75 | ||
|
|
167937bb88 | ||
|
|
988d898d6f | ||
|
|
e35060da2a | ||
|
|
c0ee1f8ffe | ||
|
|
99006c2dda | ||
|
|
f142e21bbb | ||
|
|
1c6245fa6c | ||
|
|
a307afae3c | ||
|
|
50524a7740 | ||
|
|
d00b4ed678 | ||
|
|
b45620154c | ||
|
|
5450c29178 | ||
|
|
fa666c98e6 | ||
|
|
902f1a154e | ||
|
|
4e1aa1eb1a | ||
|
|
a580e44bc9 | ||
|
|
da4a467453 | ||
|
|
0bb14e415e | ||
|
|
0a8591aa08 | ||
|
|
813768ec47 | ||
|
|
5595f5763b | ||
|
|
1be775394e | ||
|
|
55c9d4abbb | ||
|
|
93bbe868cb | ||
|
|
ec39f0fa06 | ||
|
|
439280947c | ||
|
|
5abae50be5 | ||
|
|
082e0c0486 | ||
|
|
2044166967 | ||
|
|
f33d4fbc1c | ||
|
|
0f2ef341ce | ||
|
|
c7f835da0d | ||
|
|
647e67f6e8 | ||
|
|
bf9c02bc16 | ||
|
|
1d5c26e67c | ||
|
|
b85233359f | ||
|
|
7335914695 | ||
|
|
b4e673baab | ||
|
|
767c4402e7 | ||
|
|
a9967d53b1 | ||
|
|
00fc3ed1a1 | ||
|
|
98d76ad45e | ||
|
|
0c9643fd7e | ||
|
|
ce5dee39ae | ||
|
|
e57d2a9ee2 | ||
|
|
f827e23ccc | ||
|
|
f8726640c3 | ||
|
|
4778482cdd | ||
|
|
7297cd09b6 | ||
|
|
08eeeb54dc | ||
|
|
abbec8120e | ||
|
|
23a8a33e5f | ||
|
|
758347f7bc | ||
|
|
1b6c0167de | ||
|
|
8bce0922d9 | ||
|
|
f41268cdde | ||
|
|
719b079cbc | ||
|
|
7bd5fa387d | ||
|
|
5fabbaf7ab | ||
|
|
215dc42294 | ||
|
|
09a75e89c9 | ||
|
|
559fe2d550 | ||
|
|
314916279a | ||
|
|
dbf1a1bb36 | ||
|
|
8f2b8dd013 | ||
|
|
8039852aa3 | ||
|
|
d3b567953d | ||
|
|
5064ee936a | ||
|
|
86da9b0b29 | ||
|
|
acac203e42 | ||
|
|
cdd1c8cb61 | ||
|
|
439753eb6d | ||
|
|
e30700de66 | ||
|
|
994d1723b6 | ||
|
|
2d40a89c55 | ||
|
|
802cc2b5f5 | ||
|
|
2ffca90d29 | ||
|
|
ec90df9c58 | ||
|
|
0245e7d1af | ||
|
|
94a08d86a0 | ||
|
|
bcc7bedbc9 | ||
|
|
a878a4f3f9 | ||
|
|
a7d03cf8c0 | ||
|
|
033d91ed71 | ||
|
|
392a350eab | ||
|
|
f33df59f49 | ||
|
|
cd75e85bec | ||
|
|
cb31121fe7 | ||
|
|
d5682a5f65 | ||
|
|
f6d06ba82a | ||
|
|
bbee8d7caa | ||
|
|
5b5888cf65 | ||
|
|
48d9aaa871 | ||
|
|
f44083aeba | ||
|
|
810dbcc1d7 | ||
|
|
449ab01bc2 | ||
|
|
2686b2b02d | ||
|
|
e9819fac87 | ||
|
|
4e39142fb3 | ||
|
|
e52f646558 | ||
|
|
02d4ff524a | ||
|
|
05b7ec77c8 | ||
|
|
f6aa8ceba6 | ||
|
|
b3ec325e95 | ||
|
|
e31465a1b5 | ||
|
|
84ad5b4db8 | ||
|
|
855b66c459 | ||
|
|
46f767d79c | ||
|
|
785f74ed21 | ||
|
|
699da37f06 | ||
|
|
c3badba73b | ||
|
|
5f0e9a355b | ||
|
|
39d759595d | ||
|
|
fe9dd75a23 | ||
|
|
2139147dcd | ||
|
|
c71ca7f4d5 | ||
|
|
705efb4340 | ||
|
|
ec1450cec1 | ||
|
|
290bf78db3 | ||
|
|
02c1fe46f3 | ||
|
|
7315dd80fc | ||
|
|
a496c0f2b4 | ||
|
|
ab0239ba84 | ||
|
|
f2f3abdb32 | ||
|
|
5a35b55d7a | ||
|
|
02aa4a237f | ||
|
|
cc88d382e6 | ||
|
|
a95fa2efc1 | ||
|
|
45e2b93724 | ||
|
|
fa3481fa99 | ||
|
|
eed94ec34a | ||
|
|
a6a7a26ebc | ||
|
|
7ed7b25268 | ||
|
|
703ae30a27 | ||
|
|
6bf8785f22 | ||
|
|
53768555a2 | ||
|
|
a70f4e303d | ||
|
|
7a848cf6a1 | ||
|
|
0be48568d7 | ||
|
|
1fd0963401 | ||
|
|
d2d4b442d2 | ||
|
|
9d6574d3ba | ||
|
|
f2ca67aba4 | ||
|
|
6073b20d65 | ||
|
|
b329709776 | ||
|
|
932f9fc443 | ||
|
|
c0c0a2d2d9 | ||
|
|
5cecb7adb6 | ||
|
|
26357a8d7b | ||
|
|
9819fd5bb1 | ||
|
|
adbdb89917 | ||
|
|
b7c79800eb | ||
|
|
55e1f65bbd | ||
|
|
d018b0f5e5 | ||
|
|
12745c207d | ||
|
|
f6f3c9c3e3 | ||
|
|
8bb825ef02 | ||
|
|
f1192279bf |
19
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
19
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
wrapperVersion=3.3.2
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||
66
README.md
66
README.md
@@ -57,15 +57,20 @@ We will set up the following:
|
||||
- Client - the client is the application used to _play the game_, i.e. MapleStory.exe.
|
||||
|
||||
### 1 - Database
|
||||
You will start by installing the database server and client, and then run some scripts to prepare it for the server.
|
||||
You will start by installing the database server and database client. Then you will connect to the server with the client to create a new database schema.
|
||||
|
||||
#### Steps
|
||||
|
||||
1. Download and install [MySQL Community Server 8+](https://dev.mysql.com/downloads/mysql/). You will have to set a root password, make sure you don't lose it because you will need it later.
|
||||
1. Download and install [MySQL Community Server 8+](https://dev.mysql.com/downloads/mysql/). You will have to set a root password. Make sure you don't lose it because you will need it later.
|
||||
2. Download and install [HeidiSQL](https://www.heidisql.com/download.php).
|
||||
3. Open HeidiSQL and connect to the database ("New" -> "Session in root folder" -> fill in password -> "Open").
|
||||
4. Run all four scripts located in database/sql in order. Starting with ``1-db_database.sql`` and ending with ``4-db-admin.sql``. In HeidiSQL: "File" -> "Run SQL File...".
|
||||
5. The database is ready!
|
||||
3. Connect to the database:
|
||||
1. Open HeidiSQL
|
||||
2. Create a new Session: "New" -> fill in your password -> "Save"
|
||||
3. Connect to the database: click on your saved session -> "Open"
|
||||
4. Create a new database schema:
|
||||
1. In the opened session, right-click on the session name in the menu on the left
|
||||
2. "Create new" -> "Database" -> database name should be "cosmic" -> "OK"
|
||||
5. Done. The database is now ready. Once the Cosmic server starts, it will create tables and populate some of them with initial data.
|
||||
|
||||
### 2 - Server
|
||||
You will start by cloning the repository, then configure the database properties and lastly start the server.
|
||||
@@ -88,39 +93,22 @@ Support for Docker is also provided out of the box, as an alternative to running
|
||||
|
||||
Making changes becomes a bit more tedious though as you have to rebuild the server image via `docker compose up --build`.
|
||||
|
||||
On the first launch, the database container will run the scripts which may take so long that the server fails to start. In that case, just wait until the database is done running the scripts and then retry (Ctrl+C and re-run the command).
|
||||
|
||||
#### Jar
|
||||
Another option is to start the server from a terminal by running a jar file. You first need to build the jar file from source which requires [Maven](https://maven.apache.org/).
|
||||
Another option is to start the server from a terminal by running a jar file. You first need to build the jar file from source which requires [Maven](https://maven.apache.org/). Fortunately, [Maven Wrapper](https://maven.apache.org/wrapper/) is provided so you don't have to install Maven separately.
|
||||
|
||||
Building the jar file is as easy as running ``mvn clean package``. The project is configured to produce a "fat" jar which contains all dependencies (by utilizing the _maven-assembly-plugin_). Note that the WZ XML files are __not__ included in the jar.
|
||||
Building the jar file is as easy as running ``./mvnw.cmd clean package``. The project is configured to produce a "fat" jar which contains all dependencies (by utilizing the _maven-assembly-plugin_). Note that the WZ XML files are __not__ included in the jar.
|
||||
|
||||
To run the jar, a ``launch.bat`` file is provided for convenience. Simply double-click it and the server will start in a new terminal window.
|
||||
|
||||
Alternatively, run the jar file from the terminal. Just remember to provide the `wz-path` system property pointing to your wz directory.
|
||||
|
||||
### 3 - Client
|
||||
You will start by installing the game with the old installer, then overwrite some WZ files with our custom ones, and lastly get the localhost executable in place.
|
||||
The client files are located in a separate repository: https://github.com/P0nk/Cosmic-client
|
||||
|
||||
#### Steps
|
||||
|
||||
1. Download _MapleGlobal-v83-setup.exe_ from my [Google Drive](https://drive.google.com/drive/folders/1hgnb92MGL6xqEp9szEMBh0K9pSJcJ6IT). This is the official installer from back then.
|
||||
2. Install it in a directory of your choice.
|
||||
3. Delete the following files from the installation directory: _HShield_ (entire directory), _ASPLnchr.exe_, _MapleStory.exe_, and _Patcher.exe_.
|
||||
4. Download _CosmicWZ-2024-07-17-v0.14.0.zip_ from my [Google Drive](https://drive.google.com/drive/folders/1hgnb92MGL6xqEp9szEMBh0K9pSJcJ6IT).
|
||||
5. Unzip it and copy all .wz-files into the installation directory. Replace the existing ones.
|
||||
6. Download _HeavenMS-localhost-WINDOW.exe_ from [hostr.co](https://hostr.co/amuX5SLeeVZx). This is a client modified to connect to your localhost instead of Nexon's server (along with some fixes and custom changes).
|
||||
- Your antivirus will likely detect the file as a trojan or similar and automatically delete it. To prevent this from happening, add your _Downloads_ directory and the installation directory as exclusions in your antivirus software. On W11, this is under "Virus & threat protection settings" -> "Add or remove exclusions".
|
||||
7. Move _HeavenMS-localhost-WINDOW.exe_ into the installation directory.
|
||||
8. Done! Double-click the exe and the game should start.
|
||||
- The client may be a bit fiddly. Sometimes it won't start, but if you see "Client connected" in the server console it's a good indication. Try spam-clicking it like 10+ times, that usually works for me.
|
||||
|
||||
**Important note about localhost clients**: these executables are red-flagged by antivirus tools as potentially malicious software.
|
||||
This happens due to the reverse engineering methods that were applied onto these software artifacts.
|
||||
The one provided here has been in use for years already and posed no harm so far, so it is assumed to be safe.
|
||||
Follow the installation guide in the README.
|
||||
|
||||
### 4 - Getting into the game
|
||||
The client has started, and you're looking at the login screen.
|
||||
You have successfully started the client, and you're looking at the login screen.
|
||||
|
||||
#### Logging in
|
||||
At this point, you can log in to the admin account using the following credentials:
|
||||
@@ -129,7 +117,7 @@ At this point, you can log in to the admin account using the following credentia
|
||||
* Pin: "0000"
|
||||
* Pic: "000000"
|
||||
|
||||
Or create a regular account by typing in your desired username & password and attempting to log in. This "automatic registration" feature lets you create new accounts to play around with. It is enabled by default (see _config.yaml_).
|
||||
You can also create a new regular account by typing in your desired username & password and attempting to log in. This "automatic registration" feature lets you create new accounts to play around with. It is enabled by default (see _config.yaml_).
|
||||
|
||||
#### Entering the game
|
||||
Create a new character as you normally would, and then select it to enter the game. Hooray, finally we're in!
|
||||
@@ -144,21 +132,14 @@ That's it, have fun playing around in game!
|
||||
Some slightly more advanced concepts that might be useful once you're up and running.
|
||||
|
||||
### Host on remote server
|
||||
You don't have to host the server on your local machine to play. It's possible to host on a remote server such as a VPS or even a dedicated server.
|
||||
You don't have to host the server on your local machine to play. It's possible to host on a remote server such as a VPS or a dedicated server.
|
||||
|
||||
I leave it to you to figure out the server hosting part, but once you have that running you'll need to edit the client exe to point to your remote server ip.
|
||||
|
||||
#### Edit client ip
|
||||
1. Download and install a hex editor: [HxD](https://mh-nexus.de/en/hxd/)
|
||||
2. Start HxD and open your client exe (I recommend making a copy of it first). At this point you should see a bunch of hex codes and a "Decoded text" column to the right of it.
|
||||
3. Ctrl+f and search for Text-string "127.0.0.1". You should find three occurrences right above each other.
|
||||
4. Place your cursor before the first "127" and start typing the desired ip, overwriting what is already there. Do the same on the other two and click on Save.
|
||||
5. Done! Now the client will attempt to connect to that ip address instead when you launch it.
|
||||
I leave it to you to figure out the server hosting part, but once you have that running you'll need to edit the client ip to point to your remote server ip.
|
||||
|
||||
### WZ files
|
||||
WZ files are the asset/data files required by the client and server. Typically, [HaRepacker-resurrected](https://github.com/lastbattle/Harepacker-resurrected) is used to handle (view, edit, export) the .wz files.
|
||||
WZ files are the asset/data files required by the client and server. Typically, the [HaRepacker-resurrected](https://github.com/lastbattle/Harepacker-resurrected) tool is used to manage (view, edit, export) the .wz files.
|
||||
|
||||
The client can read the .wz files directly, but the server requires them in XML format. The server also does not make use of the sprites, which is the motivation for different kinds of exporting.
|
||||
The client can read the .wz files directly, but the server requires them to be in XML format. The server does not make use of the sprites, which is the motivation for different kinds of exporting.
|
||||
HaRepacker allows you to export to "Private server", which is the .img files packaged in the .wz stripped of sprites and converted to XML. This takes much less disk space.
|
||||
|
||||
This server requires custom .wz files (unfortunately), as you may have noted during installation of the client. The intention is for these to be removed eventually and to solely run on vanilla .wz files.
|
||||
@@ -172,10 +153,3 @@ This server requires custom .wz files (unfortunately), as you may have noted dur
|
||||
Make sure to always export from the client .wz files to the server XML, and not the other way around.
|
||||
|
||||
Editing the client .wz without exporting to the server may lead to strange behavior.
|
||||
|
||||
### Client features
|
||||
For more information about the client and its features, see [HeavenMS on GitHub](https://github.com/ronancpl/HeavenMS#download-items).
|
||||
|
||||
Some notable features:
|
||||
* Opens in window mode by default
|
||||
* Uncapped max speed
|
||||
|
||||
25
config.yaml
25
config.yaml
@@ -165,6 +165,14 @@ server:
|
||||
DB_PASS: ""
|
||||
INIT_CONNECTION_POOL_TIMEOUT: 90 # Seconds
|
||||
|
||||
PG_DB_URL: "jdbc:postgresql://localhost:5432/cosmic"
|
||||
PG_DB_SCHEMA: "cosmic"
|
||||
PG_DB_ADMIN_USERNAME: "cosmic_admin"
|
||||
PG_DB_ADMIN_PASSWORD: "redsnailshell"
|
||||
PG_DB_USERNAME: "cosmic_server"
|
||||
PG_DB_PASSWORD: "bluesnailshell"
|
||||
PG_DB_CLEAN: false # !!! WARNING !!! Deletes the entire database - starts from scratch.
|
||||
|
||||
#Login Configuration
|
||||
WORLDS: 1 #Initial number of worlds on the server.
|
||||
WLDLIST_SIZE: 21 #Max possible worlds on the server.
|
||||
@@ -185,7 +193,6 @@ server:
|
||||
BYPASS_PIN_EXPIRATION: 15 #Enables PIN bypass, which will remain active for that account by that client machine for N minutes. Set 0 to disable.
|
||||
|
||||
AUTOMATIC_REGISTER: true #Automatically register players when they login with a nonexistent username.
|
||||
BCRYPT_MIGRATION: true #Performs a migration from old SHA-1 and SHA-512 password to bcrypt.
|
||||
COLLECTIVE_CHARSLOT: false #Available character slots are contabilized globally rather than per world server.
|
||||
DETERRED_MULTICLIENT: false #Enables detection of multi-client and suspicious remote IP on the login system.
|
||||
#Besides blocking logging in with several client sessions on the same machine, this also blocks suspicious login attempts for players that tries to login on an account using several diferent remote addresses.
|
||||
@@ -234,7 +241,6 @@ server:
|
||||
USE_AUTOBAN: false #Commands the server to detect infractors automatically.
|
||||
USE_AUTOBAN_LOG: true #Log autoban related messages. Still logs even with USE_AUTOBAN disabled.
|
||||
USE_EXP_GAIN_LOG: false #Logs characters exp gains; logs world rate & coupon exp, total gained exp, and current exp, level can be calculated from "ExpTable".
|
||||
USE_AUTOSAVE: true #Enables server autosaving feature (saves characters to DB each 1 hour).
|
||||
USE_SERVER_AUTOASSIGNER: false #HeavenMS-builtin autoassigner, uses algorithm based on distributing AP accordingly with required secondary stat on equipments.
|
||||
USE_REFRESH_RANK_MOVE: true
|
||||
USE_ENFORCE_ADMIN_ACCOUNT: false #Forces accounts having GM characters to be treated as a "GM account" by the client (localhost). Some of the GM account perks is the ability to FLY, but unable to TRADE.
|
||||
@@ -246,10 +252,8 @@ server:
|
||||
USE_ENFORCE_ITEM_SUGGESTION: false #Forces the Owl of Minerva and the Cash Shop to always display the defined item array instead of those featured by the players.
|
||||
USE_ENFORCE_UNMERCHABLE_CASH: true #Forces players to not sell CASH items via merchants, drops of it disappears.
|
||||
USE_ENFORCE_UNMERCHABLE_PET: true #Forces players to not sell pets via merchants, drops of it disappears. (since non-named pets gets dirty name and other possible DB-related issues)
|
||||
USE_ENFORCE_MERCHANT_SAVE: true #Forces automatic DB save on merchant owners, at every item movement on shop.
|
||||
USE_ENFORCE_MDOOR_POSITION: false #Forces mystic door to be spawned near spawnpoints.
|
||||
USE_SPAWN_CLEAN_MDOOR: false #Makes mystic doors to be spawned without deploy animation. This clears disconnecting issues that may happen when trying to cancel doors a couple seconds after deployment.
|
||||
USE_SPAWN_LOOT_ON_ANIMATION: false #Makes loot appear some time after the mob has been killed (following the mob death animation, instead of instantly).
|
||||
USE_SPAWN_RELEVANT_LOOT: true #Forces to only spawn loots that are collectable by the player or any of their party members.
|
||||
USE_ERASE_PERMIT_ON_OPENSHOP: true #Forces "shop permit" item to be consumed when player deploy his/her player shop.
|
||||
USE_ERASE_UNTRADEABLE_DROP: true #Forces flagged untradeable items to disappear when dropped.
|
||||
@@ -284,10 +288,6 @@ server:
|
||||
USE_MAKER_PERMISSIVE_ATKUP: false #Allows players to use attack-based strengthening gems on non-weapon items.
|
||||
USE_MAKER_FEE_HEURISTICS: true #Apply compiled values for stimulants and reagents into the Maker fee calculations (max error revolves around 50k mesos). Set false to use basic constant values instead (results are never higher than requested by the client-side).
|
||||
|
||||
#Custom Configuration
|
||||
USE_ENABLE_CUSTOM_NPC_SCRIPT: false #Enables usage of custom HeavenMS NPC scripts (Agent E, Coco, etc). Will not disable Abdula (it's actually useful for the gameplay) or quests.
|
||||
USE_STARTER_MERGE: false #Allows any players to use the Equipment Merge custom mechanic (as opposed to the high-level, Maker lv3 requisites).
|
||||
|
||||
#Commands Configuration
|
||||
BLOCK_GENERATE_CASH_ITEM: false #Prevents creation of cash items with the item/drop command.
|
||||
USE_WHOLE_SERVER_RANKING: false #Enables a ranking pool made from every character registered on the server for the "ranks" command, instead of separated by worlds.
|
||||
@@ -345,7 +345,7 @@ server:
|
||||
USE_ENHANCED_CRAFTING: false #Apply chaos scroll on every equip crafted.
|
||||
SCROLL_CHANCE_ROLLS: 1 #Number of rolls for success on a scroll, set 1 for default.
|
||||
CHSCROLL_STAT_RATE: 1 #Number of rolls of stat upgrade on a successfully applied chaos scroll, set 1 for default.
|
||||
CHSCROLL_STAT_RANGE: 6 #Stat upgrade range (-N, N) on chaos scrolls.
|
||||
CHSCROLL_STAT_RANGE: 5 #Stat upgrade range (-N, N) on chaos scrolls.
|
||||
|
||||
#Beginner Skills Configuration
|
||||
USE_ULTRA_NIMBLE_FEET: false #Massive speed & jump upgrade.
|
||||
@@ -360,7 +360,6 @@ server:
|
||||
USE_FULL_HOLY_SYMBOL: false #Holy symbol doesn't require EXP sharers to work in full.
|
||||
|
||||
#Character Configuration
|
||||
USE_ADD_SLOTS_BY_LEVEL: false #Slots are added each 20 levels.
|
||||
USE_ADD_RATES_BY_LEVEL: false #Rates are added each 20 levels.
|
||||
USE_STACK_COUPON_RATES: false #Multiple coupons effects builds up together.
|
||||
USE_PERFECT_PITCH: false #For lvl 30 or above, each lvlup grants player 1 perfect pitch.
|
||||
@@ -368,12 +367,6 @@ server:
|
||||
#Quest Configuration
|
||||
USE_QUEST_RATE: false #Exp/Meso gained by quests uses fixed server exp/meso rate times quest rate as multiplier, instead of player rates.
|
||||
|
||||
#Quest Points Configuration
|
||||
QUEST_POINT_REPEATABLE_INTERVAL: 25 #Minimum interval between repeatable quest completions for quest points to be awarded.
|
||||
QUEST_POINT_REQUIREMENT: 0 #Exchange factor between N quest points to +1 fame, set 0 to disable the entire quest point mechanism.
|
||||
QUEST_POINT_PER_QUEST_COMPLETE: 0 #Each completed quest awards N quest points, set 0 to disable.
|
||||
QUEST_POINT_PER_EVENT_CLEAR: 0 #Each completed event instance awards N quest points, set 0 to disable.
|
||||
|
||||
#Guild Configuration
|
||||
CREATE_GUILD_MIN_PARTNERS: 6 #Minimum number of members on Guild Headquarters to establish a new guild.
|
||||
CREATE_GUILD_COST: 1500000
|
||||
|
||||
2
database/.gitignore
vendored
Normal file
2
database/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
docker-db-data/*
|
||||
docker-pg-db-data/*
|
||||
3
database/docker-db-data/.gitignore
vendored
3
database/docker-db-data/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
*
|
||||
*/
|
||||
!.gitignore
|
||||
3
database/postgres-scripts/create-db-and-admin-user.sql
Normal file
3
database/postgres-scripts/create-db-and-admin-user.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
CREATE DATABASE cosmic;
|
||||
CREATE USER cosmic_admin WITH CREATEROLE ENCRYPTED PASSWORD 'redsnailshell';
|
||||
GRANT ALL PRIVILEGES ON DATABASE cosmic TO cosmic_admin;
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,316 +0,0 @@
|
||||
#THIS SQL IS OPTIONAL, TO BE USED AFTER 'db_drops.sql'
|
||||
#THIS REQUIRES PROVIDED WZ FILES
|
||||
|
||||
USE `cosmic`;
|
||||
|
||||
# Scroll shop at Asia, chair shop at Kino Konoko, potion shop at T-1337
|
||||
INSERT INTO `shops` (`shopid`,`npcid`) VALUES
|
||||
(2082014,2082014),
|
||||
(9110002,9110002),
|
||||
(9201101,9201101);
|
||||
|
||||
INSERT IGNORE INTO `shopitems` (`shopid`, `itemid`, `price`, `pitch`, `position`) VALUES
|
||||
(2082014, 2040004, 480000, 0, 1),
|
||||
(2082014, 2040025, 500000, 0, 2),
|
||||
(2082014, 2040029, 500000, 0, 3),
|
||||
(2082014, 2040017, 500000, 0, 4),
|
||||
(2082014, 2040301, 400000, 0, 5),
|
||||
(2082014, 2040317, 400000, 0, 6),
|
||||
(2082014, 2040321, 400000, 0, 7),
|
||||
(2082014, 2040413, 400000, 0, 8),
|
||||
(2082014, 2040418, 400000, 0, 9),
|
||||
(2082014, 2040501, 250000, 0, 10),
|
||||
(2082014, 2040513, 250000, 0, 11),
|
||||
(2082014, 2040516, 250000, 0, 12),
|
||||
(2082014, 2040532, 250000, 0, 13),
|
||||
(2082014, 2040613, 400000, 0, 14),
|
||||
(2082014, 2040701, 450000, 0, 15),
|
||||
(2082014, 2040704, 450000, 0, 16),
|
||||
(2082014, 2040707, 450000, 0, 17),
|
||||
(2082014, 2040804, 550000, 0, 18),
|
||||
(2082014, 2040817, 550000, 0, 19),
|
||||
(2082014, 2040914, 480000, 0, 20),
|
||||
(2082014, 2040919, 480000, 0, 21),
|
||||
(2082014, 2041007, 470000, 0, 22),
|
||||
(2082014, 2041010, 470000, 0, 23),
|
||||
(2082014, 2041013, 500000, 0, 24),
|
||||
(2082014, 2041016, 500000, 0, 25),
|
||||
(2082014, 2041019, 500000, 0, 26),
|
||||
(2082014, 2041022, 500000, 0, 27),
|
||||
(2082014, 2044901, 520000, 0, 28),
|
||||
(2082014, 2044701, 520000, 0, 29),
|
||||
(2082014, 2043001, 520000, 0, 30),
|
||||
(2082014, 2043801, 520000, 0, 31),
|
||||
(2082014, 2044601, 520000, 0, 32),
|
||||
(2082014, 2040727, 50000, 0, 33),
|
||||
(2082014, 2041058, 50000, 0, 34),
|
||||
(2082014, 2040807, 1000000, 0, 35),
|
||||
(2082014, 2040005, 22000, 0, 36),
|
||||
(2082014, 2040026, 23000, 0, 37),
|
||||
(2082014, 2040031, 23000, 0, 38),
|
||||
(2082014, 2040016, 23000, 0, 39),
|
||||
(2082014, 2040302, 25000, 0, 40),
|
||||
(2082014, 2040318, 25000, 0, 41),
|
||||
(2082014, 2040323, 25000, 0, 42),
|
||||
(2082014, 2040412, 20000, 0, 43),
|
||||
(2082014, 2040419, 20000, 0, 44),
|
||||
(2082014, 2040502, 25000, 0, 45),
|
||||
(2082014, 2040514, 25000, 0, 46),
|
||||
(2082014, 2040517, 25000, 0, 47),
|
||||
(2082014, 2040534, 25000, 0, 48),
|
||||
(2082014, 2040612, 20000, 0, 49),
|
||||
(2082014, 2040702, 20000, 0, 50),
|
||||
(2082014, 2040705, 25000, 0, 51),
|
||||
(2082014, 2040708, 20000, 0, 52),
|
||||
(2082014, 2040805, 100000, 0, 53),
|
||||
(2082014, 2040816, 100000, 0, 54),
|
||||
(2082014, 2040915, 55000, 0, 55),
|
||||
(2082014, 2040920, 55000, 0, 56),
|
||||
(2082014, 2041008, 38000, 0, 57),
|
||||
(2082014, 2041011, 38000, 0, 58),
|
||||
(2082014, 2041014, 40000, 0, 59),
|
||||
(2082014, 2041017, 40000, 0, 60),
|
||||
(2082014, 2041020, 40000, 0, 61),
|
||||
(2082014, 2041023, 40000, 0, 62),
|
||||
(2082014, 2044902, 50000, 0, 63),
|
||||
(2082014, 2044702, 50000, 0, 64),
|
||||
(2082014, 2043002, 50000, 0, 65),
|
||||
(2082014, 2043802, 50000, 0, 66),
|
||||
(2082014, 2044602, 50000, 0, 67),
|
||||
(2082014, 2049200, 170000, 0, 68),
|
||||
(2082014, 2049201, 220000, 0, 69),
|
||||
(2082014, 2049202, 170000, 0, 70),
|
||||
(2082014, 2049203, 220000, 0, 71),
|
||||
(2082014, 2049204, 170000, 0, 72),
|
||||
(2082014, 2049205, 220000, 0, 73),
|
||||
(2082014, 2049206, 170000, 0, 74),
|
||||
(2082014, 2049207, 220000, 0, 75),
|
||||
(2082014, 2049208, 140000, 0, 76),
|
||||
(2082014, 2049209, 170000, 0, 77),
|
||||
(2082014, 2049210, 140000, 0, 78),
|
||||
(2082014, 2049211, 170000, 0, 79),
|
||||
(2082014, 2040101, 540000, 0, 80),
|
||||
(2082014, 2040100, 700000, 0, 81),
|
||||
(2082014, 2040106, 540000, 0, 82),
|
||||
(2082014, 2040105, 700000, 0, 83),
|
||||
(2082014, 2040201, 540000, 0, 84),
|
||||
(2082014, 2040200, 700000, 0, 85),
|
||||
(2082014, 2040206, 540000, 0, 86),
|
||||
(2082014, 2040205, 700000, 0, 87),
|
||||
(2082014, 2070016, 120000000, 0, 88),
|
||||
(2082014, 2070018, 190000000, 0, 89),
|
||||
(2082014, 2030007, 1800000, 0, 90),
|
||||
(2082014, 4001017, 60000000, 0, 91);
|
||||
|
||||
UPDATE shopitems SET price = 11*price WHERE (`position` >= 33 and `position` <= 79 and `shopid` = 2082014);
|
||||
|
||||
INSERT IGNORE INTO `shopitems` (`shopid`, `itemid`, `price`, `pitch`, `position`) VALUES
|
||||
(1031100, 3010015, 20000, 0, 100),
|
||||
(9110002, 3010019, 7700000, 0, 92),
|
||||
(9110002, 3010008, 10000000, 0, 96),
|
||||
(9110002, 3010007, 10000000, 0, 100),
|
||||
(9201020, 3010009, 4200000, 0, 96),
|
||||
(9201020, 3010014, 7000000, 0, 100),
|
||||
(1081000, 3010013, 4000000, 0, 100),
|
||||
(9201101, 2022338, 2100000, 0, 100),
|
||||
(9201101, 2022339, 2800000, 0, 104),
|
||||
(9201101, 2022340, 4000000, 0, 108),
|
||||
(9201101, 2022341, 2800000, 0, 112),
|
||||
(9201101, 2022342, 2000000, 0, 116),
|
||||
(9201101, 2022343, 4700000, 0, 120),
|
||||
(9201101, 2022344, 5000000, 0, 124),
|
||||
(9201101, 2022345, 4000000, 0, 128),
|
||||
(9201101, 2002028, 5000000, 0, 132),
|
||||
(9201101, 2022544, 100000, 0, 136),
|
||||
(9201101, 2022545, 4400000, 0, 140),
|
||||
(9201101, 2020027, 2100000, 0, 144),
|
||||
(9201101, 2022113, 1800000, 0, 148),
|
||||
(9201101, 2022121, 12000000, 0, 152),
|
||||
(9201101, 2022123, 12000000, 0, 156),
|
||||
(9201101, 2022277, 5300000, 0, 160),
|
||||
(9201101, 2012008, 4200000, 0, 164),
|
||||
(9201101, 2022251, 3800000, 0, 168);
|
||||
|
||||
-- Thanks to Vcoc
|
||||
-- GMShop: Sacks, GmEquip, Cheese & Onyx, Utils,
|
||||
-- Arrows, Bullets, Throwings and Capsules,
|
||||
-- Others, Equips, Mounts, Scrolls.
|
||||
|
||||
DELETE FROM `shopitems` WHERE `shopid`=1337;
|
||||
INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `position`) VALUES
|
||||
(1337, 2100036, 1, 1),
|
||||
(1337, 2100035, 1, 2),
|
||||
(1337, 2100034, 1, 3),
|
||||
(1337, 2100033, 1, 4),
|
||||
(1337, 2100007, 1, 5),
|
||||
(1337, 2100006, 1, 6),
|
||||
(1337, 2100005, 1, 7),
|
||||
(1337, 2100004, 1, 8),
|
||||
(1337, 2100003, 1, 9),
|
||||
(1337, 2100002, 1, 10),
|
||||
(1337, 2100001, 1, 11),
|
||||
(1337, 1002959, 1, 12),
|
||||
(1337, 1002140, 1, 13),
|
||||
(1337, 1042003, 1, 14),
|
||||
(1337, 1062007, 1, 15),
|
||||
(1337, 1322013, 1, 16),
|
||||
(1337, 1072010, 1, 17),
|
||||
(1337, 2022179, 1, 18),
|
||||
(1337, 2022273, 1, 19),
|
||||
(1337, 2041200, 1, 20),
|
||||
(1337, 4006001, 1, 21),
|
||||
(1337, 4001017, 1, 22),
|
||||
(1337, 4031179, 1, 23),
|
||||
(1337, 2070018, 1, 24),
|
||||
(1337, 2060004, 1, 25),
|
||||
(1337, 2061004, 1, 26),
|
||||
(1337, 2330005, 1, 27),
|
||||
(1337, 2332000, 1, 28),
|
||||
(1337, 2331000, 1, 29),
|
||||
(1337, 5072000, 1, 30),
|
||||
(1337, 5390000, 1, 31),
|
||||
(1337, 5390001, 1, 32),
|
||||
(1337, 5390002, 1, 33),
|
||||
(1337, 5390005, 1, 34),
|
||||
(1337, 5390006, 1, 35),
|
||||
(1337, 1492013, 1, 36),
|
||||
(1337, 1482013, 1, 37),
|
||||
(1337, 1452044, 1, 38),
|
||||
(1337, 1472052, 1, 39),
|
||||
(1337, 1462039, 1, 40),
|
||||
(1337, 1332050, 1, 41),
|
||||
(1337, 1312031, 1, 42),
|
||||
(1337, 1322052, 1, 43),
|
||||
(1337, 1302059, 1, 44),
|
||||
(1337, 1442045, 1, 45),
|
||||
(1337, 1432038, 1, 46),
|
||||
(1337, 1382036, 1, 47),
|
||||
(1337, 1412026, 1, 48),
|
||||
(1337, 1422028, 1, 49),
|
||||
(1337, 1402036, 1, 50),
|
||||
(1337, 1372032, 1, 51),
|
||||
(1337, 1122000, 1, 52),
|
||||
(1337, 1082149, 1, 53),
|
||||
(1337, 1912000, 1, 54),
|
||||
(1337, 1902000, 1, 55),
|
||||
(1337, 1902001, 1, 56),
|
||||
(1337, 1902002, 1, 57),
|
||||
(1337, 1912005, 1, 58),
|
||||
(1337, 1902005, 1, 59),
|
||||
(1337, 1902006, 1, 60),
|
||||
(1337, 1902007, 1, 61),
|
||||
(1337, 1912011, 1, 62),
|
||||
(1337, 1902015, 1, 63),
|
||||
(1337, 1902016, 1, 64),
|
||||
(1337, 1902017, 1, 65),
|
||||
(1337, 1902018, 1, 66),
|
||||
(1337, 2044908, 1, 67),
|
||||
(1337, 2044815, 1, 68),
|
||||
(1337, 2044512, 1, 69),
|
||||
(1337, 2044712, 1, 70),
|
||||
(1337, 2044612, 1, 71),
|
||||
(1337, 2043312, 1, 72),
|
||||
(1337, 2043117, 1, 73),
|
||||
(1337, 2043217, 1, 74),
|
||||
(1337, 2043023, 1, 75),
|
||||
(1337, 2044417, 1, 76),
|
||||
(1337, 2044317, 1, 77),
|
||||
(1337, 2043812, 1, 78),
|
||||
(1337, 2044117, 1, 79),
|
||||
(1337, 2044217, 1, 80),
|
||||
(1337, 2044025, 1, 81),
|
||||
(1337, 2043712, 1, 82),
|
||||
(1337, 2340000, 1, 83),
|
||||
(1337, 2040807, 1, 84),
|
||||
(1337, 2210032, 1, 85),
|
||||
(1337, 2050004, 1, 86);
|
||||
|
||||
-- Thanks to DietStory v1.02 dev team
|
||||
INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `pitch`, `position`) VALUES
|
||||
(1200001, 3010001, 1000, 0, 1),
|
||||
(1200001, 1092003, 2000, 0, 2),
|
||||
(1200001, 1072063, 10000, 0, 3),
|
||||
(1200001, 1072062, 10000, 0, 4),
|
||||
(1200001, 1072017, 10000, 0, 5),
|
||||
(1200001, 1072049, 5000, 0, 6),
|
||||
(1200001, 1072048, 5000, 0, 7),
|
||||
(1200001, 1072008, 5000, 0, 8),
|
||||
(1200001, 1072005, 50, 0, 9),
|
||||
(1200001, 1072038, 50, 0, 10),
|
||||
(1200001, 1072037, 50, 0, 11),
|
||||
(1200001, 1072001, 50, 0, 12),
|
||||
(1200001, 1062001, 4800, 0, 13),
|
||||
(1200001, 1062000, 4800, 0, 14),
|
||||
(1200001, 1060004, 2800, 0, 15),
|
||||
(1200001, 1060007, 1000, 0, 16),
|
||||
(1200001, 1041012, 3000, 0, 17),
|
||||
(1200001, 1041004, 3000, 0, 18),
|
||||
(1200001, 1040014, 3000, 0, 19),
|
||||
(1200001, 1040013, 3000, 0, 20),
|
||||
(1200001, 1002001, 3000, 0, 21),
|
||||
(1200001, 1002019, 2000, 0, 22),
|
||||
(1200001, 1002134, 800, 0, 23),
|
||||
(1200001, 1002133, 800, 0, 24),
|
||||
(1200001, 1002132, 800, 0, 25),
|
||||
(1200001, 1002069, 450, 0, 26),
|
||||
(1200001, 1002068, 450, 0, 27),
|
||||
(1200001, 1002067, 450, 0, 28),
|
||||
(1200001, 1002066, 450, 0, 29),
|
||||
(1200001, 1002014, 1000, 0, 30),
|
||||
(1200001, 1002008, 500, 0, 31),
|
||||
(1200001, 1332007, 1000, 0, 32),
|
||||
(1200001, 1312000, 3000, 0, 33),
|
||||
(1200001, 1302007, 3000, 0, 34),
|
||||
(1200001, 1322005, 50, 0, 35),
|
||||
(1200001, 1312004, 50, 0, 36),
|
||||
(1200001, 1302000, 50, 0, 37),
|
||||
(1200002, 2330000, 600, 0, 104),
|
||||
(1200002, 2070000, 500, 0, 108),
|
||||
(1200002, 2061000, 1, 0, 120),
|
||||
(1200002, 2060000, 1, 0, 124),
|
||||
(1200002, 2030000, 400, 0, 132),
|
||||
(1200002, 2020028, 3000, 0, 136),
|
||||
(1200002, 2010004, 310, 0, 140),
|
||||
(1200002, 2010003, 100, 0, 144),
|
||||
(1200002, 2010001, 106, 0, 148),
|
||||
(1200002, 2010002, 50, 0, 152),
|
||||
(1200002, 2010000, 30, 0, 156),
|
||||
(1200002, 2002005, 500, 0, 160),
|
||||
(1200002, 2002004, 500, 0, 164),
|
||||
(1200002, 2002002, 500, 0, 168),
|
||||
(1200002, 2002001, 400, 0, 172),
|
||||
(1200002, 2002000, 500, 0, 176),
|
||||
(1200002, 2000006, 620, 0, 180),
|
||||
(1200002, 2000003, 200, 0, 184),
|
||||
(1200002, 2000002, 320, 0, 188),
|
||||
(1200002, 2000001, 160, 0, 192),
|
||||
(1200002, 2000000, 50, 0, 196),
|
||||
(1301000, 2330000, 600, 0, 104),
|
||||
(1301000, 2070000, 500, 0, 108),
|
||||
(1301000, 2061000, 1, 0, 112),
|
||||
(1301000, 2060000, 1, 0, 116),
|
||||
(1301000, 2030000, 400, 0, 124),
|
||||
(1301000, 2022000, 1650, 0, 128),
|
||||
(1301000, 2022003, 1100, 0, 132),
|
||||
(1301000, 2002005, 500, 0, 136),
|
||||
(1301000, 2002004, 500, 0, 140),
|
||||
(1301000, 2002002, 500, 0, 144),
|
||||
(1301000, 2002001, 400, 0, 148),
|
||||
(1301000, 2002000, 500, 0, 152),
|
||||
(1301000, 2000006, 620, 0, 156),
|
||||
(1301000, 2000003, 200, 0, 160),
|
||||
(1301000, 2000002, 320, 0, 164),
|
||||
(1301000, 2000001, 160, 0, 168),
|
||||
(1301000, 2000000, 50, 0, 172);
|
||||
|
||||
# adding missing pirate items at Singapore npc's
|
||||
INSERT INTO `shopitems` ( `shopid`, `itemid`, `price`, `pitch`, `position`) VALUES
|
||||
(9270019, 1492006, 160000, 0, 80),
|
||||
(9270019, 1492005, 100000, 0, 84),
|
||||
(9270019, 1492004, 75000, 0, 88),
|
||||
(9270019, 1482006, 150000, 0, 92),
|
||||
(9270019, 1482005, 100000, 0, 96),
|
||||
(9270019, 1482004, 75000, 0, 100),
|
||||
(9270020, 1052113, 120000, 0, 92),
|
||||
(9270020, 1052110, 100000, 0, 96),
|
||||
(9270020, 1002625, 75000, 0, 100);
|
||||
@@ -1,87 +0,0 @@
|
||||
-- MySQL dump 10.13 Distrib 8.0.22, for Win64 (x86_64)
|
||||
--
|
||||
-- Host: 127.0.0.1 Database: cosmic
|
||||
-- ------------------------------------------------------
|
||||
-- Server version 8.0.19
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!50503 SET NAMES utf8 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
USE `cosmic`;
|
||||
|
||||
--
|
||||
-- Dumping data for table `accounts`
|
||||
--
|
||||
|
||||
LOCK TABLES `accounts` WRITE;
|
||||
/*!40000 ALTER TABLE `accounts` DISABLE KEYS */;
|
||||
INSERT INTO `accounts` VALUES (1,'admin','$2y$12$aFD9BDeUocDMY1X4tDYDyeJw/HhkQwCQWs3KAY7gCaRG0cpqJcaL.','0000','000000',0,'2021-05-24 00:00:01','2021-05-24 00:00:02','2005-05-11',0,NULL,NULL,1000000,1000000,1000000,3,0,'2005-05-11 03:00:00',0,1,NULL,0,NULL,0,NULL,NULL,0,0,'1234-5678',2);
|
||||
/*!40000 ALTER TABLE `accounts` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Dumping data for table `characters`
|
||||
--
|
||||
|
||||
LOCK TABLES `characters` WRITE;
|
||||
/*!40000 ALTER TABLE `characters` DISABLE KEYS */;
|
||||
INSERT INTO `characters` VALUES (1,1,0,'Admin',1,0,0,12,5,4,4,50,5,50,5,0,0,0,0,0,0,0,30030,20000,0,'0,0,0,0,0,0,0,0,0,0',10000,2,6,-1,25,'2021-05-24 00:00:03',1,0,1,0,0,5,0,4,1,0,0,0,0,0,0,0,0,0,0,24,24,24,24,-1,0,5,0,0,0,0,0,0,0,0,0,0,0,'','2021-05-24 00:00:04','2015-01-01 05:00:00',1,0);
|
||||
/*!40000 ALTER TABLE `characters` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Dumping data for table `inventoryequipment`
|
||||
--
|
||||
|
||||
LOCK TABLES `inventoryequipment` WRITE;
|
||||
/*!40000 ALTER TABLE `inventoryequipment` DISABLE KEYS */;
|
||||
INSERT INTO `inventoryequipment` VALUES (17,22,7,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,1,0,-1),(18,23,7,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,-1),(19,24,5,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,-1),(20,25,7,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,0,0,0,1,0,-1);
|
||||
/*!40000 ALTER TABLE `inventoryequipment` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Dumping data for table `inventoryitems`
|
||||
--
|
||||
|
||||
LOCK TABLES `inventoryitems` WRITE;
|
||||
/*!40000 ALTER TABLE `inventoryitems` DISABLE KEYS */;
|
||||
INSERT INTO `inventoryitems` VALUES (21,1,1,NULL,4161001,4,1,1,'',-1,0,-1,''),(22,1,1,NULL,1040002,-1,-5,1,'',-1,0,-1,''),(23,1,1,NULL,1060002,-1,-6,1,'',-1,0,-1,''),(24,1,1,NULL,1072001,-1,-7,1,'',-1,0,-1,''),(25,1,1,NULL,1302000,-1,-11,1,'',-1,0,-1,'');
|
||||
/*!40000 ALTER TABLE `inventoryitems` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Dumping data for table `keymap`
|
||||
--
|
||||
|
||||
LOCK TABLES `keymap` WRITE;
|
||||
/*!40000 ALTER TABLE `keymap` DISABLE KEYS */;
|
||||
INSERT INTO `keymap` VALUES (161,1,18,4,0),(162,1,65,6,106),(163,1,2,4,10),(164,1,23,4,1),(165,1,3,4,12),(166,1,4,4,13),(167,1,5,4,18),(168,1,6,4,24),(169,1,16,4,8),(170,1,17,4,5),(171,1,19,4,4),(172,1,25,4,19),(173,1,26,4,14),(174,1,27,4,15),(175,1,31,4,2),(176,1,34,4,17),(177,1,35,4,11),(178,1,37,4,3),(179,1,38,4,20),(180,1,40,4,16),(181,1,43,4,9),(182,1,44,5,50),(183,1,45,5,51),(184,1,46,4,6),(185,1,50,4,7),(186,1,56,5,53),(187,1,59,6,100),(188,1,60,6,101),(189,1,61,6,102),(190,1,62,6,103),(191,1,63,6,104),(192,1,64,6,105),(193,1,57,5,54),(194,1,48,4,22),(195,1,29,5,52),(196,1,7,4,21),(197,1,24,4,25),(198,1,33,4,26),(199,1,41,4,23),(200,1,39,4,27);
|
||||
/*!40000 ALTER TABLE `keymap` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Dumping data for table `storages`
|
||||
--
|
||||
|
||||
LOCK TABLES `storages` WRITE;
|
||||
/*!40000 ALTER TABLE `storages` DISABLE KEYS */;
|
||||
INSERT INTO `storages` VALUES (1,1,0,4,0);
|
||||
/*!40000 ALTER TABLE `storages` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
@@ -1,602 +0,0 @@
|
||||
Oblivion Monk Trainee : Dark Katinas (Male)
|
||||
Star Pixie : Star Pixie Starpiece
|
||||
Star Pixie : Blue White-Line Boots
|
||||
Spirit Viking : Scroll for Knuckler for Accuracy 10%
|
||||
Spirit Viking : Spirit Viking Card
|
||||
Spirit Viking : Dark Battle Lord
|
||||
Spirit Viking : Heaven Justice
|
||||
Iron Boar : Maroon Jangoon Boots
|
||||
Iron Boar : Gold Tail
|
||||
Iron Boar : Justice Katara
|
||||
Voodoo : Steel Pow
|
||||
Green Hobi : Pin Hov Charm
|
||||
Green Hobi : Blue Stud
|
||||
Zombie Lupin : Equip Enhancement Scroll
|
||||
Zombie Lupin : Gold Mask
|
||||
Reinforced Mithril Mutae : Reinforced Mithril Mutae Card
|
||||
Yeti : Gold Tail
|
||||
Blue Kentaurus : Kentaurus Marrow
|
||||
Blue Kentaurus : Infinity Wrath
|
||||
Iruvata : Iruvata Card
|
||||
Iruvata : Heaven Justice
|
||||
Snowman : Red-Bean Soup
|
||||
White Fang : White Fang Tail
|
||||
White Fang : Blue Jangoon Boots
|
||||
Green Cornian : Cornian Marrow
|
||||
Green Cornian : [Mastery Book] Venom
|
||||
Green Cornian : Red Katte (Female)
|
||||
Dodo : Whale Helmet
|
||||
Dodo : Scroll for Overall Armor for STR 60%
|
||||
Dodo : [Mastery Book] Slash Storm 20
|
||||
Dodo : Dark Katte (Female)
|
||||
Ultra Gray : Ultra Gray Card
|
||||
Lorang : Lorang Claws
|
||||
Lorang : Dark Piette Pants
|
||||
Buffoon : Buffoon Grandpa Clock
|
||||
Buffoon : Blue Battle Lord
|
||||
Buffoon : Blue Stud
|
||||
Buffoon : Infinity Wrath
|
||||
Flaming Raccoon : Kinoko Ramen (Salt)
|
||||
Red Kentaurus : Kentaurus Flame
|
||||
Red Kentaurus : Scroll for Knuckler for Accuracy 60%
|
||||
Red Kentaurus : Serpent Tongue
|
||||
Red Kentaurus : Dragon Tail
|
||||
Red Kentaurus : Heavenly Katara
|
||||
Mighty Maple Eater : Fireman Axe
|
||||
Tauromacis : Ascalon Katara
|
||||
Tauromacis : Black Pirate Bandana
|
||||
Krappy : Krappi Card
|
||||
Roloduck : Blue Hunter Armor
|
||||
Roloduck : Blue Hunter Pants
|
||||
Crow : Fish Cake (Skewer)
|
||||
Male Mannequin : Male Mannequin Fedora
|
||||
Male Mannequin : Dark Scroll for Accessory for STR 70%
|
||||
Male Mannequin : Male Mannequin Card
|
||||
Male Mannequin : Majestic Katara
|
||||
Leader B : Leader B Charm
|
||||
Leader B : Kinoko Ramen (Roasted Pork)
|
||||
Typhon : Dark Scroll for Cape for Weapon Def 70%
|
||||
Leader A : Leader A Shades
|
||||
Leader A : Dark Scroll for Cape for Magic Def 70%
|
||||
Leader A : Serpent Tongue
|
||||
Soul Teddy : Scroll for Pole Arm for Accuracy 10%
|
||||
Soul Teddy : Steel Pow
|
||||
Soul Teddy : Heavenly Katara
|
||||
Beetle : Beetle Horn
|
||||
Beetle : Equip Enhancement Scroll
|
||||
Beetle : Ascalon Katara
|
||||
Froscola : Blue Battle Lord
|
||||
White Yeti and King Pepe : Scroll for Pole Arm for Accuracy 10%
|
||||
White Yeti and King Pepe : King Pepe Scroll for One-handed BW Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Dagger Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Two-handed Sword Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Two-handed Axe Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Two-handed BW Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Spear Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Polearm Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Wand Magic Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Staff Magic Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Bow Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Crossbow Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Thief Attacks 60%
|
||||
White Yeti and King Pepe : King Pepe Scroll for Knuckle Attacks 60%
|
||||
Harp : Harp Tail Feather
|
||||
Harp : Scroll for Knuckler for Accuracy 100%
|
||||
Harp : Heavenly Katara
|
||||
Harp : Infinity Wrath
|
||||
Lucida : Green Pirate Bottom
|
||||
Lucida : Brown Stud
|
||||
Lucida : Brown Stud Pants
|
||||
Jr. Grupin : Equip Enhancement Scroll
|
||||
Iron Hog : Iron Hog Metal Hoof
|
||||
Sophilia Doll : Fireman Axe
|
||||
Sophilia Doll : Maroon Jangoon Boots
|
||||
Tiru : Tiru Feather
|
||||
Female Mannequin : Female Mannequin Wig
|
||||
Female Mannequin : Dark Scroll for Accessory for STR 70%
|
||||
Female Mannequin : Female Mannequin Card
|
||||
Female Mannequin : Majestic Katara
|
||||
Poison Golem Level 3 : Poison Golem Card
|
||||
Malady : Malady Experimental Frog
|
||||
Malady : Potential Scroll
|
||||
Malady : Steel Pow
|
||||
Vikerola : Dark Battle Lord
|
||||
Wooden Target Dummy : Wooden Target Dummy Card
|
||||
Wooden Target Dummy : Brown Stud
|
||||
Wooden Target Dummy : Brown Stud Pants
|
||||
Cynical Orange Mushroom : Basic Archer Glove
|
||||
Extra A : Littleman A Badge
|
||||
Extra A : Gold Snowboard
|
||||
Extra B : Littleman B Name Plate
|
||||
Extra B : Fairy Honey
|
||||
Extra B : Brown Jangoon Boots
|
||||
Hodori : Majestic Katara
|
||||
Extra C : Littleman C Necklace
|
||||
Extra D : Cat Eye
|
||||
Extra D : Gold Snowboard
|
||||
Extra D : Serpent Tongue
|
||||
King Sage Cat : Scroll for Pole Arm for Accuracy 10%
|
||||
King Sage Cat : Heaven Justice
|
||||
King Sage Cat : Dragon Tail
|
||||
King Sage Cat : Infinity Wrath
|
||||
Homunscullo : Homunsculer Sand
|
||||
Homunscullo : Homunsculer Blood
|
||||
D. Roy : D. Roy Card
|
||||
Nospeed : Arwen Glass Shoes
|
||||
Ribbon Pig : Pig Ribbon
|
||||
Ribbon Pig : Champion Katara
|
||||
Grim Phantom Watch : [Storybook] Black Book
|
||||
Grim Phantom Watch : Grim Phantom Watch Card
|
||||
Qualm Guardian : Blue Katte (Female)
|
||||
Qualm Guardian : Blue Katina Boots
|
||||
Yeti Doll : Justice Katara
|
||||
King Bloctopus : Green White-Line Boots
|
||||
Bigfoot : Bigfoot Toe
|
||||
Green King Goblin : Black Pirate Bandana
|
||||
Dreamy Ghost : Kinoko Ramen (Roasted Pork)
|
||||
MT-09 : MT-09 Fuel
|
||||
Gryphon : Duck Tube [1]
|
||||
Gryphon : Serpent Tongue
|
||||
Risell Squid : Dark Pirate Bottom
|
||||
Dark Axe Stump : Stump Teardrop
|
||||
Blue Wyvern : Equip Enhancement Scroll
|
||||
Nest Golem : Blue Katinas (Male)
|
||||
Cheap Amplifier : Dark Scroll for Accessory for STR 70%
|
||||
Cheap Amplifier : Cheap Amplifier Card
|
||||
Manon : Manon Tail
|
||||
Manon : Manon Cry
|
||||
Saitie : Parwen Entry Pass
|
||||
Saitie : Red Battle Lord
|
||||
Drumming Bunny : Shoes Production Manual
|
||||
Drumming Bunny : Scroll for Pole Arm for Accuracy 10%
|
||||
Drumming Bunny : Gold Snowboard
|
||||
Drumming Bunny : Lion Fang
|
||||
Dyle : Scroll for Knuckler for Accuracy 60%
|
||||
Crimson Tree : Crimson Wood
|
||||
Crimson Tree : Crimson Wood
|
||||
Blue Flower Serpent : Blue Flower Serpent Card
|
||||
Blue Flower Serpent : Scroll for Pole Arm for Accuracy 100%
|
||||
Blue Flower Serpent : Cat Eye
|
||||
Spirit of Rock : Spirit of Rock Music Score
|
||||
Spirit of Rock : Dark Scroll for Accessory for STR 70%
|
||||
Spirit of Rock : Rock Spirit Card
|
||||
Prototype Lord : Prototype Lord Card
|
||||
Seruf : Lion Fang
|
||||
Seruf : Serpent Tongue
|
||||
Dark Wyvern : Blue Katina Boots
|
||||
Mateon : Mateon Tentacle
|
||||
Mateon : Equip Enhancement Scroll
|
||||
Mateon : Dark Pennance
|
||||
Mateon : Gold Pendant
|
||||
Mr. Anchor : [Storybook] Black Book
|
||||
Master Robo : Lion Fang
|
||||
Master Robo : Brown Jangoon Boots
|
||||
Master Robo : Gold Wings
|
||||
Ginseng Jar : Ginseng Jar Card
|
||||
Scuba Pepe : Equip Enhancement Scroll
|
||||
Ghost Pirate : Blue Battle Lord
|
||||
Ghost Pirate : Green Pirate Bottom
|
||||
Ghost Pirate : Heavenly Katara
|
||||
Leatty : Green White-Line Boots
|
||||
Tiv : Tiv Feather
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for One-handed BW Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Dagger Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Two-handed Sword Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Two-handed Axe Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Two-handed BW Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Spear Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Polearm Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Wand Magic Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Staff Magic Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Bow Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Claw Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Crossbow Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Thief Attacks 60%
|
||||
Gold Yeti and King Pepe : King Pepe Scroll for Knuckle Attacks 60%
|
||||
Gold Yeti and King Pepe : Maroon Jangoon Boots
|
||||
Slime : Champion Katara
|
||||
Rodeo : Brown Stud
|
||||
Rodeo : Brown Stud Pants
|
||||
Octopus : Champion Katara
|
||||
Luster Pixie : Luster Pixie Sunpiece
|
||||
Luster Pixie : Luster Pixie Card
|
||||
Nightshadow : Heaven Justice
|
||||
Nightshadow : Infinity Wrath
|
||||
Dual Beetle : Dual Beetle Horn
|
||||
Skeleton Soldier : Skeleton Soldier Card
|
||||
Master Death Teddy : Green Battle Lord
|
||||
Master Death Teddy : Bloodsoaked Katara
|
||||
Sakura Cellion : Maroon Jangoon Boots
|
||||
Pig : Pig Head
|
||||
Fire Boar : Fire Boar Tooth
|
||||
Fire Boar : Arwen Glass Shoes
|
||||
Fire Boar : Fire Boar Card
|
||||
Panda Teddy : Maroon Jangoon Boots
|
||||
Morphed Blin : Serpent Tongue
|
||||
Morphed Blin : Steel Pow
|
||||
Lunar Pixie : Lunar Pixie Moonpiece
|
||||
Lunar Pixie : Gold Wings
|
||||
Curse Eye : "Blackbull" deed to the land
|
||||
Curse Eye : Gold Snowboard
|
||||
Jr. Cellion : Cat Eye
|
||||
Barnard Gray : Barnard Gray Card
|
||||
Faust : Lupin Banana
|
||||
Faust : Lion Fang
|
||||
Faust : Serpent Tongue
|
||||
Gatekeeper : Gate Keeper Card
|
||||
Gatekeeper : Red Battle Lord
|
||||
Griffey : [Mastery Book] Flame Wheel 20
|
||||
Griffey : Meteor Katara
|
||||
Shark : Heaven Justice
|
||||
Deep Buffoon : Deep Buffoon Rock Piece
|
||||
Deep Buffoon : Blue Stud
|
||||
Deep Buffoon : Blazing Dragon Katara
|
||||
Melon Bubble Tea : Melon Bubble Tea Card
|
||||
Melon Bubble Tea : Maroon Jangoon Boots
|
||||
Tino : Tino Feather
|
||||
Bone Fish : Equip Enhancement Scroll
|
||||
Bone Fish : Potential Scroll
|
||||
I.AM.ROBOT : Lion Fang
|
||||
I.AM.ROBOT : Serpent Tongue
|
||||
Lilynouch : Knight Mask
|
||||
Lilynouch : [Mastery Book] Dragon Breath
|
||||
Dark Pepe : Serpent Coil
|
||||
Dark Pepe : Serpent Coil
|
||||
Toy Trojan : Toy Soldier Sword
|
||||
Toy Trojan : Justice Katara
|
||||
Sparker : Scroll for Knuckler for Accuracy 100%
|
||||
Sparker : Justice Katara
|
||||
Dark Drake : Dark Drake Horn
|
||||
Electrophant : Serpent Tongue
|
||||
Electrophant : Lion Fang
|
||||
Tick-Tock : Tick-Tock Egg
|
||||
Mecateon : Mecateon Laser Gun
|
||||
Mecateon : Majestic Katara
|
||||
Helmet Pepe : King Pepe Scroll for Polearm Attacks 60%
|
||||
Helmet Pepe : King Pepe Scroll for Wand Magic Attacks 60%
|
||||
Blue Mushroom : Thermal Fabric
|
||||
Blue Mushroom : Purple Jewelry Shoes
|
||||
Ratz : One-Handed Mace Forging Manual
|
||||
Snow Witch : Ice Tears
|
||||
Flyeye : Flyeye Wing
|
||||
Flyeye : Flyeye Card
|
||||
Headless Horseman : Devil Sunrise
|
||||
Royal Guard : Royal Guard Card
|
||||
Royal Guard : Scroll for Knuckler for Accuracy 10%
|
||||
Royal Guard : Heaven Justice
|
||||
Royal Guard : Dark Battle Lord
|
||||
Triple Rumo : Blue Jangoon Boots
|
||||
Triple Rumo : Brown Jangoon Boots
|
||||
Pianus : Miniature Pianus
|
||||
Pianus : Pianus Scream
|
||||
Pianus : Scroll for Overall Armor for STR 60%
|
||||
Pianus : [Mastery Book] Blaze 20
|
||||
Pianus : Blue Katte (Female)
|
||||
Pianus : Blue Katinas (Male)
|
||||
Rombot : Rombot Memory Card
|
||||
Rombot : Serpent Tongue
|
||||
Roid : Potential Scroll
|
||||
Roid : Equip Enhancement Scroll
|
||||
Robby : Robby Electronic Induction Device
|
||||
Robby : Robby Card
|
||||
Robby : Blue Stud
|
||||
Blue Snail : Grey/Brown Training Shirt
|
||||
Blue Snail : Grey/Brown Training Pants
|
||||
Afterlord : Afterlord Card
|
||||
Afterlord : Scroll for Overall Armor for STR 60%
|
||||
Afterlord : Heaven Gate
|
||||
Afterlord : Bloodsoaked Katara
|
||||
Block Golem : Block Golem Card
|
||||
Lyka : Guardian Horn
|
||||
Lyka : Dark Katinas (Male)
|
||||
Jr. Wraith : Equip Enhancement Scroll
|
||||
Jr. Wraith : Potential Scroll
|
||||
Sentinel : Fireman Axe
|
||||
Ice Drake : Blue Battle Lord
|
||||
Ice Drake : Gold Mask
|
||||
Overlord A : Overlord A Card
|
||||
Overlord B : Overlord B Card
|
||||
Latest Hits Compilation : Dark Scroll for Accessory for STR 70%
|
||||
Latest Hits Compilation : Latest Hits Compilation Card
|
||||
Water Goblin : Serpent Coil
|
||||
Water Goblin : Serpent Coil
|
||||
Retz : Retz Card
|
||||
Retz : Cat Eye
|
||||
Retz : Blue Jangoon Boots
|
||||
Hoodoo : Steel Pow
|
||||
Pink Bean : Pink Bean Card
|
||||
Pink Bean : [Mastery Book] Maple Warrior 30
|
||||
Paper Lantern Ghost : Fish Cake (Skewer)
|
||||
Paper Lantern Ghost : Cat Eye
|
||||
Cold Shark : Frozen Shark Fin
|
||||
Cold Eye : Icicles
|
||||
Croco : Potential Scroll
|
||||
Croco : Gold Pendant
|
||||
Croco : Majestic Katara
|
||||
Bubble Fish : Bubble Fish Thoughts
|
||||
Officer Skeleton : Serpent Coil
|
||||
Officer Skeleton : Serpent Coil
|
||||
Murumuru : Murumuru Furball
|
||||
Zeno : Black Pirate Bandana
|
||||
Panda : Ascalon Katara
|
||||
Panda : Black Pirate Bandana
|
||||
Iron Mutae : Iron Mutae Card
|
||||
Snail : Red Mini Skirt
|
||||
Hankie : Hankie Panfluit
|
||||
Hankie : Heaven Justice
|
||||
Silver Slime : Silver Slime Card
|
||||
Silver Slime : Beige Elf Shoes
|
||||
Zeta Gray : Zeta Gray Card
|
||||
Zeta Gray : Dark Piette Pants
|
||||
Zombie Mushroom : The Charm of the Undead
|
||||
Zombie Mushroom : Hunter Bow
|
||||
Zombie Mushroom : Guardian Katara
|
||||
Pepe : Majestic Katara
|
||||
Grupin : Icicles
|
||||
Grupin : Equip Enhancement Scroll
|
||||
Hobi : Hov Shorts
|
||||
Yabber Doo : Beige Elf Shoes
|
||||
Royal Cactus : Dark Hunter Armor
|
||||
Royal Cactus : Dark Hunter Pants
|
||||
Dual Ghost Pirate : Dual Pirate Propeller
|
||||
Dual Ghost Pirate : Infinity Wrath
|
||||
Memory Monk Trainee : [Mastery Book] Venom 30
|
||||
Memory Monk Trainee : Devil Sunrise
|
||||
Coolie Zombie : Zombie Lost Tooth
|
||||
Coolie Zombie : [Storybook] Black Book
|
||||
Coolie Zombie : Brown Stud
|
||||
Coolie Zombie : Brown Stud Pants
|
||||
Blood Harp : Blood Harp Crown
|
||||
Blood Harp : Heavenly Katara
|
||||
Black Kentaurus : Kentaurus Skull
|
||||
Black Kentaurus : Gold Arund
|
||||
Black Kentaurus : Blazing Dragon Katara
|
||||
Rash : Rash Furball
|
||||
Rash : Anasthetic Powder
|
||||
Imperial Guard : Imperial Guard Card
|
||||
The Book Ghost : The Book Ghost Sheet of Paper
|
||||
The Book Ghost : Blue Jangoon Boots
|
||||
Drake : Drake Meat
|
||||
Drake : Drake Blood
|
||||
Oblivion Guardian : [Mastery Book] Blessing of the Onyx 30
|
||||
Zakum3 : [Skill Book] Advanced Combo
|
||||
Zakum3 : [Mastery Book] Smoke Bomb
|
||||
Zakum3 : [Mastery Book] Sanctuary
|
||||
Zakum3 : [Mastery Book] Venom
|
||||
Zakum3 : [Mastery Book] Crossbow Expert
|
||||
Zakum3 : Zakum Helmet (1)
|
||||
Zakum3 : Devil Sunrise
|
||||
Zakum3 : Zakum Tree Branch
|
||||
Jr. Newtie : Equip Enhancement Scroll
|
||||
Jr. Newtie : Devil Sunrise
|
||||
Jr. Newtie : Red Katte (Female)
|
||||
Jr. Pepe : Jr. Pepe Fish
|
||||
Miner Zombie : Zombie Lost Tooth
|
||||
Miner Zombie : Zombie Lost Gold Tooth
|
||||
Miner Zombie : Minor Zombie Card
|
||||
Miner Zombie : Ascalon Katara
|
||||
Aufheben : Aufheben Time Sand
|
||||
Aufheben : Aufheben Card
|
||||
Eye of Time : Scroll for Overall Armor for STR 60%
|
||||
Eye of Time : Scroll for Knuckler for Accuracy 60%
|
||||
Eye of Time : Heaven Gate
|
||||
Psycho Jack : Fireman Axe
|
||||
Psycho Jack : Red Hunter Armor
|
||||
Psycho Jack : Red Hunter Pants
|
||||
Psycho Jack : Red White-Line Boots
|
||||
Death Teddy : Blazing Dragon Katara
|
||||
Bain : Bain Spiky Collar
|
||||
Bain : Gold Arund
|
||||
Dark Nependeath : Equip Enhancement Scroll
|
||||
Dark Nependeath : Dark Piette Pants
|
||||
Timu : Timu Feather
|
||||
Mano : Rainbow Colored Snail Shell
|
||||
Dark Stone Golem : Dark Stone Golem Card
|
||||
Scorpion : Cat Eye Stone
|
||||
King Clang : Lorang Claws
|
||||
King Clang : Clang Claws
|
||||
Nependeath : Nependeath Honey
|
||||
Phantom Watch : Dragon Tail
|
||||
Phantom Watch : Dark Pirate Bottom
|
||||
Reinforced Iron Mutae : Reinforced Iron Mutae Card
|
||||
Master Chronos : Brown Jangoon Boots
|
||||
Crimson Balrog the Kidnapper : [Skill Book] Dragon Breath
|
||||
Lazy Buffy : Heavenly Katara
|
||||
Red Slime : Kinoko Ramen (Salt)
|
||||
Evil Eye : Cat Eye
|
||||
Maverick Type D : Maverick Type D Card
|
||||
Maverick Type D : Green Battle Lord
|
||||
Maverick Type A : Maverick Type A Card
|
||||
Maverick Type A : Infinity Wrath
|
||||
Klock : Heavenly Katara
|
||||
Tiguru : Tiguru Feather
|
||||
Tortie : Lion Fang
|
||||
Shade : Someone Hat
|
||||
Dunas : Dunas Time Sand
|
||||
Dunas : Dunas Card
|
||||
Timer : Scroll for Knuckler for Accuracy 60%
|
||||
Timer : Serpent Coil
|
||||
Timer : Serpent Coil
|
||||
Maverick Type S : Maverick Type S Card
|
||||
Poison Poopa : Poison Poopa Poisonous Spikes
|
||||
Poison Poopa : Blue White-Line Boots
|
||||
Murupia : Murupia Furball
|
||||
Chief Gray : Chief Gray Sign
|
||||
Chief Gray : Chief Gray Card
|
||||
Chief Gray : Dark Pennance
|
||||
Skelosaurus : Meteor Katara
|
||||
Oberon : Oberon Time Sand
|
||||
Oberon : Oberon Card
|
||||
Mr. Alli : Mr. Alli Leather
|
||||
Mr. Alli : Lion Fang
|
||||
Cellion : Maroon Jangoon Boots
|
||||
Qualm Monk Trainee : [Mastery Book] Blessing of the Onyx 20
|
||||
Chronos : Chronos Egg
|
||||
Kiyo : Kiyo Beak
|
||||
Cherry Bubble Tea : Cherry Bubble Tea Card
|
||||
Cherry Bubble Tea : Maroon Jangoon Boots
|
||||
Pink Teddy : Teddy Yellow Ribbon
|
||||
Pink Teddy : White/Purple Gift Box
|
||||
Rexton : [Mastery Book] Spirit Claw
|
||||
Master of Disguise : The Lost Treasure [1]
|
||||
Master of Disguise : The Lost Treasure [2]
|
||||
Master of Disguise : The Lost Treasure [3]
|
||||
Master of Disguise : The Lost Treasure [4]
|
||||
Master of Disguise : The Lost Treasure [5]
|
||||
Neo Huroid : Gold Mask
|
||||
Jr. Pepe Doll : Guardian Katara
|
||||
Dual Birk : Dual Birk Tiny Tail
|
||||
Muru : Muru Furball
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for One-handed BW Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Dagger Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Two-handed Sword Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Two-handed Axe Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Two-handed BW Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Spear Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Polearm Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Bow Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Crossbow Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Wand Magic Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Staff Magic Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Thief Attacks 60%
|
||||
Grey Yeti and King Pepe : King Pepe Scroll for Knuckle Attacks 60%
|
||||
Wild Kargo : Gold Wings
|
||||
Bubbling : Bubbling Large Bubble
|
||||
Bubbling : Blue Jewelry Shoes
|
||||
Bubbling : Champion Katara
|
||||
Papulatus : [Mastery Book] High Mastery 30
|
||||
Papulatus : Red Katte (Female)
|
||||
Papulatus : Red Katinas (Male)
|
||||
Plateon : Plateon Helmet
|
||||
Plateon : Serpent Tongue
|
||||
Nightghost : Ghost Headband
|
||||
Nightghost : Serpent Coil
|
||||
Nightghost : Serpent Coil
|
||||
Mango Bubble Tea : Mango Bubble Tea Card
|
||||
Mango Bubble Tea : Maroon Jangoon Boots
|
||||
Homunculus : Homunculus Card
|
||||
Homunculus : Green Pirate Bottom
|
||||
Homunculus : Brown Stud
|
||||
Homunculus : Brown Stud Pants
|
||||
Orange Mushroom : Hunter Bow
|
||||
Orange Mushroom : Basic Archer Glove
|
||||
Scarf Plead : Worn-Out Muffler
|
||||
Scarf Plead : Green Hunter Armor
|
||||
Scarf Plead : Green Hunter Pants
|
||||
Female Boss : Lady Boss Comb
|
||||
Female Boss : Devil Sunrise
|
||||
Hogul : Hogul Card
|
||||
Memory Guardian : Meteor Katara
|
||||
Poison Mushroom : King Pepe Scroll for Two-handed Sword Attacks 60%
|
||||
Poison Mushroom : King Pepe Scroll for Two-handed Axe Attacks 60%
|
||||
Poison Mushroom : Justice Katara
|
||||
Homun : Gold Pendant
|
||||
Homun : Ascalon Katara
|
||||
Greatest Oldies : Dark Scroll for Accessory for STR 70%
|
||||
Greatest Oldies : Greatest Oldies Card
|
||||
Kid Mannequin : Kid Mannequin Bunny Suit
|
||||
Kid Mannequin : Dark Scroll for Accessory for STR 70%
|
||||
Kid Mannequin : Kid Mannequin Card
|
||||
Kid Mannequin : Justice Katara
|
||||
Dark Rash : Dark Rash Furball
|
||||
Cerebes : Beige Elf Shoes
|
||||
Grizzly : Equip Enhancement Scroll
|
||||
Lioner : Gold Tail
|
||||
Lioner : Majestic Katara
|
||||
Red Wyvern : Equip Enhancement Scroll
|
||||
Gigantic Spirit Viking : Gigantic Spirit Viking Card
|
||||
Gigantic Spirit Viking : Heaven Gate
|
||||
Gigantic Spirit Viking : Red Battle Lord
|
||||
Gigantic Spirit Viking : Beige Elf Shoes
|
||||
Hector : Blue Jangoon Boots
|
||||
Hector : Serpent Coil
|
||||
Hector : Serpent Coil
|
||||
Crimson Balrog : [Storybook] Crimson Balrog Proposal
|
||||
Memory Monk : [Mastery Book] High Mastery 30
|
||||
Lupin : Lupin Banana
|
||||
Tae Roon : Mind And Heart Medicine
|
||||
Birk : Birk Chewed Grass
|
||||
Birk : Dark Battle Lord
|
||||
Birk : Blazing Dragon Katara
|
||||
Clang : Clang Claws
|
||||
Clang : Lion Fang
|
||||
Straw Target Dummy : Straw Target Dummy Card
|
||||
Royal Guard Pepe : King Pepe Scroll for Crossbow Attacks 60%
|
||||
Royal Guard Pepe : King Pepe Scroll for Thief Attacks 60%
|
||||
Royal Guard Pepe : King Pepe Scroll for Knuckle Attacks 60%
|
||||
Blue King Goblin : Blue Stud
|
||||
Nightmare : Blue Jangoon Boots
|
||||
Renegade Spores : King Pepe Scroll for One-handed BW Attacks 60%
|
||||
Renegade Spores : King Pepe Scroll for Dagger Attacks 60%
|
||||
Renegade Spores : Potential Scroll
|
||||
Prime Minister : King Pepe Scroll for One-handed BW Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Dagger Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Two-handed Sword Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Two-handed Axe Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Two-handed BW Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Spear Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Polearm Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Wand Magic Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Staff Magic Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Bow Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Crossbow Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Thief Attacks 60%
|
||||
Prime Minister : King Pepe Scroll for Knuckle Attacks 60%
|
||||
Prime Minister : Lion Fang
|
||||
Prime Minister : Serpent Tongue
|
||||
Prime Minister : Justice Katara
|
||||
Prime Minister : Guardian Katara
|
||||
Ear Plug Plead : Ear Muffs
|
||||
Oly Oly : Somebody Tire
|
||||
Samiho : Samiho Card
|
||||
Charmer : Charmer Flute
|
||||
Murupa : Murupa Furball
|
||||
Murukun : Murukun Furball
|
||||
Bob : Bob Snail Shell
|
||||
Horny Mushroom : Guardian Katara
|
||||
Brown Teddy : Teddy Cotton
|
||||
Brown Teddy : Equip Enhancement Scroll
|
||||
Brown Teddy : Guardian Katara
|
||||
Thanatos : Thanatos' Strap
|
||||
Thanatos : [Storybook] Black Book
|
||||
Thanatos : Dark Battle Lord
|
||||
Mummydog : Mummydog Card
|
||||
Dark Cornian : Devil Sunrise
|
||||
Dark Cornian : Red Katinas (Male)
|
||||
Intoxicated Pig : King Pepe Scroll for Two-handed BW Attacks 60%
|
||||
Intoxicated Pig : King Pepe Scroll for Spear Attacks 60%
|
||||
Red Flower Serpent : Red Flower Serpent Card
|
||||
Red Flower Serpent : Gold Mask
|
||||
Propelly : Lion Fang
|
||||
Propelly : Fireman Axe
|
||||
Propelly : Dark Pennance
|
||||
Platoon Chronos : Equip Enhancement Scroll
|
||||
Platoon Chronos : Serpent Tongue
|
||||
Chirppy : Fireman Axe
|
||||
Chirppy : Red Hunter Armor
|
||||
Chirppy : Red White-Line Boots
|
||||
Planey : Brown Jangoon Boots
|
||||
Zombie Mushmom : Zombie Mushmom Card
|
||||
Dark Leatty : Black Guise
|
||||
Dark Leatty : Green White-Line Boots
|
||||
Ligator : Equip Enhancement Scroll
|
||||
Male Boss : Boss Pomade
|
||||
Cloud Fox : Sushi (Salmon)
|
||||
Cloud Fox : Fish Cake (Skewer)
|
||||
Cloud Fox : Cat Eye
|
||||
Bodyguard B : Bodyguard B Bullet Shell
|
||||
Baby Typhon : Dark Scroll for Cape for Weapon Def 70%
|
||||
Bodyguard A : Bodyguard A Tie Pin
|
||||
Ergoth : Ergoth Jawbone
|
||||
Annoyed Zombie Mushroom : The Charm of the Undead
|
||||
Annoyed Zombie Mushroom : Hunter Bow
|
||||
Cico : Seahorse Horn
|
||||
Robo : Blue Jangoon Boots
|
||||
Wraith : Cat Eye
|
||||
Wraith : Gold Pendant
|
||||
Red Drake : Dark Piette Pants
|
||||
Killa Bee : Cat Eye
|
||||
Skeledog : Skeledog Bone
|
||||
Skeledog : Maroon Jangoon Boots
|
||||
Windraider : Scroll for Gloves for DEX 15%
|
||||
Tutorial Muru : Tutorial Muru Furball
|
||||
@@ -1,13 +0,0 @@
|
||||
# Migrations
|
||||
The files contained in this directory are intended to be run manually when transitioning from an earlier version of Cosmic to a more recent one.
|
||||
|
||||
Not every version comes with an associated migration script. Only those with breaking changes such as removal of custom assets that would otherwise crash the client.
|
||||
|
||||
This is a temporary solution until automatic database migrations are in place.
|
||||
|
||||
## How to
|
||||
Each script is only intended to be run __once__.
|
||||
|
||||
When a new migration is available, simply run the SQL script in HeidiSQL (or other SQL client of choice).
|
||||
|
||||
If there are multiple new migrations that you haven't run, run them in order starting with the lowest version and ending with the highest version.
|
||||
@@ -1,6 +0,0 @@
|
||||
/* Manually run this script in MySQL Workbench or some other database client
|
||||
to migrate your old (pre Jan 19th 2022) monsterbook table to the new version */
|
||||
ALTER TABLE cosmic.`monsterbook`
|
||||
CHANGE COLUMN `charid` `charid` INT(11) NOT NULL,
|
||||
ADD PRIMARY KEY (`charid`, `cardid`),
|
||||
ADD CONSTRAINT `FK_monsterbook_1` FOREIGN KEY (`charid`) REFERENCES `characters` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
@@ -1,2 +0,0 @@
|
||||
DELETE FROM shopitems
|
||||
WHERE itemid = 2030100; # Return Scroll - Banished Area (a custom item added in HeavenMS)
|
||||
@@ -1,7 +0,0 @@
|
||||
---- Cosmic MySQL Database ----
|
||||
|
||||
These SQL files must be executed IN ORDER to set up the database:
|
||||
- 1-db_database.sql (Tables and some data)
|
||||
- 2-db_drops.sql (Remaining data: monster drops, reactor drops)
|
||||
- 3-db_shopupdate.sql (Custom shops - optional, requires provided WZs)
|
||||
- 4-db_admin (Basic admin account - optional)
|
||||
@@ -4,6 +4,7 @@ services:
|
||||
build: .
|
||||
depends_on:
|
||||
- db
|
||||
- pg_db
|
||||
ports:
|
||||
# Login server
|
||||
- "8484:8484"
|
||||
@@ -19,7 +20,8 @@ services:
|
||||
- ./wz:/opt/server/wz
|
||||
environment:
|
||||
DB_HOST: "db" ## Remember if this is present it will OVERRIDE the host in the config.yaml, if you put here anything other than db, you'll need to change the config.yaml jdbc string to port 3307, and not port 3306
|
||||
|
||||
PG_DB_HOST: "pg_db"
|
||||
|
||||
db:
|
||||
image: mysql:8.4.0
|
||||
environment:
|
||||
@@ -30,4 +32,13 @@ services:
|
||||
- "3307:3306"
|
||||
volumes:
|
||||
- ./database/docker-db-data:/var/lib/mysql
|
||||
- ./database/sql:/docker-entrypoint-initdb.d
|
||||
|
||||
pg_db:
|
||||
image: postgres:15.0
|
||||
ports:
|
||||
- "5433:5432"
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
volumes:
|
||||
- ./database/docker-pg-db-data:/var/lib/postgresql/data
|
||||
- ./database/postgres-scripts:/docker-entrypoint-initdb.d
|
||||
|
||||
@@ -480,9 +480,7 @@
|
||||
5590000 - High-Five Stamp - Can equip items that are 5 levels above your current level.
|
||||
5021026 - Gift Box Throwing Stars - A gift box that can be freely thrown around. Using the #cThrowing Star# will create an orbital effect.\n\nThis item cannot be deleted.
|
||||
5010073 - Miss Popular - Well, lookie here. Someone<6E>s certainly become popular with the guys. Turn this effect on and off by assigning it to a shortcut key from the keyboard settings menu.
|
||||
|
||||
5010074 - Mr. Popular - Well, lookie here. Someone<6E>s certainly become popular with the girls. Turn this effect on and off by assigning it to a shortcut key from the keyboard settings menu.
|
||||
|
||||
5240027 - Golden Drumstick - A drumstick that can be consumed only by #cBaby Tiger#. It recovers hunger and #cincreases Closeness by 100.#
|
||||
5390005 - Cute Tiger Messenger - Shout to everyone in the world your character is on with this megaphone. Now available with your avatar on the top of everyone's screen! Comes with a tiger background for your avatar.
|
||||
5390006 - Roaring Tiger Messenger - Shout to everyone in the world your character is on with this megaphone. Now available with your avatar on the top of everyone's screen! Comes with a screen shaked.
|
||||
|
||||
200
handbook/Commands.txt
Normal file
200
handbook/Commands.txt
Normal file
@@ -0,0 +1,200 @@
|
||||
Common Commands:
|
||||
@help - Show available commands.
|
||||
@commands - Show available commands.
|
||||
@droplimit - Check drop limit of current map.
|
||||
@time - Show current server time.
|
||||
@credits - Show credits. These people made the server possible.
|
||||
@uptime - Show server online time.
|
||||
@gacha - Show gachapon rewards.
|
||||
@dispose - Dispose to fix NPC chat.
|
||||
@changel - Change language settings
|
||||
@equiplv - Show levels of all equipped items.
|
||||
@showrates - Show all world/character rates.
|
||||
@rates - Show your rates.
|
||||
@online - Show all online players.
|
||||
@gm- Send a message to the game masters.
|
||||
@reportbug - Send in a bug report.
|
||||
@points - Show point total.
|
||||
@joinevent - Join active event.
|
||||
@leaveevent-Leave active event.
|
||||
@ranks - Show player rankings.
|
||||
@str - Assign AP into STR.
|
||||
@dex - Assign AP into DEX.
|
||||
@int - Assign AP into INT.
|
||||
@luk - Assign AP into LUK.
|
||||
@enableauth - Enable PIC code by resetting the cooldown.
|
||||
@toggleexp - Toggle enable/disable all exp gain.
|
||||
@mylawn - Claim ownership of the current map.
|
||||
@bosshp - Show HP of bosses on current map.
|
||||
@mobhp - Show HP of mobs on current map.
|
||||
|
||||
|
||||
Donator Commands:
|
||||
@whatdropsfrom - Show what items drop from a mob.
|
||||
@whodrops - Show what drops an item.
|
||||
@buffme - Activate GM buffs on self.
|
||||
@goto - Warp to a predefined map.
|
||||
|
||||
|
||||
JrGM Commands:
|
||||
!recharge - Recharge and refill all USE items.
|
||||
!whereami - Show info about objects on current map.
|
||||
!hide - Hide from players.
|
||||
!unhide - Toggle Hide.
|
||||
!sp - Set available SP.
|
||||
!ap - Set available AP.
|
||||
!empowerme - Activate all useful buffs.
|
||||
!buffmap - Give GM buffs to the whole map.
|
||||
!buff - Activate a buff.
|
||||
!bomb - Bomb a player, dealing damage.
|
||||
!dc - Disconnect a player.
|
||||
!cleardrops - Clear drops by player.
|
||||
!clearslot - Clear all items in an inventory tab.
|
||||
!clearsavelocs - Clear saved locations for a player.
|
||||
!warp - Warp to a map.
|
||||
!warphere - Move a player to your location.
|
||||
!summon - Move a player to your location.
|
||||
!warpto - Warp to a player.
|
||||
!reach - Warp to a player.
|
||||
!follow - Warp to a player.
|
||||
!gmshop - Open the GM shop.
|
||||
!heal - Fully heal your HP/MP.
|
||||
!item - Spawn an item into your inventory.
|
||||
!drop - Spawn an item onto the ground.
|
||||
!level - Set your level.
|
||||
!levelpro - Set your level, one by one.
|
||||
!setslot - Set amount of inventory slots in all tabs.
|
||||
!setstat - Set all primary stats to new value.
|
||||
!maxstat - Max out all character stats.
|
||||
!maxskill - Max out all job skills.
|
||||
!resetskill Set all skill levels to 0.
|
||||
!search - Search String.wz.
|
||||
!jail - Move a player to the jail.
|
||||
!unjail- Free a player from jail.
|
||||
!job - Change job of a player.
|
||||
!unbug - Unbug self.
|
||||
!id - Search in handbook.
|
||||
!gachalist - Show gachapon rewards.
|
||||
!loot - Loots all items that belong to you.
|
||||
!mobskill - Apply a mob skill to all mobs on the map.
|
||||
Args: <mob skill id> <skill level>
|
||||
|
||||
|
||||
GM Commands:
|
||||
!debuff - Put a debuff on all nearby players.
|
||||
!fly - Enable/disable fly feature.
|
||||
!spawn - Spawn mob(s) on your location.
|
||||
!mutemap - Toggle mute players in the map.
|
||||
!checkdmg - Show stats and damage of a player.
|
||||
!inmap - Show all players in the map.
|
||||
!reloadevents - Reload all event data.
|
||||
!reloaddrops - Reload all drop data.
|
||||
!reloadportals - Reload all portal scripts.
|
||||
!reloadmap - Reload the map.
|
||||
!reloadshops - Reload popup shops and NPC shops.
|
||||
!hpmp - Set HP/MP of a player.
|
||||
!maxhpmp - Set base HP/MP of a player.
|
||||
!music - Play a song.
|
||||
!monitor - Toggle monitored packet logging of a character.
|
||||
!monitors - Show all characters being monitored for packet logging.
|
||||
!ignore - Toggle ignore a character from auto-ban alerts.
|
||||
!ignored - Show all characters being ignored in auto-ban alerts.
|
||||
!pos - Show current position and foothold.
|
||||
!togglecoupon - Toggle enable/disable a coupon.
|
||||
!togglewhitechat - Toggle white GM chat.
|
||||
!fame - Set new fame value of a player.
|
||||
!givenx - Give NX to a player.
|
||||
!givevp - Give vote points to a player.
|
||||
!givems - Give mesos to a player.
|
||||
!giverp - Give reward points to a player.
|
||||
!expeds - Show all ongoing boss expeditions.
|
||||
!kill - Kill a player.
|
||||
!seed - Drop all seeds inside Henesys PQ.
|
||||
!maxenergy - Set dojo energy to max value.
|
||||
!killall - Kill all mobs in the map.
|
||||
!notice - Send a blue message to everyone on the server.
|
||||
!rip - Send a RIP notice.
|
||||
!openportal - Open a portal on the map.
|
||||
!closeportal - Close a portal.
|
||||
!pe - Handle synthesized packets from file, and handle them as if sent from a client.
|
||||
!startevent - Start an event on current map.
|
||||
!endevent - Close entry for ongoing event.
|
||||
!startmapevent - Start a "classic" event on current map.
|
||||
!stopmapevent - Stop ongoing "classic" event.
|
||||
!online2 - Show all online players.
|
||||
!ban - Ban a player.
|
||||
!unban - Unban a player.
|
||||
!healmap - Heal all HP/MP of all players in the map.
|
||||
!healperson - Heal all HP/MP of a player.
|
||||
!hurt - Nearly kill a player.
|
||||
!killmap - Kill all players in the map.
|
||||
!night - Set sky background to black.
|
||||
!npc - Spawn an NPC on your location.
|
||||
!face - Change face of a player.
|
||||
!hair - Change hair of a player.
|
||||
!startquest - Start a quest.
|
||||
!completequest - Complete an active quest.
|
||||
!resetquest - Reset a completed quest.
|
||||
!timer - Set timer on a player in current map.
|
||||
!timermap - Set timer on all players in current map.
|
||||
!timerall Set a server wide timer.
|
||||
!warpmap - Warp all characters on current map to a new map.
|
||||
!warparea - Warp all nearby players to a new map.
|
||||
|
||||
|
||||
SuperGM Commands:
|
||||
!servermessage - Set scrolling server message.
|
||||
!proitem - Spawn an item with custom stats.
|
||||
!seteqstat-Set stats of all equips in inventory.
|
||||
!exprate - Set world exp rate.
|
||||
!mesorate - Set world meso rate.
|
||||
!droprate - Set world drop rate.
|
||||
!bossdroprate - Set world boss drop rate.
|
||||
!questrate - Set world quest rate.
|
||||
!travelrate - Set world travel rate.
|
||||
!fishrate - Set fishing rate.
|
||||
!itemvac - Loot all drops on the map.
|
||||
!forcevac-Loot all drops on the map.
|
||||
!zakum - Spawn Zakum on your location.
|
||||
!horntail - Spawn Horntail on your location.
|
||||
!pinkbean - Spawn Pink Bean on your location.
|
||||
!pap - Spawn Papulatus on your location.
|
||||
!pianus - Spawn Pianus (R) on your location.
|
||||
!cake - Spawn Cake boss with specified HP.
|
||||
!playernpc - Spawn a player NPC of an online player.
|
||||
!playernpcremove - Remove a "Iv 200" player NPC.
|
||||
!pnpc - Spawn a permanent NPC on your location.
|
||||
!pnpcremove - Remove a permanent NPC on the map.
|
||||
!pmob - Spawn a permanent mob on your location.
|
||||
!pmobremove - Remove all permanent mobs of the same type on the map.
|
||||
|
||||
|
||||
Developer Commands:
|
||||
!debug - Show a debug message.
|
||||
!set - Store value in an array, for testing.
|
||||
!showpackets - Toggle show received packets in console.
|
||||
!showmovelife - Toggle show move life in console.
|
||||
!showsessions - Show online sessions.
|
||||
!iplist - Show IP of all players.
|
||||
|
||||
|
||||
Admin Commands:
|
||||
!setgmlevel - Set GM level of a player.
|
||||
!warpworld - Warp to a different world.
|
||||
!saveall - Save all characters.
|
||||
!dcall - Disconnect all players (online or logged in).
|
||||
!mapplayers - Show all players on the map.
|
||||
!getacc - Show account name of an online player.
|
||||
!shutdown - Shut down the server.
|
||||
!clearquestcache - Clear all quest cache.
|
||||
!clearquest - Clear cache of a quest.
|
||||
!supplyratecoupon - Set availability of coupons in Cash Shop.
|
||||
!spawnallpnpcs - Spawn player NPCs of all existing players.
|
||||
!eraseallpnpcs - Remove all player NPCs.
|
||||
!addchannel - Add a new channel to a world.
|
||||
!addworld - Add a new world.
|
||||
!removechannel - Remove channel from a world.
|
||||
!removeworld - Remove a world.
|
||||
!devtest - Runs devtest.js. Developer utility - test stuff without restarting the server.
|
||||
|
||||
|
||||
9
handbook/Equip/Skin.txt
Normal file
9
handbook/Equip/Skin.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
0 - Light - (no description)
|
||||
1 - Tanned - (no description)
|
||||
2 - Dark - (no description)
|
||||
3 - Pale - (no description)
|
||||
4 - Blue - (no description)
|
||||
5 - Green - (no description)
|
||||
9 - White - (no description)
|
||||
10 - Pink - (no description)
|
||||
11 - Brown - (no description)
|
||||
2
handbook/Gender.txt
Normal file
2
handbook/Gender.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
0 - Male - (no description)
|
||||
1 - Female - (no description)
|
||||
70
handbook/Job.txt
Normal file
70
handbook/Job.txt
Normal file
@@ -0,0 +1,70 @@
|
||||
0 - Beginner - (no description)
|
||||
100 - Warrior - (no description)
|
||||
110 - Fighter - (no description)
|
||||
111 - Crusader - (no description)
|
||||
112 - Hero - (no description)
|
||||
120 - Page - (no description)
|
||||
121 - White Knight - (no description)
|
||||
122 - Paladin - (no description)
|
||||
130 - Spearman - (no description)
|
||||
131 - Dragon Knight - (no description)
|
||||
132 - Dark Knight - (no description)
|
||||
200 - Magician - (no description)
|
||||
210 - Fp Wizard - (no description)
|
||||
211 - Fp Mage - (no description)
|
||||
212 - Fp Archmage - (no description)
|
||||
220 - Il Wizard - (no description)
|
||||
221 - Il Mage - (no description)
|
||||
222 - Il Archmage - (no description)
|
||||
230 - Cleric - (no description)
|
||||
231 - Priest - (no description)
|
||||
232 - Bishop - (no description)
|
||||
300 - Bowman - (no description)
|
||||
310 - Hunter - (no description)
|
||||
311 - Ranger - (no description)
|
||||
312 - Bow Master - (no description)
|
||||
320 - Crossbowman - (no description)
|
||||
321 - Sniper - (no description)
|
||||
322 - Crossbow Master - (no description)
|
||||
400 - Thief - (no description)
|
||||
410 - Assassin - (no description)
|
||||
411 - Hermit - (no description)
|
||||
412 - Night Lord - (no description)
|
||||
420 - Bandit - (no description)
|
||||
421 - Chief Bandit - (no description)
|
||||
422 - Shadower - (no description)
|
||||
500 - Pirate - (no description)
|
||||
510 - Brawler - (no description)
|
||||
511 - Marauder - (no description)
|
||||
512 - Buccaneer - (no description)
|
||||
520 - Gunslinger - (no description)
|
||||
521 - Outlaw - (no description)
|
||||
522 - Corsair - (no description)
|
||||
800 - Maple Leaf Brigadier - (no description)
|
||||
900 - Gm - (no description)
|
||||
910 - Super Gm - (no description)
|
||||
1000 - Noblesse - (no description)
|
||||
1100 - Dawn Warrior 1 - (no description)
|
||||
1110 - Dawn Warrior 2 - (no description)
|
||||
1111 - Dawn Warrior 3 - (no description)
|
||||
1200 - Blaze Wizard 1 - (no description)
|
||||
1210 - Blaze Wizard 2 - (no description)
|
||||
1211 - Blaze Wizard 3 - (no description)
|
||||
1212 - Blaze Wizard 4 - (no description)
|
||||
1300 - Wind Archer 1 - (no description)
|
||||
1310 - Wind Archer 2 - (no description)
|
||||
1311 - Wind Archer 3 - (no description)
|
||||
1312 - Wind Archer 4 - (no description)
|
||||
1400 - Night Walker 1 - (no description)
|
||||
1410 - Night Walker 2 - (no description)
|
||||
1411 - Night Walker 3 - (no description)
|
||||
1412 - Night Walker 4 - (no description)
|
||||
1500 - Thunder Breaker 1 - (no description)
|
||||
1510 - Thunder Breaker 2 - (no description)
|
||||
1511 - Thunder Breaker 3 - (no description)
|
||||
1512 - Thunder Breaker 4 - (no description)
|
||||
2000 - Legend - (no description)
|
||||
2100 - Aran 1 - (no description)
|
||||
2110 - Aran 2 - (no description)
|
||||
2111 - Aran 3 - (no description)
|
||||
2112 - Aran 4 - (no description)
|
||||
@@ -36,10 +36,7 @@
|
||||
5000044 - Orange tiger - They are very gentle and obedient in nature, easily becoming friendly with the owner, which in turn speeds up the level-up process.
|
||||
5000045 - Skunk - Calm and quiet by nature, the easy-going, eccentric Skunk has a rather humorous and pompous outlook on life, the finer things are what it enjoys.
|
||||
5000026 - Sun Wu Kong - Sun Wu Kong ran out of Tang Shan Zhang. He is lazy and moody but can be changed with love.
|
||||
5000040 - ??? ?? - ??? ??? ??? ??? ???????. ??? ????? ??? ?????, ??? ? ?? ??? ??? ???? ??? ?? ????. \n#c??: ?? ??, ??? ??, ??? ?? ???&?? ??, ?? ??, ???? ??, MP ????#
|
||||
5000042 - Kino - A happy-go-lucky, orange mushroom that loves shiny stones.
|
||||
5000043 - ???? - ??? ????, ?? ??? ??? ???????. ??? ?? ? ????, ??? ??? ???? ??? ?? ????. \n#c??: ????, ?????#
|
||||
5000046 - ?? - ???? ?? ?? ???? ???? ??? ???????. \n#c??:????, ?????#
|
||||
5000047 - Robo - A special egg that becomes a mythical Robo upon hatching.
|
||||
5000048 - Baby Robo - A Baby Robo hatched out of the special Capsule. At Level 15, the pet can be evolved into a full-fledged Adult Robo with the help of Garnox the NPC using the Rock of Evolution.
|
||||
5000049 - Blue Robo - Mysterious magical powers aligned and sucessfully evolved the Baby Robo into a Blue Robo!
|
||||
|
||||
259
mvnw
vendored
Normal file
259
mvnw
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.3.2
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
|
||||
# MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
set -euf
|
||||
[ "${MVNW_VERBOSE-}" != debug ] || set -x
|
||||
|
||||
# OS specific support.
|
||||
native_path() { printf %s\\n "$1"; }
|
||||
case "$(uname)" in
|
||||
CYGWIN* | MINGW*)
|
||||
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
|
||||
native_path() { cygpath --path --windows "$1"; }
|
||||
;;
|
||||
esac
|
||||
|
||||
# set JAVACMD and JAVACCMD
|
||||
set_java_home() {
|
||||
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
|
||||
if [ -n "${JAVA_HOME-}" ]; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACCMD="$JAVA_HOME/jre/sh/javac"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACCMD="$JAVA_HOME/bin/javac"
|
||||
|
||||
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
|
||||
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
|
||||
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(
|
||||
'set' +e
|
||||
'unset' -f command 2>/dev/null
|
||||
'command' -v java
|
||||
)" || :
|
||||
JAVACCMD="$(
|
||||
'set' +e
|
||||
'unset' -f command 2>/dev/null
|
||||
'command' -v javac
|
||||
)" || :
|
||||
|
||||
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
|
||||
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# hash string like Java String::hashCode
|
||||
hash_string() {
|
||||
str="${1:-}" h=0
|
||||
while [ -n "$str" ]; do
|
||||
char="${str%"${str#?}"}"
|
||||
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
|
||||
str="${str#?}"
|
||||
done
|
||||
printf %x\\n $h
|
||||
}
|
||||
|
||||
verbose() { :; }
|
||||
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
|
||||
|
||||
die() {
|
||||
printf %s\\n "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
trim() {
|
||||
# MWRAPPER-139:
|
||||
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
|
||||
# Needed for removing poorly interpreted newline sequences when running in more
|
||||
# exotic environments such as mingw bash on Windows.
|
||||
printf "%s" "${1}" | tr -d '[:space:]'
|
||||
}
|
||||
|
||||
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
|
||||
while IFS="=" read -r key value; do
|
||||
case "${key-}" in
|
||||
distributionUrl) distributionUrl=$(trim "${value-}") ;;
|
||||
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
|
||||
esac
|
||||
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
|
||||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
|
||||
|
||||
case "${distributionUrl##*/}" in
|
||||
maven-mvnd-*bin.*)
|
||||
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
|
||||
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
|
||||
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
|
||||
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
|
||||
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
|
||||
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
|
||||
*)
|
||||
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
|
||||
distributionPlatform=linux-amd64
|
||||
;;
|
||||
esac
|
||||
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
|
||||
;;
|
||||
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
|
||||
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
|
||||
esac
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
|
||||
distributionUrlName="${distributionUrl##*/}"
|
||||
distributionUrlNameMain="${distributionUrlName%.*}"
|
||||
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
|
||||
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
|
||||
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
|
||||
|
||||
exec_maven() {
|
||||
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
|
||||
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
|
||||
}
|
||||
|
||||
if [ -d "$MAVEN_HOME" ]; then
|
||||
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||
exec_maven "$@"
|
||||
fi
|
||||
|
||||
case "${distributionUrl-}" in
|
||||
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
|
||||
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
|
||||
esac
|
||||
|
||||
# prepare tmp dir
|
||||
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
|
||||
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
|
||||
trap clean HUP INT TERM EXIT
|
||||
else
|
||||
die "cannot create temp dir"
|
||||
fi
|
||||
|
||||
mkdir -p -- "${MAVEN_HOME%/*}"
|
||||
|
||||
# Download and Install Apache Maven
|
||||
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||
verbose "Downloading from: $distributionUrl"
|
||||
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
|
||||
# select .zip or .tar.gz
|
||||
if ! command -v unzip >/dev/null; then
|
||||
distributionUrl="${distributionUrl%.zip}.tar.gz"
|
||||
distributionUrlName="${distributionUrl##*/}"
|
||||
fi
|
||||
|
||||
# verbose opt
|
||||
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
|
||||
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
|
||||
|
||||
# normalize http auth
|
||||
case "${MVNW_PASSWORD:+has-password}" in
|
||||
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||
esac
|
||||
|
||||
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
|
||||
verbose "Found wget ... using wget"
|
||||
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
|
||||
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
|
||||
verbose "Found curl ... using curl"
|
||||
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
|
||||
elif set_java_home; then
|
||||
verbose "Falling back to use Java to download"
|
||||
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
|
||||
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
cat >"$javaSource" <<-END
|
||||
public class Downloader extends java.net.Authenticator
|
||||
{
|
||||
protected java.net.PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
|
||||
}
|
||||
public static void main( String[] args ) throws Exception
|
||||
{
|
||||
setDefault( new Downloader() );
|
||||
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
|
||||
}
|
||||
}
|
||||
END
|
||||
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
|
||||
verbose " - Compiling Downloader.java ..."
|
||||
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
|
||||
verbose " - Running Downloader.java ..."
|
||||
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
|
||||
fi
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||
if [ -n "${distributionSha256Sum-}" ]; then
|
||||
distributionSha256Result=false
|
||||
if [ "$MVN_CMD" = mvnd.sh ]; then
|
||||
echo "Checksum validation is not supported for maven-mvnd." >&2
|
||||
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
elif command -v sha256sum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
elif command -v shasum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
else
|
||||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
|
||||
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ $distributionSha256Result = false ]; then
|
||||
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
|
||||
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# unzip and move
|
||||
if command -v unzip >/dev/null; then
|
||||
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
|
||||
else
|
||||
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
|
||||
fi
|
||||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
|
||||
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||
|
||||
clean || :
|
||||
exec_maven "$@"
|
||||
149
mvnw.cmd
vendored
Normal file
149
mvnw.cmd
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
<# : batch portion
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.3.2
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
|
||||
@SET __MVNW_CMD__=
|
||||
@SET __MVNW_ERROR__=
|
||||
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
|
||||
@SET PSModulePath=
|
||||
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
|
||||
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
|
||||
)
|
||||
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
|
||||
@SET __MVNW_PSMODULEP_SAVE=
|
||||
@SET __MVNW_ARG0_NAME__=
|
||||
@SET MVNW_USERNAME=
|
||||
@SET MVNW_PASSWORD=
|
||||
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
|
||||
@echo Cannot start maven from wrapper >&2 && exit /b 1
|
||||
@GOTO :EOF
|
||||
: end batch / begin powershell #>
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
if ($env:MVNW_VERBOSE -eq "true") {
|
||||
$VerbosePreference = "Continue"
|
||||
}
|
||||
|
||||
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
|
||||
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
|
||||
if (!$distributionUrl) {
|
||||
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
}
|
||||
|
||||
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
|
||||
"maven-mvnd-*" {
|
||||
$USE_MVND = $true
|
||||
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
|
||||
$MVN_CMD = "mvnd.cmd"
|
||||
break
|
||||
}
|
||||
default {
|
||||
$USE_MVND = $false
|
||||
$MVN_CMD = $script -replace '^mvnw','mvn'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
if ($env:MVNW_REPOURL) {
|
||||
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
|
||||
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
|
||||
}
|
||||
$distributionUrlName = $distributionUrl -replace '^.*/',''
|
||||
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
|
||||
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
|
||||
if ($env:MAVEN_USER_HOME) {
|
||||
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
|
||||
}
|
||||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
|
||||
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
|
||||
|
||||
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
|
||||
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||
exit $?
|
||||
}
|
||||
|
||||
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
|
||||
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
|
||||
}
|
||||
|
||||
# prepare tmp dir
|
||||
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
|
||||
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
|
||||
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
|
||||
trap {
|
||||
if ($TMP_DOWNLOAD_DIR.Exists) {
|
||||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||
}
|
||||
}
|
||||
|
||||
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
|
||||
|
||||
# Download and Install Apache Maven
|
||||
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||
Write-Verbose "Downloading from: $distributionUrl"
|
||||
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
|
||||
$webclient = New-Object System.Net.WebClient
|
||||
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
|
||||
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
|
||||
}
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
|
||||
if ($distributionSha256Sum) {
|
||||
if ($USE_MVND) {
|
||||
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
|
||||
}
|
||||
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
|
||||
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
|
||||
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
|
||||
}
|
||||
}
|
||||
|
||||
# unzip and move
|
||||
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
|
||||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
|
||||
try {
|
||||
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
|
||||
} catch {
|
||||
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
|
||||
Write-Error "fail to move MAVEN_HOME"
|
||||
}
|
||||
} finally {
|
||||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||
}
|
||||
|
||||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||
75
pom.xml
75
pom.xml
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>cosmic-maplestory</groupId>
|
||||
@@ -51,24 +50,30 @@
|
||||
<mainClass>net.server.Server</mainClass>
|
||||
|
||||
<!-- Maven plugins -->
|
||||
<maven-surefire-plugin.version>3.2.5</maven-surefire-plugin.version> <!-- For running unit tests -->
|
||||
<maven-jar-plugin.version>3.4.1</maven-jar-plugin.version> <!-- Disabled. (for building thin jar) -->
|
||||
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version> <!-- For running unit tests -->
|
||||
<maven-jar-plugin.version>3.4.2</maven-jar-plugin.version> <!-- Disabled. (for building thin jar) -->
|
||||
<maven-assembly-plugin.version>3.7.1
|
||||
</maven-assembly-plugin.version> <!-- For packaging the executable fat jar -->
|
||||
|
||||
<!-- Dependencies -->
|
||||
<slf4j-api.version>2.0.13</slf4j-api.version> <!-- Logging facade -->
|
||||
<log4j.version>2.23.1</log4j.version> <!-- Slf4j implementation -->
|
||||
<slf4j-api.version>2.0.17</slf4j-api.version> <!-- Logging facade -->
|
||||
<log4j.version>2.25.0</log4j.version> <!-- Slf4j implementation -->
|
||||
<graalvm-js.version>23.0.4</graalvm-js.version>
|
||||
<graalvm-js-scriptengine.version>24.0.1</graalvm-js-scriptengine.version> <!-- ScriptEngine implementation -->
|
||||
<netty.version>4.1.109.Final</netty.version> <!-- Networking -->
|
||||
<netty.version>4.2.2.Final</netty.version> <!-- Networking -->
|
||||
<yamlbeans.version>1.17</yamlbeans.version> <!-- Config file -->
|
||||
<jcip-annotations.version>1.0</jcip-annotations.version> <!-- Annotations for concurrency documentation -->
|
||||
<HikariCP.version>5.1.0</HikariCP.version> <!-- Database connection pool -->
|
||||
<mysql-connector-j.version>8.4.0</mysql-connector-j.version> <!-- MySQL JDBC driver -->
|
||||
<jdbi-version>3.45.1</jdbi-version> <!-- Convenience wrapper around JDBC -->
|
||||
<junit.version>5.10.2</junit.version> <!-- Unit test -->
|
||||
<mockito.version>5.11.0</mockito.version> <!-- Unit test -->
|
||||
<HikariCP.version>6.3.0</HikariCP.version> <!-- Database connection pool -->
|
||||
<mysql-connector-j.version>9.3.0</mysql-connector-j.version> <!-- MySQL JDBC driver -->
|
||||
<jdbi-version>3.49.5</jdbi-version> <!-- Convenience wrapper around JDBC -->
|
||||
<liquibase-core.version>4.32.0</liquibase-core.version> <!-- Database migrations -->
|
||||
<junit.version>5.13.1</junit.version> <!-- Unit test -->
|
||||
<mockito.version>5.18.0</mockito.version> <!-- Unit test -->
|
||||
<testcontainers.version>1.20.1</testcontainers.version> <!-- Docker test with real temporary database -->
|
||||
<postgresql.version>42.5.4</postgresql.version> <!-- PostgreSQL JDBC driver -->
|
||||
<flyway.version>9.15.1</flyway.version> <!-- Database migration -->
|
||||
<caffeine.version>3.1.4</caffeine.version> <!-- Caching -->
|
||||
<lombok.version>1.18.34</lombok.version> <!-- Code generation -->
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -82,6 +87,17 @@
|
||||
<artifactId>jcip-annotations</artifactId>
|
||||
<version>${jcip-annotations.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||
<artifactId>caffeine</artifactId>
|
||||
<version>${caffeine.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Database -->
|
||||
<dependency>
|
||||
@@ -94,12 +110,26 @@
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>${mysql-connector-j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgresql.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jdbi</groupId>
|
||||
<artifactId>jdbi3-core</artifactId>
|
||||
<version>${jdbi-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<version>${flyway.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.liquibase</groupId>
|
||||
<artifactId>liquibase-core</artifactId>
|
||||
<version>${liquibase-core.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Networking -->
|
||||
<dependency>
|
||||
@@ -188,6 +218,25 @@
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${testcontainers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>mysql</artifactId>
|
||||
<version>${testcontainers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${testcontainers.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
/* Rooney
|
||||
Map Name (Map ID)
|
||||
Used to exchange VP for Maple Leaves, and Maple Leaves for rewards.
|
||||
*/
|
||||
|
||||
var itemToUse = 4001126;
|
||||
|
||||
var chairs = [3010000, 3010001, 3010002, 3010003, 3010004, 3010005, 3010006, 3010007, 3010008, 3010009, 3010010, 3010011, 3010012, 3010013, 3010015, 3010016, 3010017, 3010018, 3010019, 3010022, 3010023, 3010024, 3010025, 3010026, 3010028, 3010040, 3010041, 3010043, 3010045, 3010046, 3010047, 3010057, 3010058, 3010060, 3010061, 3010062, 3010063, 3010064, 3010065, 3010066, 3010067, 3010069, 3010071, 3010072, 3010073, 3010080, 3010081, 3010082, 3010083, 3010084, 3010085, 3010097, 3010098, 3010099, 3010101, 3010106, 3010116, 3011000, 3012005, 3012010, 3012011];
|
||||
var scrolls = [2040603, 2044503, 2041024, 2041025, 2044703, 2044603, 2043303, 2040807, 2040806, 2040006, 2040007, 2043103, 2043203, 2043003, 2040506, 2044403, 2040903, 2040709, 2040710, 2040711, 2044303, 2043803, 2040403, 2044103, 2044203, 2044003, 2043703];
|
||||
var weapons = [1302020, 1302030, 1302033, 1302058, 1302064, 1302080, 1312032, 1322054, 1332025, 1332055, 1332056, 1372034, 1382009, 1382012, 1382039, 1402039, 1412011, 1412027, 1422014, 1422029, 1432012, 1432040, 1432046, 1442024, 1442030, 1442051, 1452016, 1452022, 1452045, 1462014, 1462019, 1462040, 1472030, 1472032, 1472055, 1482020, 1482021, 1482022, 1492020, 1492021, 1492022, 1092030, 1092045, 1092046, 1092047];
|
||||
|
||||
var nxAmount = 3000;
|
||||
var chairAmount = 2;
|
||||
var weaponAmount = 2;
|
||||
var buffAmount = 2;
|
||||
var hiredMerchantLength = 7;
|
||||
|
||||
var buff1ID = 2022273;
|
||||
var buff2ID = 2022179;
|
||||
var status;
|
||||
var vp;
|
||||
var choice;
|
||||
|
||||
function start() {
|
||||
//vp = cm.getClient().getVotePoints();
|
||||
//if(vp == null)
|
||||
vp = 0;
|
||||
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode < 0) {
|
||||
cm.dispose();
|
||||
} else {
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
status--;
|
||||
}
|
||||
if (status == 0 && mode == 1) {
|
||||
if (cm.getPlayer().getLevel() < 20) {
|
||||
cm.sendOk("Hello, I am the Vote Point exchanger for #rMapleSolaxia#k!\r\n\r\nI am sorry, but I can only exchange Vote Points for players #blevel 20 or over#k.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
var outStr = "Hello, I am the Vote Point exchanger for #rMapleSolaxia#k!\r\n";
|
||||
outStr += "You currently have #r#c" + itemToUse + "##k #t" + itemToUse + "# and #r" + vp + "#k Vote Points.#b\r\n\r\n";
|
||||
outStr += "#L0#I would like to exchange my vote points for Maple Leaves#l\r\n";
|
||||
outStr += "#L1#I would like to exchange 1 #t" + itemToUse + "# for " + nxAmount + " NX Cash#l\r\n";
|
||||
outStr += "#L2#I would like to exchange 1 #t" + itemToUse + "# for " + chairAmount + " Random Chair" + (chairAmount > 1 ? "s" : "") + "#l\r\n";
|
||||
outStr += "#L3#I would like to exchange 1 #t" + itemToUse + "# for " + weaponAmount + " Maple Weapons#l\r\n";
|
||||
outStr += "#L4#I would like to exchange 1 #t" + itemToUse + "# for " + buffAmount + " #t" + buff1ID + "#s and " + buffAmount + " #t" + buff2ID + "#s#l\r\n";
|
||||
outStr += "#L5#I would like to exchange 1 #t" + itemToUse + "# for a " + hiredMerchantLength + " Day Hired Merchant#l\r\n";
|
||||
cm.sendSimple(outStr);
|
||||
} else if (status == 1) {
|
||||
choice = selection;
|
||||
|
||||
if (selection > 0) {
|
||||
if (!cm.haveItem(itemToUse) && vp == 0) {
|
||||
cm.sendOk("I'm sorry, but you don't have any #t" + itemToUse + " or Vote Points.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (selection == 0) {
|
||||
// Exchange VP for leaves
|
||||
if (vp <= 0) {
|
||||
cm.sendOk("I'm sorry, but you don't have any Vote Points to exchange!");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
cm.sendYesNo("Would you like to exchange " + vp + " Vote Point" + (vp > 0 ? "s" : "") + " for " + vp + " #t" + itemToUse + "# " + (vp > 0 ? "s" : "") + "?");
|
||||
} else if (selection == 1) {
|
||||
// Exchange 1 Leaf for Cash
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for " + nxAmount + " NX Cash?");
|
||||
} else if (selection == 2) {
|
||||
// Exchange 1 Leaf for Chair
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for " + chairAmount + " Random Chair" + (chairAmount > 1 ? "s" : "") + "?");
|
||||
} else if (selection == 3) {
|
||||
// Exchange 1 Leaf for Maple Weapons
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for " + weaponAmount + " Random Maple Weapons?");
|
||||
} else if (selection == 4) {
|
||||
// Exchange 1 Leaf for Apples/Cheese
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for " + buffAmount + " #t" + buff1ID + "# and #t" + buff2ID + "#?");
|
||||
} else if (selection == 5) {
|
||||
// Echange 1 Leaf for Merchant
|
||||
cm.sendYesNo("Would you like to exchange 1 #t" + itemToUse + "# for a " + hiredMerchantLength + " Day Hired Merchant?");
|
||||
} else {
|
||||
cm.dispose();
|
||||
}
|
||||
} else if (status == 2) {
|
||||
var useVP = false;
|
||||
if (!cm.hasItem(itemToUse) && vp > 0) {
|
||||
useVP = true;
|
||||
}
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
if (choice == 0) {
|
||||
// VP Exchange
|
||||
if (!cm.canHold(itemToUse)) {
|
||||
cm.sendOk("It looks like you don't have enough space in your #rETC#k inventory to hold the #t" + itemToUse + "#" + (vp > 0 ? "s" : "") + ".");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
cm.getClient().useVotePoints(vp);
|
||||
cm.gainItem(itemToUse, vp);
|
||||
cm.dispose();
|
||||
} else if (choice == 1) {
|
||||
// Leaf for Cash
|
||||
if (useVP) {
|
||||
cm.getClient().useVotePoints(1);
|
||||
} else {
|
||||
cm.gainItem(itemToUse, -1);
|
||||
}
|
||||
|
||||
cm.getPlayer().getCashShop().gainCash(1, nxAmount);
|
||||
const PacketCreator = Java.type('tools.PacketCreator');
|
||||
cm.getPlayer().sendPacket(PacketCreator.earnTitleMessage("You have earned " + nxAmount + " NX"));
|
||||
cm.logLeaf(nxAmount + " NX");
|
||||
cm.dispose();
|
||||
} else if (choice == 2) {
|
||||
if (!cm.getPlayer().getInventory(InventoryType.SETUP).isFull(chairAmount)) {
|
||||
|
||||
var chairStr = "";
|
||||
for (var i = 0; i < chairAmount; i++) {
|
||||
var chair = chairs[Math.floor(Math.random() * chairs.length)];
|
||||
cm.gainItem(chair, 1, true);
|
||||
chairStr += chair + " ";
|
||||
}
|
||||
|
||||
if (useVP) {
|
||||
cm.getClient().useVotePoints(1);
|
||||
} else {
|
||||
cm.gainItem(itemToUse, -1);
|
||||
}
|
||||
|
||||
cm.logLeaf("Chair ID: " + chairStr);
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("Please make sure you have enough space to hold the items!");
|
||||
}
|
||||
} else if (choice == 3) {
|
||||
if (!cm.getPlayer().getInventory(InventoryType.EQUIP).isFull(weaponAmount)) {
|
||||
|
||||
var weaponStr = "";
|
||||
for (var i = 0; i < weaponAmount; i++) {
|
||||
var weapon = weapons[Math.floor(Math.random() * weapons.length)];
|
||||
cm.gainItem(weapon, 1, true, true);
|
||||
weaponStr += weapon + " ";
|
||||
}
|
||||
|
||||
if (useVP) {
|
||||
cm.getClient().useVotePoints(1);
|
||||
} else {
|
||||
cm.gainItem(itemToUse, -1);
|
||||
}
|
||||
|
||||
cm.logLeaf("Maple Weapon IDs: " + weaponStr);
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("Please make sure you have enough space to hold the items!");
|
||||
}
|
||||
} else if (choice == 4) {
|
||||
if (!cm.getPlayer().getInventory(InventoryType.USE).isFull(2)) {
|
||||
cm.gainItem(buff1ID, buffAmount, true);
|
||||
cm.gainItem(buff2ID, buffAmount, true);
|
||||
cm.gainItem(itemToUse, -1);
|
||||
cm.logLeaf(buffAmount + " cheeses and apples");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("Please make sure you have enough space to hold the items!");
|
||||
}
|
||||
} else if (choice == 5) {
|
||||
if (!cm.haveItem(5030000, 1)) {
|
||||
if (!cm.getPlayer().getInventory(InventoryType.CASH).isFull(1)) {
|
||||
cm.gainItem(5030000, 1, false, true, 1000 * 60 * 60 * 24 * hiredMerchantLength);
|
||||
|
||||
if (useVP) {
|
||||
cm.getClient().useVotePoints(1);
|
||||
} else {
|
||||
cm.gainItem(itemToUse, -1);
|
||||
}
|
||||
|
||||
cm.logLeaf(hiredMerchantLength + " day hired merchant");
|
||||
cm.dispose();
|
||||
} else {
|
||||
cm.sendOk("Please make sure you have enough space to hold these items!");
|
||||
}
|
||||
} else {
|
||||
cm.sendOk("I can't give you a merchant if you already have one!");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
function start() {
|
||||
const ShopFactory = Java.type('server.ShopFactory');
|
||||
ShopFactory.getInstance().getShop(11000).sendShop(cm.getClient());
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -21,25 +21,13 @@ var cpqMaxLvl = 50;
|
||||
var cpqMinAmt = 2;
|
||||
var cpqMaxAmt = 6;
|
||||
|
||||
// Ronan's custom ore refiner NPC
|
||||
var refineRocks = true; // enables moon rock, star rock
|
||||
var refineCrystals = true; // enables common crystals
|
||||
var refineSpecials = true; // enables lithium, special crystals
|
||||
var feeMultiplier = 7.0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_CPQ) {
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
status = 0;
|
||||
action(1, 0, 4);
|
||||
} else {
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -239,9 +227,6 @@ function action(mode, type, selection) {
|
||||
} else {
|
||||
if (status == 0) {
|
||||
var talk = "What would you like to do? If you have never participate in the Monster Carnival, you will need to know a few things before participating! \r\n#b#L0# Go to the Monster Carnival 1.#l \r\n#L3# Go to the Monster Carnival 2.#l \r\n#L1# Learn about the Monster Carnival.#l\r\n#L2# Trade #t4001129#.#l";
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
talk += "\r\n#L4# ... Can I just refine my ores?#l";
|
||||
}
|
||||
cm.sendSimple(talk);
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
@@ -269,24 +254,6 @@ function action(mode, type, selection) {
|
||||
cm.warp(980030000, 0);
|
||||
cm.dispose();
|
||||
|
||||
} else if (selection == 4) {
|
||||
var selStr = "Very well, instead I offer a steadfast #bore refining#k service for you, taxing #r" + ((feeMultiplier * 100) | 0) + "%#k over the usual fee to synthetize them. What will you do?#b";
|
||||
|
||||
var options = ["Refine mineral ores", "Refine jewel ores"];
|
||||
if (refineCrystals) {
|
||||
options.push("Refine crystal ores");
|
||||
}
|
||||
if (refineRocks) {
|
||||
options.push("Refine plates/jewels");
|
||||
}
|
||||
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
|
||||
cm.sendSimple(selStr);
|
||||
|
||||
status = 76;
|
||||
}
|
||||
} else if (status == 2) {
|
||||
select = selection;
|
||||
@@ -445,170 +412,7 @@ function action(mode, type, selection) {
|
||||
} else if (status == 66) {
|
||||
cm.sendNext("Lastly, while in the Monster Carnival, #byou can not use items / recovery potions that you carry around with you. #kMeanwhile, the monsters let these items fall for good. when, and when you #bget them, the item will immediately activate#k. That's why it's important to know when to get these items.");
|
||||
cm.dispose();
|
||||
} else if (status == 77) {
|
||||
var allDone;
|
||||
|
||||
if (selection == 0) {
|
||||
allDone = refineItems(0); // minerals
|
||||
} else if (selection == 1) {
|
||||
allDone = refineItems(1); // jewels
|
||||
} else if (selection == 2 && refineCrystals) {
|
||||
allDone = refineItems(2); // crystals
|
||||
} else if (selection == 2 && !refineCrystals || selection == 3) {
|
||||
allDone = refineRockItems(); // moon/star rock
|
||||
}
|
||||
|
||||
if (allDone) {
|
||||
cm.sendOk("Done. Thanks for showing up~.");
|
||||
} else {
|
||||
cm.sendOk("Done. Be aware some of the items #rcould not be synthetized#k because either you have a lack of space on your ETC inventory or there's not enough mesos to cover the fee.");
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRefineFee(fee) {
|
||||
return ((feeMultiplier * fee) | 0);
|
||||
}
|
||||
|
||||
function isRefineTarget(refineType, refineItemid) {
|
||||
if (refineType == 0) { //mineral refine
|
||||
return refineItemid >= 4010000 && refineItemid <= 4010007 && !(refineItemid == 4010007 && !refineSpecials);
|
||||
} else if (refineType == 1) { //jewel refine
|
||||
return refineItemid >= 4020000 && refineItemid <= 4020008 && !(refineItemid == 4020008 && !refineSpecials);
|
||||
} else if (refineType == 2) { //crystal refine
|
||||
return refineItemid >= 4004000 && refineItemid <= 4004004 && !(refineItemid == 4004004 && !refineSpecials);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRockRefineTarget(refineItemid) {
|
||||
if (refineItemid >= 4011000 && refineItemid <= 4011006) {
|
||||
return 0;
|
||||
} else if (refineItemid >= 4021000 && refineItemid <= 4021008) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function refineItems(refineType) {
|
||||
var allDone = true;
|
||||
|
||||
var refineFees = [[300, 300, 300, 500, 500, 500, 800, 270], [500, 500, 500, 500, 500, 500, 500, 1000, 3000], [5000, 5000, 5000, 5000, 1000000]];
|
||||
var itemCount = {};
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
|
||||
if (isRefineTarget(refineType, itemid)) {
|
||||
var ic = itemCount[itemid];
|
||||
|
||||
if (ic != undefined) {
|
||||
itemCount[itemid] += it.getQuantity();
|
||||
} else {
|
||||
itemCount[itemid] = it.getQuantity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in itemCount) {
|
||||
var itemqty = itemCount[key];
|
||||
var itemid = parseInt(key);
|
||||
|
||||
var refineQty = ((itemqty / 10) | 0);
|
||||
if (refineQty <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
itemqty = refineQty * 10;
|
||||
|
||||
var fee = getRefineFee(refineFees[refineType][(itemid % 100) | 0] * refineQty);
|
||||
if (cm.canHold(itemid + 1000, refineQty, itemid, itemqty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
cm.gainItem(itemid, -itemqty);
|
||||
cm.gainItem(itemid + (itemid != 4010007 ? 1000 : 1001), refineQty);
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
|
||||
function refineRockItems() {
|
||||
var allDone = true;
|
||||
var minItems = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]];
|
||||
var minRocks = [2147483647, 2147483647];
|
||||
|
||||
var rockItems = [4011007, 4021009];
|
||||
var rockFees = [10000, 15000];
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
var rockRefine = getRockRefineTarget(itemid);
|
||||
if (rockRefine >= 0) {
|
||||
var rockItem = ((itemid % 100) | 0);
|
||||
var itemqty = it.getQuantity();
|
||||
|
||||
minItems[rockRefine][rockItem] += itemqty;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < minRocks.length; i++) {
|
||||
for (var j = 0; j < minItems[i].length; j++) {
|
||||
if (minRocks[i] > minItems[i][j]) {
|
||||
minRocks[i] = minItems[i][j];
|
||||
}
|
||||
}
|
||||
if (minRocks[i] <= 0 || minRocks[i] == 2147483647) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var refineQty = minRocks[i];
|
||||
while (true) {
|
||||
var fee = getRefineFee(rockFees[i] * refineQty);
|
||||
if (cm.canHold(rockItems[i], refineQty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
|
||||
var j;
|
||||
if (i == 0) {
|
||||
for (j = 4011000; j < 4011007; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
} else {
|
||||
for (j = 4021000; j < 4021009; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
1.0 - First Version by Drago (MapleStorySA)
|
||||
2.0 - Second Version by Ronan (HeavenMS)
|
||||
3.0 - Third Version by Jayd - translated CPQ contents to English and added Pirate items
|
||||
Special thanks to 頼晏 (ryantpayton) for also stepping in to translate CPQ scripts.
|
||||
---------------------------------------------------------------------------------------------------
|
||||
**/
|
||||
|
||||
@@ -20,25 +21,13 @@ var cpqMaxLvl = 50;
|
||||
var cpqMinAmt = 2;
|
||||
var cpqMaxAmt = 6;
|
||||
|
||||
// Ronan's custom ore refiner NPC
|
||||
var refineRocks = true; // enables moon rock, star rock
|
||||
var refineCrystals = true; // enables common crystals
|
||||
var refineSpecials = true; // enables lithium, special crystals
|
||||
var feeMultiplier = 7.0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_CPQ) {
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
status = 0;
|
||||
action(1, 0, 4);
|
||||
} else {
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -238,9 +227,6 @@ function action(mode, type, selection) {
|
||||
} else {
|
||||
if (status == 0) {
|
||||
var talk = "What would you like to do? If you have never participate in the Monster Carnival, you will need to know a few things before participating! \r\n#b#L0# Go to the Monster Carnival 1.#l \r\n#L3# Go to the Monster Carnival 2.#l \r\n#L1# Learn about the Monster Carnival.#l\r\n#L2# Trade #t4001129#.#l";
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
talk += "\r\n#L4# ... Can I just refine my ores?#l";
|
||||
}
|
||||
cm.sendSimple(talk);
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
@@ -268,24 +254,6 @@ function action(mode, type, selection) {
|
||||
cm.warp(980030000, 0);
|
||||
cm.dispose();
|
||||
|
||||
} else if (selection == 4) {
|
||||
var selStr = "Very well, instead I offer a steadfast #bore refining#k service for you, taxing #r" + ((feeMultiplier * 100) | 0) + "%#k over the usual fee to synthetize them. What will you do?#b";
|
||||
|
||||
var options = ["Refine mineral ores", "Refine jewel ores"];
|
||||
if (refineCrystals) {
|
||||
options.push("Refine crystal ores");
|
||||
}
|
||||
if (refineRocks) {
|
||||
options.push("Refine plates/jewels");
|
||||
}
|
||||
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
|
||||
cm.sendSimple(selStr);
|
||||
|
||||
status = 76;
|
||||
}
|
||||
} else if (status == 2) {
|
||||
select = selection;
|
||||
@@ -439,175 +407,12 @@ function action(mode, type, selection) {
|
||||
cm.sendNext("Oh, and do not worry about turning into a ghost. In the Monster Carnival, #byou will not lose EXP after death#k. So it's really an experience like no other!");
|
||||
cm.dispose();
|
||||
} else if (select == 2) {
|
||||
cm.sendNext("#bProtetor#k basically an invoked item that drastically increases the abilities of the monsters invoked by your group. Protector works until it is demolished by the opposing group, so I'm hoping you'll summon several monsters first, and then bring the Protector.");
|
||||
cm.sendNext("#bProtector#k is basically an invoked item that drastically increases the abilities of the monsters invoked by your group. Protector works until it is demolished by the opposing group, so I'm hoping you'll summon several monsters first, and then bring the Protector.");
|
||||
}
|
||||
} else if (status == 66) {
|
||||
cm.sendNext("Lastly, while in the Monster Carnival, #byou can not use items / recovery potions that you carry around with you. #kMeanwhile, the monsters let these items fall for good. when, and when you #bget them, the item will immediately activate#k. That's why it's important to know when to get these items.");
|
||||
cm.dispose();
|
||||
} else if (status == 77) {
|
||||
var allDone;
|
||||
|
||||
if (selection == 0) {
|
||||
allDone = refineItems(0); // minerals
|
||||
} else if (selection == 1) {
|
||||
allDone = refineItems(1); // jewels
|
||||
} else if (selection == 2 && refineCrystals) {
|
||||
allDone = refineItems(2); // crystals
|
||||
} else if (selection == 2 && !refineCrystals || selection == 3) {
|
||||
allDone = refineRockItems(); // moon/star rock
|
||||
}
|
||||
|
||||
if (allDone) {
|
||||
cm.sendOk("Done. Thanks for showing up~.");
|
||||
} else {
|
||||
cm.sendOk("Done. Be aware some of the items #rcould not be synthetized#k because either you have a lack of space on your ETC inventory or there's not enough mesos to cover the fee.");
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRefineFee(fee) {
|
||||
return ((feeMultiplier * fee) | 0);
|
||||
}
|
||||
|
||||
function isRefineTarget(refineType, refineItemid) {
|
||||
if (refineType == 0) { //mineral refine
|
||||
return refineItemid >= 4010000 && refineItemid <= 4010007 && !(refineItemid == 4010007 && !refineSpecials);
|
||||
} else if (refineType == 1) { //jewel refine
|
||||
return refineItemid >= 4020000 && refineItemid <= 4020008 && !(refineItemid == 4020008 && !refineSpecials);
|
||||
} else if (refineType == 2) { //crystal refine
|
||||
return refineItemid >= 4004000 && refineItemid <= 4004004 && !(refineItemid == 4004004 && !refineSpecials);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRockRefineTarget(refineItemid) {
|
||||
if (refineItemid >= 4011000 && refineItemid <= 4011006) {
|
||||
return 0;
|
||||
} else if (refineItemid >= 4021000 && refineItemid <= 4021008) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function refineItems(refineType) {
|
||||
var allDone = true;
|
||||
|
||||
var refineFees = [[300, 300, 300, 500, 500, 500, 800, 270], [500, 500, 500, 500, 500, 500, 500, 1000, 3000], [5000, 5000, 5000, 5000, 1000000]];
|
||||
var itemCount = {};
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
|
||||
if (isRefineTarget(refineType, itemid)) {
|
||||
var ic = itemCount[itemid];
|
||||
|
||||
if (ic != undefined) {
|
||||
itemCount[itemid] += it.getQuantity();
|
||||
} else {
|
||||
itemCount[itemid] = it.getQuantity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in itemCount) {
|
||||
var itemqty = itemCount[key];
|
||||
var itemid = parseInt(key);
|
||||
|
||||
var refineQty = ((itemqty / 10) | 0);
|
||||
if (refineQty <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
itemqty = refineQty * 10;
|
||||
|
||||
var fee = getRefineFee(refineFees[refineType][(itemid % 100) | 0] * refineQty);
|
||||
if (cm.canHold(itemid + 1000, refineQty, itemid, itemqty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
cm.gainItem(itemid, -itemqty);
|
||||
cm.gainItem(itemid + (itemid != 4010007 ? 1000 : 1001), refineQty);
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
|
||||
function refineRockItems() {
|
||||
var allDone = true;
|
||||
var minItems = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]];
|
||||
var minRocks = [2147483647, 2147483647];
|
||||
|
||||
var rockItems = [4011007, 4021009];
|
||||
var rockFees = [10000, 15000];
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
var rockRefine = getRockRefineTarget(itemid);
|
||||
if (rockRefine >= 0) {
|
||||
var rockItem = ((itemid % 100) | 0);
|
||||
var itemqty = it.getQuantity();
|
||||
|
||||
minItems[rockRefine][rockItem] += itemqty;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < minRocks.length; i++) {
|
||||
for (var j = 0; j < minItems[i].length; j++) {
|
||||
if (minRocks[i] > minItems[i][j]) {
|
||||
minRocks[i] = minItems[i][j];
|
||||
}
|
||||
}
|
||||
if (minRocks[i] <= 0 || minRocks[i] == 2147483647) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var refineQty = minRocks[i];
|
||||
while (true) {
|
||||
var fee = getRefineFee(rockFees[i] * refineQty);
|
||||
if (cm.canHold(rockItems[i], refineQty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
|
||||
var j;
|
||||
if (i == 0) {
|
||||
for (j = 4011000; j < 4011007; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
} else {
|
||||
for (j = 4021000; j < 4021009; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
1.0 - First Version by Drago (MapleStorySA)
|
||||
2.0 - Second Version by Ronan (HeavenMS)
|
||||
3.0 - Third Version by Jayd - translated CPQ contents to English and added Pirate items
|
||||
Special thanks to 頼晏 (ryantpayton) for also stepping in to translate CPQ scripts.
|
||||
---------------------------------------------------------------------------------------------------
|
||||
**/
|
||||
|
||||
@@ -20,25 +21,13 @@ var cpqMaxLvl = 50;
|
||||
var cpqMinAmt = 2;
|
||||
var cpqMaxAmt = 6;
|
||||
|
||||
// Ronan's custom ore refiner NPC
|
||||
var refineRocks = true; // enables moon rock, star rock
|
||||
var refineCrystals = true; // enables common crystals
|
||||
var refineSpecials = true; // enables lithium, special crystals
|
||||
var feeMultiplier = 7.0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_CPQ) {
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
status = 0;
|
||||
action(1, 0, 4);
|
||||
} else {
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
cm.sendOk("The Monster Carnival is currently unavailable.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,6 +48,7 @@ function action(mode, type, selection) {
|
||||
status--;
|
||||
}
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (cm.getPlayer().getMapId() == 980000010) {
|
||||
if (status == 0) {
|
||||
cm.sendNext("I hope you had fun at the Monster Carnival!");
|
||||
@@ -222,9 +212,9 @@ function action(mode, type, selection) {
|
||||
}
|
||||
} else {
|
||||
var party = cm.getParty().getMembers();
|
||||
if ((selection >= 0 && selection <= 3) && party.size() < 1) {
|
||||
if ((selection >= 0 && selection <= 3) && party.size() < (YamlConfig.config.server.USE_ENABLE_SOLO_EXPEDITIONS ? 1 : 2)) {
|
||||
cm.sendOk("You need at least 2 players to participate in the battle!");
|
||||
} else if ((selection >= 4 && selection <= 5) && party.size() < 1) {
|
||||
} else if ((selection >= 4 && selection <= 5) && party.size() < (YamlConfig.config.server.USE_ENABLE_SOLO_EXPEDITIONS ? 1 : 3)) {
|
||||
cm.sendOk("You need at least 3 players to participate in the battle!");
|
||||
} else {
|
||||
cm.cpqLobby(selection);
|
||||
@@ -237,11 +227,6 @@ function action(mode, type, selection) {
|
||||
} else {
|
||||
if (status == 0) {
|
||||
var talk = "What would you like to do? If you have never participate in the Monster Carnival, you will need to know a few things before participating! \r\n#b#L0# Go to the Monster Carnival 1.#l \r\n#L3# Go to the Monster Carnival 2.#l \r\n#L1# Learn about the Monster Carnival.#l\r\n#L2# Trade #t4001129#.#l";
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
talk += "\r\n#L4# ... Can I just refine my ores?#l";
|
||||
}
|
||||
cm.sendSimple(talk);
|
||||
} else if (status == 1) {
|
||||
if (selection == 0) {
|
||||
@@ -269,24 +254,6 @@ function action(mode, type, selection) {
|
||||
cm.warp(980030000, 0);
|
||||
cm.dispose();
|
||||
|
||||
} else if (selection == 4) {
|
||||
var selStr = "Very well, instead I offer a steadfast #bore refining#k service for you, taxing #r" + ((feeMultiplier * 100) | 0) + "%#k over the usual fee to synthetize them. What will you do?#b";
|
||||
|
||||
var options = ["Refine mineral ores", "Refine jewel ores"];
|
||||
if (refineCrystals) {
|
||||
options.push("Refine crystal ores");
|
||||
}
|
||||
if (refineRocks) {
|
||||
options.push("Refine plates/jewels");
|
||||
}
|
||||
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
|
||||
cm.sendSimple(selStr);
|
||||
|
||||
status = 76;
|
||||
}
|
||||
} else if (status == 2) {
|
||||
select = selection;
|
||||
@@ -310,7 +277,7 @@ function action(mode, type, selection) {
|
||||
}
|
||||
} else if (select == 2) {//S2 Warrior 26 S3 Magician 6 S4 Bowman 6 S5 Thief 8
|
||||
status = 10;
|
||||
cm.sendSimple("Please make sure you have #t4001129# for the weapon you want. Select the weapon you would like to trade #t4001129#. The choices I have are really good, and I'm not the one who speaks to the people who say it! \r\n#b#L0# #z1302004# (" + n3 + " coins)#l\r\n#L1# #z1402006# (" + n3 + " coins)#l\r\n#L2# #z1302009# (" + n4 + " coins)#l\r\n#L3# #z1402007# (" + n4 + " coins)#l\r\n#L4# #z1302010# (" + n5 + " coins)#l\r\n#L5# #z1402003# (" + n5 + " coins)#l\r\n#L6# #z1312006# (" + n3 + " coins)#l\r\n#L7# #z1412004# (" + n3 + " coins)#l\r\n#L8# #z1312007# (" + n4 + " coins)#l\r\n#L9# #z1412005# (" + n4 + " coins)#l\r\n#L10# #z1312008# (" + n5 + " coins)#l\r\n#L11# #z1412003# (" + n5 + " coins)#l\r\n#L12# Continue to the next page(1/2)#l");
|
||||
cm.sendSimple("Please make sure you have # t4001129 # for the weapon you want. Select the weapon you would like to trade # t4001129 #. The choices I have are really good, and I'm not the one who speaks to the people who say it! \r\n#b#L0# #z1302004# (" + n3 + " coins)#l\r\n#L1# #z1402006# (" + n3 + " coins)#l\r\n#L2# #z1302009# (" + n4 + " coins)#l\r\n#L3# #z1402007# (" + n4 + " coins)#l\r\n#L4# #z1302010# (" + n5 + " coins)#l\r\n#L5# #z1402003# (" + n5 + " coins)#l\r\n#L6# #z1312006# (" + n3 + " coins)#l\r\n#L7# #z1412004# (" + n3 + " coins)#l\r\n#L8# #z1312007# (" + n4 + " coins)#l\r\n#L9# #z1412005# (" + n4 + " coins)#l\r\n#L10# #z1312008# (" + n5 + " coins)#l\r\n#L11# #z1412003# (" + n5 + " coins)#l\r\n#L12# Continue to the next page (1/2)#l");
|
||||
} else if (select == 3) {
|
||||
status = 20;
|
||||
cm.sendSimple("Select the weapon you would like to trade. The weapons I have here are extremely attractive. See for yourself! \r\n#b#L0# #z1372001# (" + n3 + " coins)#l\r\n#L1# #z1382018# (" + n3 + " coins)#l\r\n#L2# #z1372012# (" + n4 + " coins)#l\r\n#L3# #z1382019# (" + n4 + " coins)#l\r\n#L4# #z1382001# (" + n5 + " coins)#l\r\n#L5# #z1372007# (" + n5 + " coins)#l");
|
||||
@@ -440,175 +407,12 @@ function action(mode, type, selection) {
|
||||
cm.sendNext("Oh, and do not worry about turning into a ghost. In the Monster Carnival, #byou will not lose EXP after death#k. So it's really an experience like no other!");
|
||||
cm.dispose();
|
||||
} else if (select == 2) {
|
||||
cm.sendNext("#bProtetor#k basically an invoked item that drastically increases the abilities of the monsters invoked by your group. Protector works until it is demolished by the opposing group, so I'm hoping you'll summon several monsters first, and then bring the Protector.");
|
||||
cm.sendNext("#bProtector#k is basically an invoked item that drastically increases the abilities of the monsters invoked by your group. Protector works until it is demolished by the opposing group, so I'm hoping you'll summon several monsters first, and then bring the Protector.");
|
||||
}
|
||||
} else if (status == 66) {
|
||||
cm.sendNext("Lastly, while in the Monster Carnival, #byou can not use items / recovery potions that you carry around with you. #kMeanwhile, the monsters let these items fall for good. when, and when you #bget them, the item will immediately activate#k. That's why it's important to know when to get these items.");
|
||||
cm.dispose();
|
||||
} else if (status == 77) {
|
||||
var allDone;
|
||||
|
||||
if (selection == 0) {
|
||||
allDone = refineItems(0); // minerals
|
||||
} else if (selection == 1) {
|
||||
allDone = refineItems(1); // jewels
|
||||
} else if (selection == 2 && refineCrystals) {
|
||||
allDone = refineItems(2); // crystals
|
||||
} else if (selection == 2 && !refineCrystals || selection == 3) {
|
||||
allDone = refineRockItems(); // moon/star rock
|
||||
}
|
||||
|
||||
if (allDone) {
|
||||
cm.sendOk("Done. Thanks for showing up~.");
|
||||
} else {
|
||||
cm.sendOk("Done. Be aware some of the items #rcould not be synthetized#k because either you have a lack of space on your ETC inventory or there's not enough mesos to cover the fee.");
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRefineFee(fee) {
|
||||
return ((feeMultiplier * fee) | 0);
|
||||
}
|
||||
|
||||
function isRefineTarget(refineType, refineItemid) {
|
||||
if (refineType == 0) { //mineral refine
|
||||
return refineItemid >= 4010000 && refineItemid <= 4010007 && !(refineItemid == 4010007 && !refineSpecials);
|
||||
} else if (refineType == 1) { //jewel refine
|
||||
return refineItemid >= 4020000 && refineItemid <= 4020008 && !(refineItemid == 4020008 && !refineSpecials);
|
||||
} else if (refineType == 2) { //crystal refine
|
||||
return refineItemid >= 4004000 && refineItemid <= 4004004 && !(refineItemid == 4004004 && !refineSpecials);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRockRefineTarget(refineItemid) {
|
||||
if (refineItemid >= 4011000 && refineItemid <= 4011006) {
|
||||
return 0;
|
||||
} else if (refineItemid >= 4021000 && refineItemid <= 4021008) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function refineItems(refineType) {
|
||||
var allDone = true;
|
||||
|
||||
var refineFees = [[300, 300, 300, 500, 500, 500, 800, 270], [500, 500, 500, 500, 500, 500, 500, 1000, 3000], [5000, 5000, 5000, 5000, 1000000]];
|
||||
var itemCount = {};
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
|
||||
if (isRefineTarget(refineType, itemid)) {
|
||||
var ic = itemCount[itemid];
|
||||
|
||||
if (ic != undefined) {
|
||||
itemCount[itemid] += it.getQuantity();
|
||||
} else {
|
||||
itemCount[itemid] = it.getQuantity();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in itemCount) {
|
||||
var itemqty = itemCount[key];
|
||||
var itemid = parseInt(key);
|
||||
|
||||
var refineQty = ((itemqty / 10) | 0);
|
||||
if (refineQty <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
itemqty = refineQty * 10;
|
||||
|
||||
var fee = getRefineFee(refineFees[refineType][(itemid % 100) | 0] * refineQty);
|
||||
if (cm.canHold(itemid + 1000, refineQty, itemid, itemqty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
cm.gainItem(itemid, -itemqty);
|
||||
cm.gainItem(itemid + (itemid != 4010007 ? 1000 : 1001), refineQty);
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
|
||||
function refineRockItems() {
|
||||
var allDone = true;
|
||||
var minItems = [[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]];
|
||||
var minRocks = [2147483647, 2147483647];
|
||||
|
||||
var rockItems = [4011007, 4021009];
|
||||
var rockFees = [10000, 15000];
|
||||
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
var iter = cm.getPlayer().getInventory(InventoryType.ETC).iterator();
|
||||
while (iter.hasNext()) {
|
||||
var it = iter.next();
|
||||
var itemid = it.getItemId();
|
||||
var rockRefine = getRockRefineTarget(itemid);
|
||||
if (rockRefine >= 0) {
|
||||
var rockItem = ((itemid % 100) | 0);
|
||||
var itemqty = it.getQuantity();
|
||||
|
||||
minItems[rockRefine][rockItem] += itemqty;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < minRocks.length; i++) {
|
||||
for (var j = 0; j < minItems[i].length; j++) {
|
||||
if (minRocks[i] > minItems[i][j]) {
|
||||
minRocks[i] = minItems[i][j];
|
||||
}
|
||||
}
|
||||
if (minRocks[i] <= 0 || minRocks[i] == 2147483647) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var refineQty = minRocks[i];
|
||||
while (true) {
|
||||
var fee = getRefineFee(rockFees[i] * refineQty);
|
||||
if (cm.canHold(rockItems[i], refineQty) && cm.getMeso() >= fee) {
|
||||
cm.gainMeso(-fee);
|
||||
|
||||
var j;
|
||||
if (i == 0) {
|
||||
for (j = 4011000; j < 4011007; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
} else {
|
||||
for (j = 4021000; j < 4021009; j++) {
|
||||
cm.gainItem(j, -refineQty);
|
||||
}
|
||||
cm.gainItem(j, refineQty);
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (refineQty <= 1) {
|
||||
allDone = false;
|
||||
break;
|
||||
} else {
|
||||
refineQty--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allDone;
|
||||
}
|
||||
}
|
||||
@@ -40,10 +40,7 @@ function action(mode, type, selection) {
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.openShopNPC(2082014);
|
||||
} else if (cm.isQuestStarted(3749)) {
|
||||
if (cm.isQuestStarted(3749)) {
|
||||
cm.sendOk("We've already located the enemy's ultimate weapon! Follow along the ship's bow area ahead and you will find my sister #b#p2082013##k. Report to her for futher instructions on the mission.");
|
||||
} else {
|
||||
cm.sendDefault();
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
var status = 0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
cm.openShopNPC(2100002);
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
var status = 0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
cm.openShopNPC(2100003);
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -58,8 +58,8 @@ function action(mode, type, selection) {
|
||||
}
|
||||
}
|
||||
if (cm.getChar().getGender() == 1) {
|
||||
for (var i = 0; i < fface.length; i++) {
|
||||
pushIfItemExists(facenew, fface[i] + cm.getChar().getFace()
|
||||
for (var i = 0; i < fface_v.length; i++) {
|
||||
pushIfItemExists(facenew, fface_v[i] + cm.getChar().getFace()
|
||||
% 1000 - (cm.getChar().getFace()
|
||||
% 100));
|
||||
}
|
||||
|
||||
@@ -17,127 +17,9 @@
|
||||
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/>.
|
||||
*/
|
||||
/* Coco
|
||||
Refining NPC:
|
||||
* Chaos scroll SYNTHETIZER (rofl)
|
||||
*
|
||||
* @author RonanLana (ronancpl)
|
||||
*/
|
||||
|
||||
var status = 0;
|
||||
var selectedType = -1;
|
||||
var selectedItem = -1;
|
||||
var item;
|
||||
var mats;
|
||||
var matQty;
|
||||
var cost;
|
||||
var qty;
|
||||
var equip;
|
||||
var last_use; //last item is a use item
|
||||
/* Coco */
|
||||
|
||||
function start() {
|
||||
cm.getPlayer().setCS(true);
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
cm.sendOk("Oh, ok... Talk back to us when you want to make business.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.sendOk("Hi, I'm #b#p" + cm.getNpc() + "##k.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
var selStr = "Hey traveler! Come, come closer... We offer a #bhuge opportunity of business#k to you. If you want to know what it is, keep listening...";
|
||||
cm.sendNext(selStr);
|
||||
} else if (status == 1) {
|
||||
var selStr = "We've got here the knowledge to synthetize the mighty #b#t2049100##k! Of course, making one is not an easy task... But worry not! Just gather some material to me and a fee of #b1,200,000 mesos#k for our services to #bobtain it#k. You still want to do it?";
|
||||
cm.sendYesNo(selStr);
|
||||
} else if (status == 2) {
|
||||
//selectedItem = selection;
|
||||
selectedItem = 0;
|
||||
|
||||
var itemSet = [2049100, 7777777];
|
||||
var matSet = new Array([4031203, 4001356, 4000136, 4000082, 4001126, 4080100, 4000021, 4003005]);
|
||||
var matQtySet = new Array([100, 60, 40, 80, 10, 8, 200, 120]);
|
||||
var costSet = [1200000, 7777777];
|
||||
item = itemSet[selectedItem];
|
||||
mats = matSet[selectedItem];
|
||||
matQty = matQtySet[selectedItem];
|
||||
cost = costSet[selectedItem];
|
||||
|
||||
var prompt = "So, you want us to make some #t" + item + "#? In that case, how many do you want us to make?";
|
||||
cm.sendGetNumber(prompt, 1, 1, 100)
|
||||
} else if (status == 3) {
|
||||
qty = (selection > 0) ? selection : (selection < 0 ? -selection : 1);
|
||||
last_use = false;
|
||||
|
||||
var prompt = "You want us to make ";
|
||||
if (qty == 1) {
|
||||
prompt += "a #t" + item + "#?";
|
||||
} else {
|
||||
prompt += qty + " #t" + item + "#?";
|
||||
}
|
||||
|
||||
prompt += " In that case, we're going to need specific items from you in order to make it. Make sure you have room in your inventory, though!#b";
|
||||
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; i < mats.length; i++) {
|
||||
prompt += "\r\n#i" + mats[i] + "# " + matQty[i] * qty + " #t" + mats[i] + "#";
|
||||
}
|
||||
} else {
|
||||
prompt += "\r\n#i" + mats + "# " + matQty * qty + " #t" + mats + "#";
|
||||
}
|
||||
|
||||
if (cost > 0) {
|
||||
prompt += "\r\n#i4031138# " + cost * qty + " meso";
|
||||
}
|
||||
cm.sendYesNo(prompt);
|
||||
} else if (status == 4) {
|
||||
var complete = true;
|
||||
|
||||
if (cm.getMeso() < cost * qty) {
|
||||
cm.sendOk("Come on! We're not here doing you a favor! We all need money to live properly, so bring the cash so we make deal and start the synthesis.");
|
||||
} else if (!cm.canHold(item, qty)) {
|
||||
cm.sendOk("You didn't check if you got a slot to spare on your inventory before our business, no?");
|
||||
} else {
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; complete && i < mats.length; i++) {
|
||||
if (matQty[i] * qty == 1) {
|
||||
complete = cm.haveItem(mats[i]);
|
||||
} else {
|
||||
complete = cm.haveItem(mats[i], matQty[i] * qty);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
complete = cm.haveItem(mats, matQty * qty);
|
||||
}
|
||||
|
||||
if (!complete) {
|
||||
cm.sendOk("You kidding, right? We won't be able to start the process without all the ingredients at hands. Go get all of them and then talk to us!");
|
||||
} else {
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; i < mats.length; i++) {
|
||||
cm.gainItem(mats[i], -matQty[i] * qty);
|
||||
}
|
||||
} else {
|
||||
cm.gainItem(mats, -matQty * qty);
|
||||
}
|
||||
cm.gainMeso(-cost * qty);
|
||||
cm.gainItem(item, qty);
|
||||
cm.sendOk("Wow... can't believe it worked! To think for a moment that it could f... Ahem. Of course it worked, all work of ours are very efficient! Nice doing business with you.");
|
||||
}
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
cm.sendDefault();
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -19,208 +19,9 @@
|
||||
*/
|
||||
/* NPC: Agent E (9000036)
|
||||
Victoria Road : Henesys
|
||||
|
||||
Refining NPC:
|
||||
* Accessories refiner
|
||||
*
|
||||
* @author Ronan Lana
|
||||
*/
|
||||
|
||||
var status = -1;
|
||||
var selectedType = -1;
|
||||
var selectedItem = -1;
|
||||
var item;
|
||||
var items;
|
||||
var mats;
|
||||
var matQty;
|
||||
var cost;
|
||||
var qty = 1;
|
||||
var equip;
|
||||
var maxEqp = 0;
|
||||
|
||||
function start() {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.sendOk("Hi, I'm #b#p" + cm.getNpc() + "##k.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
cm.getPlayer().setCS(true);
|
||||
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";
|
||||
}
|
||||
cm.sendSimple(selStr);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
status++;
|
||||
if (mode != 1) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (status == 0) {
|
||||
if (selection == 0) { //pendants
|
||||
var selStr = "Well, I've got these pendants on my repertoire:#b";
|
||||
items = [1122018, 1122007, 1122001, 1122003, 1122004, 1122006, 1122002, 1122005, 1122058];
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##b";
|
||||
}
|
||||
} else if (selection == 1) { //face accessory
|
||||
var selStr = "Hmm, face accessories? There you go: #b";
|
||||
items = [1012181, 1012182, 1012183, 1012184, 1012185, 1012186, 1012108, 1012109, 1012110, 1012111];
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##b";
|
||||
}
|
||||
} else if (selection == 2) { //eye accessory
|
||||
var selStr = "Got hard sight? Okay, so which glasses do you want me to make?#b";
|
||||
items = [1022073, 1022088, 1022103, 1022089, 1022082];
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##b";
|
||||
}
|
||||
} else if (selection == 3) { //belt & medal
|
||||
var selStr = "Hmm... For these, things get a little tricky. Since these items are too short and too similar one another, I don't really know what item will emerge when I finish the synthesis. Still wanna try for something?";
|
||||
items = [];
|
||||
maxEqp = 0;
|
||||
|
||||
for (var x = 1132005; x < 1132017; maxEqp++, x++) {
|
||||
items[maxEqp] = x;
|
||||
}
|
||||
|
||||
for (var x = 1142000; x < 1142102; maxEqp++, x++) {
|
||||
items[maxEqp] = x;
|
||||
}
|
||||
|
||||
for (var x = 1142107; x < 1142121; maxEqp++, x++) {
|
||||
items[maxEqp] = x;
|
||||
}
|
||||
|
||||
for (var x = 1142122; x < 1142143; maxEqp++, x++) {
|
||||
items[maxEqp] = x;
|
||||
}
|
||||
selStr += "\r\n#L" + i + "##bTry it!#b";
|
||||
|
||||
} else if (selection == 4) { //ring refine
|
||||
var selStr = "Rings, huh? These are my specialty, go check it yourself!#b";
|
||||
items = [1112407, 1112408, 1112401, 1112413, 1112414, 1112405, 1112402];
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##b";
|
||||
}
|
||||
|
||||
}/*else if (selection == 5) { //make necklace
|
||||
var selStr = "Need to make #t4032496#?#b";
|
||||
items = [4032496];
|
||||
for (var i = 0; i < items.length; i++)
|
||||
selStr += "\r\n#L" + i + "##t" + items[i] + "##l";
|
||||
}*/
|
||||
selectedType = selection;
|
||||
cm.sendSimple(selStr);
|
||||
} else if (status == 1) {
|
||||
if (selectedType != 3) {
|
||||
selectedItem = selection;
|
||||
}
|
||||
|
||||
if (selectedType == 0) { //pendant refine
|
||||
var matSet = [[4003004, 4030012, 4001356, 4000026], [4000026, 4001356, 4000073, 4001006], [4001343, 4011002, 4003004, 4003005], [4001343, 4011006, 4003004, 4003005], [4000091, 4011005, 4003004, 4003005], [4000091, 4011001, 4003004, 4003005], [4000469, 4011000, 4003004, 4003005], [4000469, 4011004, 4003004, 4003005], [1122007, 4003002, 4000413]];
|
||||
var matQtySet = [[20, 20, 5, 1], [5, 5, 10, 1], [10, 2, 20, 4], [10, 1, 20, 4], [15, 3, 30, 6], [15, 3, 30, 6], [20, 5, 20, 8], [20, 4, 40, 8], [1, 1, 1]];
|
||||
var costSet = [150000, 500000, 200000, 200000, 300000, 300000, 400000, 400000, 2500000];
|
||||
} else if (selectedType == 1) { //face accessory refine
|
||||
var matSet = [[4006000, 4003004], [4006000, 4003004, 4000026], [4006000, 4003004, 4000026, 4000082, 4003002], [4006000, 4003005], [4006000, 4003005, 4000026], [4006000, 4003005, 4000026, 4000082, 4003002], [4001006, 4011008], [4001006, 4011008], [4001006, 4011008], [4001006, 4011008]];
|
||||
var matQtySet = [[5, 5], [5, 5, 5], [5, 5, 5, 5, 1], [5, 5], [5, 5, 5], [5, 5, 5, 5, 1], [1, 1], [1, 1], [1, 1], [1, 1]];
|
||||
var costSet = [100000, 200000, 300000, 125000, 250000, 375000, 500000, 500000, 500000, 500000, 25000, 25000, 25000, 25000];
|
||||
} else if (selectedType == 2) { //eye accessory refine
|
||||
var matSet = [[4001006, 4003002, 4000082, 4031203], [4001005, 4011008], [4001005, 4011008], [4001005, 4011008, 4000082], [4001006, 4003002, 4003000, 4003001]];
|
||||
var matQtySet = [[2, 2, 5, 10], [3, 2], [4, 3], [5, 3, 10], [2, 2, 10, 5]];
|
||||
var costSet = [250000, 250000, 300000, 400000, 200000];
|
||||
} else if (selectedType == 3) { //belt & medals refine
|
||||
var matSet = [[4001006, 4003005, 4003004], [7777, 7777]];
|
||||
var matQtySet = [[2, 5, 10], [7777, 7777]];
|
||||
var costSet = [15000, 7777];
|
||||
} else if (selectedType == 4) { //ring refine
|
||||
var matSet = [[4003001, 4001344, 4006000], [4003001, 4001344, 4006000], [4021004, 4011008], [4011008, 4001006], [1112413, 2022039], [1112414, 4000176], [4011007, 4021009]];
|
||||
var matQtySet = [[2, 2, 2], [2, 2, 2], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1]];
|
||||
var costSet = [10000, 10000, 10000, 20000, 15000, 15000, 10000];
|
||||
}/*else if (selectedType == 5) { //necklace refine
|
||||
var matSet = [[4011007, 4011008, 4021009]];
|
||||
var matQtySet = [[1, 1, 1]];
|
||||
var costSet = [10000];
|
||||
}*/
|
||||
|
||||
if (selectedType == 3) {
|
||||
selectedItem = Math.floor(Math.random() * maxEqp);
|
||||
item = items[selectedItem];
|
||||
mats = matSet[0];
|
||||
matQty = matQtySet[0];
|
||||
cost = costSet[0];
|
||||
} else {
|
||||
item = items[selectedItem];
|
||||
mats = matSet[selectedItem];
|
||||
matQty = matQtySet[selectedItem];
|
||||
cost = costSet[selectedItem];
|
||||
}
|
||||
|
||||
var prompt = "You want me to make ";
|
||||
if (selectedType != 3) {
|
||||
if (qty == 1) {
|
||||
prompt += "a #b#t" + item + "##k?";
|
||||
} else {
|
||||
prompt += "#b" + qty + " #t" + item + "##k?";
|
||||
}
|
||||
} else {
|
||||
prompt += "a #bbelt#k or a #bmedal#k?";
|
||||
}
|
||||
|
||||
prompt += " Right! I will need some items to make that item. Make sure you have a #bfree slot#k in your inventory!#b";
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; i < mats.length; i++) {
|
||||
prompt += "\r\n#i" + mats[i] + "# " + (matQty[i] * qty) + " #t" + mats[i] + "#";
|
||||
}
|
||||
} else {
|
||||
prompt += "\r\n#i" + mats + "# " + (matQty * qty) + " #t" + mats + "#";
|
||||
}
|
||||
if (cost > 0) {
|
||||
prompt += "\r\n#i4031138# " + (cost * qty) + " meso";
|
||||
}
|
||||
cm.sendYesNo(prompt);
|
||||
} else if (status == 2) {
|
||||
if (cm.getMeso() < (cost * qty)) {
|
||||
cm.sendOk("This is the fee I charge to make my items! No credit.");
|
||||
} else {
|
||||
var complete = true;
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; complete && i < mats.length; i++) {
|
||||
if (!cm.haveItem(mats[i], matQty[i] * qty)) {
|
||||
complete = false;
|
||||
}
|
||||
}
|
||||
} else if (!cm.haveItem(mats, matQty * qty)) {
|
||||
complete = false;
|
||||
}
|
||||
|
||||
if (!complete) {
|
||||
cm.sendOk("Are you sure you got all the items required? Double check it!");
|
||||
} else {
|
||||
if (cm.canHold(item, qty)) {
|
||||
if (mats instanceof Array) {
|
||||
for (var i = 0; i < mats.length; i++) {
|
||||
cm.gainItem(mats[i], -(matQty[i] * qty));
|
||||
}
|
||||
} else {
|
||||
cm.gainItem(mats, -(matQty * qty));
|
||||
}
|
||||
cm.gainMeso(-(cost * qty));
|
||||
|
||||
cm.gainItem(item, qty);
|
||||
cm.sendOk("The item is done! Take and try this piece of art yourself.");
|
||||
} else {
|
||||
cm.sendOk("You got no free slot on your inventory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cm.dispose();
|
||||
}
|
||||
cm.sendDefault();
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
@@ -19,72 +19,9 @@
|
||||
*/
|
||||
/* Dalair
|
||||
Medal NPC.
|
||||
|
||||
NPC Equipment Merger:
|
||||
* @author Ronan Lana
|
||||
*/
|
||||
|
||||
var status;
|
||||
var mergeFee = 50000;
|
||||
var name;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == -1) {
|
||||
cm.dispose();
|
||||
} else {
|
||||
if (mode == 0 && type > 0) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
status--;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.sendOk("The medal ranking system is currently unavailable...");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
var levelLimit = !cm.getPlayer().isCygnus() ? 160 : 110;
|
||||
var selStr = "The medal ranking system is currently unavailable... Therefore, I am providing the #bEquipment Merge#k service! ";
|
||||
|
||||
const MakerProcessor = Java.type('client.processor.action.MakerProcessor');
|
||||
if (!YamlConfig.config.server.USE_STARTER_MERGE && (cm.getPlayer().getLevel() < levelLimit || MakerProcessor.getMakerSkillLevel(cm.getPlayer()) < 3)) {
|
||||
selStr += "However, you must have #rMaker level 3#k and at least #rlevel 110#k (Cygnus Knight), #rlevel 160#k (other classes) and a fund of #r" + cm.numberWithCommas(mergeFee) + " mesos#k to use the service.";
|
||||
cm.sendOk(selStr);
|
||||
cm.dispose();
|
||||
} else if (cm.getMeso() < mergeFee) {
|
||||
selStr += "I'm sorry, but this service tax is of #r" + cm.numberWithCommas(mergeFee) + " mesos#k, which it seems you unfortunately don't have right now... Please, stop by again later.";
|
||||
cm.sendOk(selStr);
|
||||
cm.dispose();
|
||||
} else {
|
||||
selStr += "For the fee of #r" + cm.numberWithCommas(mergeFee) + "#k mesos, merge unnecessary equipments in your inventory into your currently equipped gears to get stat boosts into them, statups based on the attributes of the items used on the merge!";
|
||||
cm.sendNext(selStr);
|
||||
}
|
||||
} else if (status == 1) {
|
||||
selStr = "#rWARNING#b: Make sure you have your items ready to merge at the slots #rAFTER#b the item you have selected to merge.#k Any items #bunder#k the item selected will be merged thoroughly.\r\n\r\nNote that equipments receiving bonuses from merge are going to become #rUntradeable#k thereon, and equipments that already received the merge bonus #rcannot be used for merge#k.\r\n\r\n";
|
||||
cm.sendGetText(selStr);
|
||||
} else if (status == 2) {
|
||||
name = cm.getText();
|
||||
|
||||
if (cm.getPlayer().mergeAllItemsFromName(name)) {
|
||||
cm.gainMeso(-mergeFee);
|
||||
cm.sendOk("Merging complete! Thanks for using the service and enjoy your new equipment stats.");
|
||||
} else {
|
||||
cm.sendOk("There is no #b'" + name + "'#k in your #bEQUIP#k inventory!");
|
||||
}
|
||||
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
cm.sendOk("The medal ranking system is currently unavailable...");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
@@ -19,54 +19,9 @@
|
||||
*/
|
||||
/* NPC: Donation Box (9000041)
|
||||
Victoria Road : Henesys
|
||||
|
||||
NPC Bazaar:
|
||||
* @author Ronan Lana
|
||||
*/
|
||||
|
||||
var options = ["EQUIP", "USE", "SET-UP", "ETC"];
|
||||
var name;
|
||||
var status;
|
||||
var selectedType = 0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
cm.sendOk("The medal ranking system is currently unavailable...");
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
status++;
|
||||
if (mode != 1) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (!YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.sendOk("The medal ranking system is currently unavailable...");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
var selStr = "Hello, I am the #bBazaar NPC#k! Sell to me any item on your inventory you don't need. #rWARNING#b: Make sure you have your items ready to sell at the slots #rAFTER#b the item you have selected to sell.#k Any items #bunder#k the item selected will be sold thoroughly.";
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
selStr += "\r\n#L" + i + "# " + options[i] + "#l";
|
||||
}
|
||||
cm.sendSimple(selStr);
|
||||
} else if (status == 1) {
|
||||
selectedType = selection;
|
||||
cm.sendGetText("From what item on your #r" + options[selectedType] + "#k inventory do you want to start the transaction?");
|
||||
} else if (status == 2) {
|
||||
name = cm.getText();
|
||||
var res = cm.getPlayer().sellAllItemsFromName(selectedType + 1, name);
|
||||
|
||||
if (res > -1) {
|
||||
cm.sendOk("Transaction complete! You received #r" + cm.numberWithCommas(res) + " mesos#k from this action.");
|
||||
} else {
|
||||
cm.sendOk("There is no #b'" + name + "'#k in your #b" + options[selectedType] + "#k inventory!");
|
||||
}
|
||||
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ function action(mode, type, selection) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (cm.getMeso < price) {
|
||||
if (cm.getMeso() < price) {
|
||||
cm.sendOk("Please check and see if you have " + price + " mesos to enter this place.");
|
||||
} else {
|
||||
cm.gainMeso(-price);
|
||||
|
||||
@@ -1,14 +1,88 @@
|
||||
/**
|
||||
*9201098 - Mo
|
||||
*@author Ronan
|
||||
* 9201098 - Mo
|
||||
* @author Ronan
|
||||
* @author Ponk
|
||||
*/
|
||||
|
||||
let status = 0;
|
||||
let selectedItem = undefined;
|
||||
|
||||
/*
|
||||
References:
|
||||
- https://www.youtube.com/watch?v=g6y2zmCGglI
|
||||
- https://www.youtube.com/watch?v=CttmlVWLJKM
|
||||
*/
|
||||
function start() {
|
||||
if (cm.getQuestStatus(8224) == 2) {
|
||||
cm.openShopNPC(9201099);
|
||||
} else {
|
||||
cm.sendOk("Hm, at who do you think you are looking at?");
|
||||
if (cm.getQuestStatus(8224) !== 2) {
|
||||
cm.sendDefault();
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
cm.dispose();
|
||||
cm.sendSimple("Name's Mo. I've got Mo' items for Mo' mesos. What business do you bring me?\r\n#L0##bI'd like to buy some items#k");
|
||||
}
|
||||
|
||||
function action(action, type, selection) {
|
||||
if (!action) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
if (status === 0) {
|
||||
let index = 0;
|
||||
const selections = "#e" + shopItems()
|
||||
.map(i => {
|
||||
const mesoText = i.quantity === 1 ? "meso" : `meso per ${i.quantity} arrows`;
|
||||
return `\r\n#L${index++}##i${i.itemId}# #z${i.itemId}# #b${i.cost} ${mesoText}#k`;
|
||||
})
|
||||
.join("");
|
||||
cm.sendSimple("An ally of the Raven Ninja Clan is welcome to buy from me!" + selections);
|
||||
status++;
|
||||
} else if (status === 1 && selection !== -1) {
|
||||
selectedItem = shopItems()[selection];
|
||||
cm.sendAcceptDecline("Are you sure you want to buy it?");
|
||||
status++;
|
||||
} else if (status === 2) {
|
||||
if (!selectedItem) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (!cm.hasMeso(selectedItem.cost)) {
|
||||
cm.sendOk("You don't have enough mesos.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (!cm.canHold(selectedItem.itemId, selectedItem.quantity)) {
|
||||
cm.sendOk("There's no room in your inventory.");
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
cm.loseMeso(selectedItem.cost);
|
||||
cm.gainItem(selectedItem.itemId, selectedItem.quantity);
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
function shopItems() {
|
||||
return [
|
||||
{itemId: 2050004, quantity: 1, cost: 400}, // All-Cure Potion
|
||||
{itemId: 2050000, quantity: 1, cost: 200}, // Antidote
|
||||
{itemId: 2020012, quantity: 1, cost: 4500}, // Melting Cheese
|
||||
{itemId: 2020013, quantity: 1, cost: 5000}, // Reindeer Milk
|
||||
{itemId: 2020014, quantity: 1, cost: 8100}, // Sunrise Dew
|
||||
{itemId: 2020015, quantity: 1, cost: 9690}, // Sunset Dew
|
||||
{itemId: 2050001, quantity: 1, cost: 200}, // Eyedrop
|
||||
{itemId: 2050002, quantity: 1, cost: 300}, // Tonic
|
||||
{itemId: 2050003, quantity: 1, cost: 500}, // Holy Water
|
||||
{itemId: 2022000, quantity: 1, cost: 1650}, // Pure Water
|
||||
{itemId: 2002017, quantity: 1, cost: 5000}, // Warrior Elixir
|
||||
{itemId: 2060004, quantity: 2000, cost: 40_000}, // Diamond Arrow for Bow
|
||||
{itemId: 2061004, quantity: 2000, cost: 40_000}, // Diamond Arrow for Crossbow
|
||||
{itemId: 2070010, quantity: 1, cost: 2000}, // Icicle
|
||||
{itemId: 2022003, quantity: 1, cost: 1100}, // Unagi
|
||||
{itemId: 2000006, quantity: 1, cost: 620}, // Mana Elixir
|
||||
{itemId: 2022002, quantity: 1, cost: 1000}, // Cider
|
||||
{itemId: 2030020, quantity: 1, cost: 400}, // Return to New Leaf City Scroll
|
||||
]
|
||||
}
|
||||
|
||||
@@ -4,13 +4,6 @@
|
||||
*/
|
||||
|
||||
function start() {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.openShopNPC(9201101);
|
||||
} else {
|
||||
//cm.sendOk("The patrol in New Leaf City is always ready. No creatures are able to break through to the city.");
|
||||
cm.sendDefault();
|
||||
}
|
||||
|
||||
cm.sendDefault();
|
||||
cm.dispose();
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ var staff_heading = "!";
|
||||
var levels = ["Common", "Donator", "JrGM", "GM", "SuperGM", "Developer", "Admin"];
|
||||
var commands;
|
||||
|
||||
// Expectation: "ce" bound to an instance of java.client.command.CommandsExecutor
|
||||
function writeHeavenMSCommands() {
|
||||
const CommandsExecutor = Java.type('client.command.CommandsExecutor');
|
||||
commands = CommandsExecutor.getInstance().getGmCommands();
|
||||
commands = ce.getGmCommands();
|
||||
}
|
||||
|
||||
function start() {
|
||||
|
||||
@@ -21,37 +21,6 @@
|
||||
Default Maple TV
|
||||
*/
|
||||
|
||||
var status;
|
||||
|
||||
function start() {
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (YamlConfig.config.server.USE_ENABLE_CUSTOM_NPC_SCRIPT) {
|
||||
cm.dispose();
|
||||
cm.openNpc(9201088, "scroll_generator");
|
||||
return;
|
||||
}
|
||||
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == -1) {
|
||||
cm.dispose();
|
||||
} else {
|
||||
if (mode == 0 && type > 0) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
status--;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
// do nothing
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
cm.dispose();
|
||||
}
|
||||
@@ -1,452 +0,0 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
/* NPC: MapleTV / Larry
|
||||
|
||||
Exchanger NPC:
|
||||
* Scroll generator
|
||||
*
|
||||
* @author Ronan Lana
|
||||
*/
|
||||
|
||||
var status;
|
||||
|
||||
var jobWeaponRestricted = [[[2043000, 2043100, 2044000, 2044100, 2043200, 2044200]], [[2043000, 2043100, 2044000, 2044100], [2043000, 2043200, 2044000, 2044200], [2044300, 2044400]], [[2043700, 2043800], [2043700, 2043800], [2043700, 2043800]], [[2044500], [2044600]], [[2044700], [2043300]], [[2044800], [2044900]]];
|
||||
var aranWeaponRestricted = [jobWeaponRestricted[1][2][1]];
|
||||
|
||||
var tier1Scrolls = [];
|
||||
var tier2Scrolls = [2040000, 2040400, 2040500, 2040600, 2040700, 2040800, 2040900];
|
||||
var tier3Scrolls = [2048000, 2049200, 2041000, 2041100, 2041300, 2040100, 2040200, 2040300];
|
||||
|
||||
var typeTierScrolls = [["PAD", "MAD"], ["STR", "DEX", "INT", "LUK", "ACC", "EVA", "Speed", "Jump"], ["PDD", "MDD", "MHP", "MMP"]];
|
||||
|
||||
var sgItems = [4003004, 4003005, 4001006, 4006000, 4006001, 4030012];
|
||||
var sgToBucket = [100, 50, 37.5, 37.5, 37.5, 200];
|
||||
var mesoToBucket = 2800000;
|
||||
|
||||
var sgAppliedItems = [0, 0, 0, 0, 0, 0];
|
||||
var sgAppliedMeso = 0;
|
||||
|
||||
var sgBuckets = 0.0;
|
||||
var sgBookBuckets = 0.0;
|
||||
var sgItemBuckets = 0.0;
|
||||
|
||||
function start() {
|
||||
status = -1;
|
||||
action(1, 0, 0);
|
||||
}
|
||||
|
||||
function action(mode, type, selection) {
|
||||
if (mode == -1) {
|
||||
cm.dispose();
|
||||
} else {
|
||||
if (mode == 0 && type > 0) {
|
||||
cm.dispose();
|
||||
return;
|
||||
}
|
||||
if (mode == 1) {
|
||||
status++;
|
||||
} else {
|
||||
status--;
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
cm.sendNext("This is the MapleTV Scroll Generator broadcast. Place your supplies or mesos earned throughout your adventure to redeem a prize! You can place #bany amount of supplies#k, however take note that placing #rdifferent supplies#k with #rbigger shots of any of them#k will improve the reward possibilities!");
|
||||
} else if (status == 1) {
|
||||
var sendStr;
|
||||
|
||||
//print("Book: " + sgBookBuckets + " Item: " + sgItemBuckets);
|
||||
|
||||
if (sgItemBuckets > 0.0) {
|
||||
sendStr = "With the items you have currently placed, you have #r" + sgBuckets + "#k buckets (#r" + (sgItemBuckets < 1.0 ? sgItemBuckets.toFixed(2) : Math.floor(sgItemBuckets)) + "#k supply buckets) for claiming a prize. Place supplies:";
|
||||
} else {
|
||||
sendStr = "You have placed no supplies yet. Place supplies:";
|
||||
}
|
||||
|
||||
var listStr = "";
|
||||
var i;
|
||||
for (i = 0; i < sgItems.length; i++) {
|
||||
listStr += "#b#L" + i + "##t" + sgItems[i] + "##k";
|
||||
if (sgAppliedItems[i] > 0) {
|
||||
listStr += " - " + sgAppliedItems[i];
|
||||
}
|
||||
listStr += "#l\r\n";
|
||||
}
|
||||
|
||||
listStr += "#b#L" + i + "#Mesos#k";
|
||||
if (sgAppliedMeso > 0) {
|
||||
listStr += " - " + sgAppliedMeso;
|
||||
}
|
||||
listStr += "#l\r\n";
|
||||
|
||||
cm.sendSimple(sendStr + "\r\n\r\n" + listStr + "#r#L" + (sgItems.length + 2) + "#Retrieve a prize!#l#k\r\n");
|
||||
} else if (status == 2) {
|
||||
if (selection == (sgItems.length + 2)) {
|
||||
if (sgItemBuckets < 1.0) {
|
||||
cm.sendPrev("You have set not enough supplies. Insert at least one bucket of #bsupplies#k to claim a prize.");
|
||||
} else {
|
||||
generateRandomScroll();
|
||||
cm.dispose();
|
||||
}
|
||||
} else {
|
||||
var tickSel;
|
||||
if (selection < sgItems.length) {
|
||||
tickSel = "of #b#t" + sgItems[selection] + "##k";
|
||||
curItemQty = cm.getItemQuantity(sgItems[selection]);
|
||||
} else {
|
||||
tickSel = "#bmesos#k";
|
||||
curItemQty = cm.getMeso();
|
||||
}
|
||||
|
||||
curItemSel = selection;
|
||||
if (curItemQty > 0) {
|
||||
cm.sendGetText("How many " + tickSel + " do you want to provide? (#r" + curItemQty + "#k available)#k");
|
||||
} else {
|
||||
cm.sendPrev("You have got #rnone#k " + tickSel + " to provide for Scroll Generation. Click '#rBack#k' to return to the main interface.");
|
||||
}
|
||||
}
|
||||
} else if (status == 3) {
|
||||
var text = cm.getText();
|
||||
|
||||
try {
|
||||
var placedQty = parseInt(text);
|
||||
if (isNaN(placedQty) || placedQty < 0) {
|
||||
throw true;
|
||||
}
|
||||
|
||||
if (placedQty > curItemQty) {
|
||||
cm.sendPrev("You cannot insert the given amount of #r" + (curItemSel < sgItems.length ? "#t" + sgItems[curItemSel] + "#" : "mesos") + "#k (#r" + curItemQty + "#k available). Click '#rBack#k' to return to the main interface.");
|
||||
} else {
|
||||
if (curItemSel < sgItems.length) {
|
||||
sgApplyItem(curItemSel, placedQty);
|
||||
} else {
|
||||
sgApplyMeso(placedQty);
|
||||
}
|
||||
|
||||
cm.sendPrev("Operation succeeded. Click '#rBack#k' to return to the main interface.");
|
||||
}
|
||||
} catch (err) {
|
||||
cm.sendPrev("You must enter a positive number of supplies to insert. Click '#rBack#k' to return to the main interface.");
|
||||
}
|
||||
|
||||
status = 2;
|
||||
} else {
|
||||
cm.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getJobTierScrolls() {
|
||||
var scrolls = [];
|
||||
|
||||
var job = cm.getPlayer().getJob();
|
||||
var jobScrolls = jobWeaponRestricted[Math.floor(cm.getPlayer().getJobStyle().getId() / 100)];
|
||||
|
||||
const GameConstants = Java.type('constants.game.GameConstants');
|
||||
var jobBranch = GameConstants.getJobBranch(job);
|
||||
if (jobBranch >= 2) {
|
||||
Array.prototype.push.apply(scrolls, jobScrolls[Math.floor((job.getId() / 10) % 10) - 1]);
|
||||
} else {
|
||||
for (var i = 0; i < jobScrolls.length; i++) {
|
||||
Array.prototype.push.apply(scrolls, jobScrolls[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return scrolls;
|
||||
}
|
||||
|
||||
function getScrollTypePool(rewardTier) {
|
||||
var scrolls = [];
|
||||
switch (rewardTier) {
|
||||
case 1:
|
||||
if (cm.getPlayer().isAran()) {
|
||||
Array.prototype.push.apply(scrolls, aranWeaponRestricted);
|
||||
} else {
|
||||
Array.prototype.push.apply(scrolls, getJobTierScrolls());
|
||||
}
|
||||
|
||||
Array.prototype.push.apply(scrolls, tier1Scrolls);
|
||||
break;
|
||||
case 2:
|
||||
Array.prototype.push.apply(scrolls, tier2Scrolls);
|
||||
break;
|
||||
default:
|
||||
Array.prototype.push.apply(scrolls, tier3Scrolls);
|
||||
}
|
||||
|
||||
return scrolls;
|
||||
}
|
||||
|
||||
function getScrollTier(scrollStats) {
|
||||
for (var i = 0; i < typeTierScrolls.length; i++) {
|
||||
for (var j = 0; j < typeTierScrolls[i].length; j++) {
|
||||
if (scrollStats.get(typeTierScrolls[i][j]) > 0) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
function getScrollSuccessTier(scrollStats) {
|
||||
var prop = scrollStats.get("success");
|
||||
|
||||
const YamlConfig = Java.type('config.YamlConfig');
|
||||
if (prop > 90) {
|
||||
return 3;
|
||||
} else if (prop < 50) {
|
||||
return YamlConfig.config.server.SCROLL_CHANCE_ROLLS > 2 ? 2 : 1;
|
||||
} else {
|
||||
return YamlConfig.config.server.SCROLL_CHANCE_ROLLS > 2 ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
function getAvailableScrollsPool(baseScrolls, rewardTier, successTier) {
|
||||
var scrolls = [];
|
||||
const ItemInformationProvider = Java.type('server.ItemInformationProvider');
|
||||
var ii = ItemInformationProvider.getInstance();
|
||||
|
||||
for (var i = 0; i < baseScrolls.length; i++) {
|
||||
for (var j = 0; j < 100; j++) {
|
||||
var scrollid = baseScrolls[i] + j;
|
||||
var scrollStats = ii.getEquipStats(scrollid);
|
||||
if (scrollStats != null && ii.getScrollReqs(scrollid).isEmpty()) {
|
||||
var scrollTier = getScrollTier(scrollStats);
|
||||
if (scrollTier == rewardTier && successTier == getScrollSuccessTier(scrollStats)) {
|
||||
scrolls.push(scrollid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return scrolls;
|
||||
}
|
||||
|
||||
// passive tier buckets...
|
||||
|
||||
function getLevelTier(level) {
|
||||
return Math.floor((level - 1) / 15) + 1;
|
||||
}
|
||||
|
||||
function getPlayerCardTierPower() {
|
||||
var cardset = cm.getPlayer().getMonsterBook().getCardSet();
|
||||
var countTier = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
for (var iterator = cardset.iterator(); iterator.hasNext();) {
|
||||
var ce = iterator.next();
|
||||
|
||||
var cardid = ce.getKey();
|
||||
var ceTier = Math.floor(cardid / 1000) % 10;
|
||||
countTier[ceTier] += ce.getValue();
|
||||
|
||||
if (ceTier >= 8) { // is special card
|
||||
const LifeFactory = Java.type('server.life.LifeFactory');
|
||||
const ItemInformationProvider = Java.type('server.ItemInformationProvider');
|
||||
var mobLevel = LifeFactory.getMonsterLevel(ItemInformationProvider.getInstance().getCardMobId(cardid));
|
||||
var mobTier = getLevelTier(mobLevel) - 1;
|
||||
|
||||
countTier[mobTier] += (ce.getValue() * 1.2);
|
||||
}
|
||||
}
|
||||
|
||||
return countTier;
|
||||
}
|
||||
|
||||
function calculateMobBookTierBuckets(tierSize, playerCards, tier) {
|
||||
if (tier < 1) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
tier--; // started at 1
|
||||
var tierHitRate = playerCards[tier] / (tierSize[tier] * 5);
|
||||
if (tierHitRate > 0.5) {
|
||||
tierHitRate = 0.5;
|
||||
}
|
||||
|
||||
return tierHitRate * 4;
|
||||
}
|
||||
|
||||
function calculateMobBookBuckets() {
|
||||
var book = cm.getPlayer().getMonsterBook();
|
||||
var bookLevelMult = 0.9 + (0.1 * book.getBookLevel());
|
||||
|
||||
var playerLevelTier = getLevelTier(cm.getPlayer().getLevel());
|
||||
if (playerLevelTier > 8) {
|
||||
playerLevelTier = 8;
|
||||
}
|
||||
|
||||
const MonsterBook = Java.type('client.MonsterBook');
|
||||
var tierSize = MonsterBook.getCardTierSize();
|
||||
var playerCards = getPlayerCardTierPower();
|
||||
|
||||
var prevBuckets = calculateMobBookTierBuckets(tierSize, playerCards, playerLevelTier - 1);
|
||||
var currBuckets = calculateMobBookTierBuckets(tierSize, playerCards, playerLevelTier);
|
||||
|
||||
return (prevBuckets + currBuckets) * bookLevelMult;
|
||||
}
|
||||
|
||||
function recalcBuckets() {
|
||||
sgBookBuckets = calculateMobBookBuckets();
|
||||
sgItemBuckets = calculateSuppliesBuckets();
|
||||
|
||||
var buckets = sgBookBuckets + sgItemBuckets;
|
||||
if (buckets > 6.0) {
|
||||
sgBuckets = 6;
|
||||
} else {
|
||||
sgBuckets = Math.floor(buckets);
|
||||
}
|
||||
}
|
||||
|
||||
// variable buckets...
|
||||
|
||||
function sgApplyItem(idx, amount) {
|
||||
if (sgAppliedItems[idx] != amount) {
|
||||
sgAppliedItems[idx] = amount;
|
||||
recalcBuckets();
|
||||
}
|
||||
}
|
||||
|
||||
function sgApplyMeso(amount) {
|
||||
if (sgAppliedMeso != amount) {
|
||||
sgAppliedMeso = amount;
|
||||
recalcBuckets();
|
||||
}
|
||||
}
|
||||
|
||||
function calculateSuppliesBuckets() {
|
||||
var suppliesHitRate = 0.0;
|
||||
for (var i = 0; i < sgItems.length; i++) {
|
||||
suppliesHitRate += sgAppliedItems[i] / sgToBucket[i];
|
||||
}
|
||||
suppliesHitRate *= 2;
|
||||
|
||||
suppliesHitRate += (sgAppliedMeso / mesoToBucket);
|
||||
return suppliesHitRate;
|
||||
}
|
||||
|
||||
function calculateScrollTiers() {
|
||||
var buckets = sgBuckets;
|
||||
var tiers = [0, 0, 0];
|
||||
while (buckets > 0) {
|
||||
var pool = [];
|
||||
for (var i = 0; i < tiers.length; i++) {
|
||||
if (tiers[i] < 2) {
|
||||
pool.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
var rnd = pool[Math.floor(Math.random() * pool.length)];
|
||||
|
||||
tiers[rnd]++;
|
||||
buckets--;
|
||||
}
|
||||
|
||||
// normalize tiers
|
||||
for (var i = 0; i < tiers.length; i++) {
|
||||
tiers[i] = 3 - tiers[i];
|
||||
}
|
||||
|
||||
return tiers;
|
||||
}
|
||||
|
||||
function getRandomScrollFromTiers(tiers) {
|
||||
var typeTier = tiers[0], subtypeTier = tiers[1], successTier = tiers[2];
|
||||
var scrollTypePool = getScrollTypePool(typeTier);
|
||||
var scrollPool = getAvailableScrollsPool(scrollTypePool, subtypeTier, successTier);
|
||||
|
||||
if (scrollPool.length > 0) {
|
||||
return scrollPool[Math.floor(Math.random() * scrollPool.length)];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
function getRandomScrollFromRightPermutations(tiers) {
|
||||
for (var i = 2; i >= 0; i--) {
|
||||
for (var j = i - 1; j >= 0; j--) {
|
||||
if (tiers[i] >= 3) {
|
||||
break;
|
||||
} else if (tiers[j] > 1) {
|
||||
tiers[i]++;
|
||||
tiers[j]--;
|
||||
|
||||
var itemid = getRandomScrollFromTiers(tiers);
|
||||
if (itemid != -1) {
|
||||
return itemid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function getRandomScroll(tiers) {
|
||||
var itemid = getRandomScrollFromTiers(tiers);
|
||||
if (itemid == -1) {
|
||||
// worst case shift-right permutations...
|
||||
itemid = getRandomScrollFromRightPermutations(tiers);
|
||||
}
|
||||
|
||||
return itemid;
|
||||
}
|
||||
|
||||
function performExchange(sgItemid, sgCount) {
|
||||
if (cm.getMeso() < sgAppliedMeso) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < sgItems.length; i++) {
|
||||
var itemid = sgItems[i];
|
||||
var count = sgAppliedItems[i];
|
||||
if (count > 0 && !cm.haveItem(itemid, count)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cm.gainMeso(-sgAppliedMeso);
|
||||
|
||||
for (var i = 0; i < sgItems.length; i++) {
|
||||
var itemid = sgItems[i];
|
||||
var count = sgAppliedItems[i];
|
||||
cm.gainItem(itemid, -count);
|
||||
}
|
||||
|
||||
cm.gainItem(sgItemid, sgCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
function generateRandomScroll() {
|
||||
const InventoryType = Java.type('client.inventory.InventoryType');
|
||||
if (cm.getPlayer().getInventory(InventoryType.USE).getNumFreeSlot() >= 1) {
|
||||
var itemid = getRandomScroll(calculateScrollTiers());
|
||||
if (itemid != -1) {
|
||||
if (performExchange(itemid, 1)) {
|
||||
cm.sendNext("Transaction accepted! You have received a #r#t" + itemid + "##k.");
|
||||
} else {
|
||||
cm.sendOk("Oh, it looks like some items are missing... Please double-check provided items in your inventory before trying to exchange.");
|
||||
}
|
||||
} else {
|
||||
cm.sendOk("Sorry for the inconvenience, but it seems there are no scrolls on store right now... Try again later.");
|
||||
}
|
||||
} else {
|
||||
cm.sendOk("Please look out for a slot available on your USE inventory before trying for a scroll.");
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ public abstract class AbstractCharacterObject extends AbstractAnimatedMapObject
|
||||
protected MapleMap map;
|
||||
protected int str, dex, luk, int_, hp, maxhp, mp, maxmp;
|
||||
protected int hpMpApUsed, remainingAp;
|
||||
protected int[] remainingSp = new int[10];
|
||||
protected int[] remainingSp = new int[10]; // TODO: change to a simple int. Evan is not in v83, so why support it?
|
||||
protected transient int clientmaxhp, clientmaxmp, localmaxhp = 50, localmaxmp = 5;
|
||||
protected float transienthp = Float.NEGATIVE_INFINITY, transientmp = Float.NEGATIVE_INFINITY;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
package client;
|
||||
|
||||
import model.CharacterIdentity;
|
||||
import net.packet.Packet;
|
||||
import net.server.PlayerStorage;
|
||||
import tools.DatabaseConnection;
|
||||
@@ -48,7 +49,7 @@ public class BuddyList {
|
||||
|
||||
private final Map<Integer, BuddylistEntry> buddies = new LinkedHashMap<>();
|
||||
private int capacity;
|
||||
private final Deque<CharacterNameAndId> pendingRequests = new LinkedList<>();
|
||||
private final Deque<CharacterIdentity> pendingRequests = new LinkedList<>();
|
||||
|
||||
public BuddyList(int capacity) {
|
||||
this.capacity = capacity;
|
||||
@@ -150,7 +151,7 @@ public class BuddyList {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
if (rs.getInt("pending") == 1) {
|
||||
pendingRequests.push(new CharacterNameAndId(rs.getInt("buddyid"), rs.getString("buddyname")));
|
||||
pendingRequests.push(new CharacterIdentity(rs.getString("buddyname"), rs.getInt("buddyid")));
|
||||
} else {
|
||||
put(new BuddylistEntry(rs.getString("buddyname"), rs.getString("group"), rs.getInt("buddyid"), (byte) -1, true));
|
||||
}
|
||||
@@ -167,7 +168,7 @@ public class BuddyList {
|
||||
}
|
||||
}
|
||||
|
||||
public CharacterNameAndId pollPendingRequest() {
|
||||
public CharacterIdentity pollPendingRequest() {
|
||||
return pendingRequests.pollLast();
|
||||
}
|
||||
|
||||
@@ -176,7 +177,7 @@ public class BuddyList {
|
||||
if (pendingRequests.isEmpty()) {
|
||||
c.sendPacket(PacketCreator.requestBuddylistAdd(cidFrom, c.getPlayer().getId(), nameFrom));
|
||||
} else {
|
||||
pendingRequests.push(new CharacterNameAndId(cidFrom, nameFrom));
|
||||
pendingRequests.push(new CharacterIdentity(nameFrom, cidFrom));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
66
src/main/java/client/CharacterStats.java
Normal file
66
src/main/java/client/CharacterStats.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package client;
|
||||
|
||||
import lombok.Builder;
|
||||
|
||||
@Builder
|
||||
public record CharacterStats(
|
||||
int account,
|
||||
int world,
|
||||
String name,
|
||||
int id,
|
||||
int level,
|
||||
int fame,
|
||||
int str,
|
||||
int dex,
|
||||
int luk,
|
||||
int int_,
|
||||
int exp,
|
||||
int gachaExp,
|
||||
int hp,
|
||||
int mp,
|
||||
int maxHp,
|
||||
int maxMp,
|
||||
int sp,
|
||||
int ap,
|
||||
int gmLevel,
|
||||
int skin,
|
||||
int gender,
|
||||
int job,
|
||||
int hair,
|
||||
int face,
|
||||
int mapId,
|
||||
int meso,
|
||||
int hpMpApUsed,
|
||||
int spawnPortal,
|
||||
Integer party,
|
||||
int buddyCapacity,
|
||||
Integer messenger,
|
||||
Integer messengerPosition,
|
||||
Integer mountLevel,
|
||||
Integer mountExp,
|
||||
Integer mountTiredness,
|
||||
int equipSlots,
|
||||
int useSlots,
|
||||
int setupSlots,
|
||||
int etcSlots,
|
||||
Integer monsterBookCover,
|
||||
Integer dojoVanquisherStage,
|
||||
int dojoPoints,
|
||||
Integer dojoStage,
|
||||
boolean dojoTutorialComplete,
|
||||
int dojoVanquisherKills,
|
||||
int matchCardWins,
|
||||
int matchCardLosses,
|
||||
int matchCardTies,
|
||||
int omokWins,
|
||||
int omokLosses,
|
||||
int omokTies,
|
||||
String dataString,
|
||||
Long jailExpiration,
|
||||
Integer partnerId,
|
||||
Integer marriageItemId,
|
||||
Long lastExpGainTime,
|
||||
int ariantPoints,
|
||||
boolean canRecvPartySearchInvite
|
||||
) {
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
10
src/main/java/client/Gender.java
Normal file
10
src/main/java/client/Gender.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package client;
|
||||
|
||||
/**
|
||||
* @author Ponk
|
||||
*/
|
||||
public class Gender {
|
||||
public static final byte MALE = 0;
|
||||
public static final byte FEMALE = 1;
|
||||
public static final byte NOT_SET = 10;
|
||||
}
|
||||
29
src/main/java/client/LoginState.java
Normal file
29
src/main/java/client/LoginState.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package client;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Ponk
|
||||
*/
|
||||
public enum LoginState {
|
||||
LOGGED_OUT(0),
|
||||
SERVER_TRANSITION(1),
|
||||
LOGGED_IN(2);
|
||||
|
||||
private final byte value;
|
||||
|
||||
LoginState(int value) {
|
||||
this.value = (byte) value;
|
||||
}
|
||||
|
||||
public byte getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Optional<LoginState> fromValue(int value) {
|
||||
return Arrays.stream(values())
|
||||
.filter(v -> v.getValue() == value)
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
@@ -1,225 +1,110 @@
|
||||
/*
|
||||
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 client;
|
||||
|
||||
import tools.DatabaseConnection;
|
||||
import database.monsterbook.MonsterCard;
|
||||
import net.jcip.annotations.ThreadSafe;
|
||||
import tools.PacketCreator;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class MonsterBook {
|
||||
private int specialCard = 0;
|
||||
private int normalCard = 0;
|
||||
private int bookLevel = 1;
|
||||
private final Map<Integer, Integer> cards = new LinkedHashMap<>();
|
||||
private final Lock lock = new ReentrantLock();
|
||||
// TODO: add tests
|
||||
@ThreadSafe
|
||||
public class MonsterBook {
|
||||
private final Map<Integer, MonsterCard> cards;
|
||||
private int bookLevel;
|
||||
|
||||
public Set<Entry<Integer, Integer>> getCardSet() {
|
||||
lock.lock();
|
||||
try {
|
||||
return new HashSet<>(cards.entrySet());
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
public MonsterBook(List<MonsterCard> monsterCards) {
|
||||
this.cards = monsterCards.stream()
|
||||
.collect(Collectors.toMap(MonsterCard::cardId, Function.identity()));
|
||||
}
|
||||
|
||||
public void addCard(final Client c, final int cardid) {
|
||||
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), PacketCreator.showForeignCardEffect(c.getPlayer().getId()), false);
|
||||
public synchronized List<MonsterCard> getCards() {
|
||||
return new ArrayList<>(cards.values());
|
||||
}
|
||||
|
||||
Integer qty;
|
||||
lock.lock();
|
||||
try {
|
||||
qty = cards.get(cardid);
|
||||
|
||||
if (qty != null) {
|
||||
if (qty < 5) {
|
||||
cards.put(cardid, qty + 1);
|
||||
}
|
||||
} else {
|
||||
cards.put(cardid, 1);
|
||||
qty = 0;
|
||||
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
public synchronized void addCard(int cardId, Client client) {
|
||||
var monsterCard = cards.get(cardId);
|
||||
if (monsterCard != null && monsterCard.isMaxLevel()) {
|
||||
client.sendPacket(PacketCreator.addMonsterCardAlreadyFull());
|
||||
return;
|
||||
}
|
||||
|
||||
if (qty < 5) {
|
||||
if (qty == 0) { // leveling system only accounts unique cards
|
||||
calculateLevel();
|
||||
}
|
||||
|
||||
c.sendPacket(PacketCreator.addCard(false, cardid, qty + 1));
|
||||
c.sendPacket(PacketCreator.showGainCard());
|
||||
boolean isNewCard = monsterCard == null;
|
||||
final MonsterCard card;
|
||||
if (isNewCard) {
|
||||
card = new MonsterCard(cardId, (byte) 1);
|
||||
cards.put(cardId, card);
|
||||
calculateAndSetLevel();
|
||||
} else {
|
||||
c.sendPacket(PacketCreator.addCard(true, cardid, 5));
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateLevel() {
|
||||
lock.lock();
|
||||
try {
|
||||
int collectionExp = (normalCard + specialCard);
|
||||
|
||||
int level = 0, expToNextlevel = 1;
|
||||
do {
|
||||
level++;
|
||||
expToNextlevel += level * 10;
|
||||
} while (collectionExp >= expToNextlevel);
|
||||
|
||||
bookLevel = level; // thanks IxianMace for noticing book level differing between book UI and character info UI
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getBookLevel() {
|
||||
lock.lock();
|
||||
try {
|
||||
return bookLevel;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getCards() {
|
||||
lock.lock();
|
||||
try {
|
||||
return Collections.unmodifiableMap(cards);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalCards() {
|
||||
lock.lock();
|
||||
try {
|
||||
return specialCard + normalCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getNormalCard() {
|
||||
lock.lock();
|
||||
try {
|
||||
return normalCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public int getSpecialCard() {
|
||||
lock.lock();
|
||||
try {
|
||||
return specialCard;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadCards(final int charid) throws SQLException {
|
||||
lock.lock();
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT cardid, level FROM monsterbook WHERE charid = ? ORDER BY cardid ASC")) {
|
||||
ps.setInt(1, charid);
|
||||
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
int cardid;
|
||||
int level;
|
||||
while (rs.next()) {
|
||||
cardid = rs.getInt("cardid");
|
||||
level = rs.getInt("level");
|
||||
if (cardid / 1000 >= 2388) {
|
||||
specialCard++;
|
||||
} else {
|
||||
normalCard++;
|
||||
}
|
||||
cards.put(cardid, level);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
card = new MonsterCard(cardId, (byte) (monsterCard.level() + 1));
|
||||
cards.put(cardId, card);
|
||||
}
|
||||
|
||||
calculateLevel();
|
||||
var chr = client.getPlayer();
|
||||
chr.sendPacket(PacketCreator.addMonsterCard(card));
|
||||
chr.sendPacket(PacketCreator.showMonsterCardEffect());
|
||||
chr.getMap().broadcastMessage(chr, PacketCreator.showForeignMonsterCardEffect(chr.getId()), false);
|
||||
}
|
||||
|
||||
public void saveCards(Connection con, int chrId) throws SQLException {
|
||||
private synchronized void calculateAndSetLevel() {
|
||||
int collectionExp = getTotalCards();
|
||||
|
||||
int level = 0;
|
||||
int expToNextLevel = 1;
|
||||
do {
|
||||
level++;
|
||||
expToNextLevel += level * 10;
|
||||
} while (collectionExp >= expToNextLevel);
|
||||
|
||||
this.bookLevel = level;
|
||||
}
|
||||
|
||||
public synchronized int getBookLevel() {
|
||||
return bookLevel;
|
||||
}
|
||||
|
||||
public synchronized int getNormalCards() {
|
||||
return (int) cards.values().stream()
|
||||
.filter(Predicate.not(MonsterCard::isSpecial))
|
||||
.count();
|
||||
}
|
||||
|
||||
public synchronized int getSpecialCards() {
|
||||
return (int) cards.values().stream()
|
||||
.filter(MonsterCard::isSpecial)
|
||||
.count();
|
||||
}
|
||||
|
||||
public synchronized int getTotalCards() {
|
||||
return cards.size();
|
||||
}
|
||||
|
||||
public synchronized void saveCards(Connection con, int chrId) throws SQLException {
|
||||
final String query = """
|
||||
INSERT INTO monsterbook (charid, cardid, level)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE level = ?;
|
||||
""";
|
||||
try (final PreparedStatement ps = con.prepareStatement(query)) {
|
||||
for (Map.Entry<Integer, Integer> cardAndLevel : cards.entrySet()) {
|
||||
final int card = cardAndLevel.getKey();
|
||||
final int level = cardAndLevel.getValue();
|
||||
for (MonsterCard card : cards.values()) {
|
||||
// insert
|
||||
ps.setInt(1, chrId);
|
||||
ps.setInt(2, card);
|
||||
ps.setInt(3, level);
|
||||
ps.setInt(2, card.cardId());
|
||||
ps.setInt(3, card.level());
|
||||
|
||||
// update
|
||||
ps.setInt(4, level);
|
||||
ps.setInt(4, card.level());
|
||||
|
||||
ps.addBatch();
|
||||
}
|
||||
ps.executeBatch();
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] getCardTierSize() {
|
||||
try (Connection con = DatabaseConnection.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) FROM monstercarddata GROUP BY floor(cardid / 1000);", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet rs = ps.executeQuery()) {
|
||||
rs.last();
|
||||
int[] tierSizes = new int[rs.getRow()];
|
||||
rs.beforeFirst();
|
||||
|
||||
while (rs.next()) {
|
||||
tierSizes[rs.getRow() - 1] = rs.getInt(1);
|
||||
}
|
||||
|
||||
return tierSizes;
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,14 +22,15 @@
|
||||
package client;
|
||||
|
||||
public enum SkinColor {
|
||||
NORMAL(0),
|
||||
DARK(1),
|
||||
BLACK(2),
|
||||
LIGHT(0),
|
||||
TANNED(1),
|
||||
DARK(2),
|
||||
PALE(3),
|
||||
BLUE(4),
|
||||
GREEN(5),
|
||||
WHITE(9),
|
||||
PINK(10);
|
||||
PINK(10),
|
||||
BROWN(11);
|
||||
|
||||
final int id;
|
||||
|
||||
|
||||
@@ -88,10 +88,6 @@ public enum AutobanFactory {
|
||||
return expiretime;
|
||||
}
|
||||
|
||||
public void addPoint(AutobanManager ban, String reason) {
|
||||
ban.addPoint(this, reason);
|
||||
}
|
||||
|
||||
public void alert(Character chr, String reason) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
if (chr != null && isIgnored(chr.getId())) {
|
||||
@@ -105,13 +101,6 @@ public enum AutobanFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public void autoban(Character chr, String value) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
chr.autoban("Autobanned for (" + this.name() + ": " + value + ")");
|
||||
//chr.sendPolice("You will be disconnected for (" + this.name() + ": " + value + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle ignored status for a character id.
|
||||
* An ignored character will not trigger GM alerts.
|
||||
|
||||
@@ -7,6 +7,7 @@ package client.autoban;
|
||||
|
||||
import client.Character;
|
||||
import config.YamlConfig;
|
||||
import net.netty.GameViolationException;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -35,35 +36,27 @@ public class AutobanManager {
|
||||
this.chr = chr;
|
||||
}
|
||||
|
||||
public void addPoint(AutobanFactory fac, String reason) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
if (chr.isGM() || chr.isBanned()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lastTime.containsKey(fac)) {
|
||||
if (lastTime.get(fac) < (Server.getInstance().getCurrentTime() - fac.getExpire())) {
|
||||
points.put(fac, points.get(fac) / 2); //So the points are not completely gone.
|
||||
}
|
||||
}
|
||||
if (fac.getExpire() != -1) {
|
||||
lastTime.put(fac, Server.getInstance().getCurrentTime());
|
||||
}
|
||||
|
||||
if (points.containsKey(fac)) {
|
||||
points.put(fac, points.get(fac) + 1);
|
||||
} else {
|
||||
points.put(fac, 1);
|
||||
}
|
||||
|
||||
if (points.get(fac) >= fac.getMaximum()) {
|
||||
chr.autoban(reason);
|
||||
/**
|
||||
* @return true if the added point should result in an autoban
|
||||
*/
|
||||
public boolean addPoint(AutobanFactory fac) {
|
||||
if (lastTime.containsKey(fac)) {
|
||||
if (lastTime.get(fac) < (Server.getInstance().getCurrentTime() - fac.getExpire())) {
|
||||
points.put(fac, points.get(fac) / 2); //So the points are not completely gone.
|
||||
}
|
||||
}
|
||||
if (YamlConfig.config.server.USE_AUTOBAN_LOG) {
|
||||
// Lets log every single point too.
|
||||
log.info("Autoban - chr {} caused {} {}", Character.makeMapleReadable(chr.getName()), fac.name(), reason);
|
||||
|
||||
if (fac.getExpire() != -1) {
|
||||
lastTime.put(fac, Server.getInstance().getCurrentTime());
|
||||
}
|
||||
|
||||
if (points.containsKey(fac)) {
|
||||
points.put(fac, points.get(fac) + 1);
|
||||
} else {
|
||||
points.put(fac, 1);
|
||||
}
|
||||
|
||||
return points.get(fac) >= fac.getMaximum();
|
||||
}
|
||||
|
||||
public void addMiss() {
|
||||
@@ -118,11 +111,10 @@ public class AutobanManager {
|
||||
if (this.timestamp[type] == time) {
|
||||
this.timestampcounter[type]++;
|
||||
if (this.timestampcounter[type] >= times) {
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
chr.getClient().disconnect(false, false);
|
||||
}
|
||||
|
||||
log.info("Autoban - Chr {} was caught spamming TYPE {} and has been disconnected", chr, type);
|
||||
if (YamlConfig.config.server.USE_AUTOBAN) {
|
||||
throw new GameViolationException("Auto ban");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.timestamp[type] = time;
|
||||
|
||||
@@ -30,7 +30,7 @@ public abstract class Command {
|
||||
protected int rank;
|
||||
protected String description;
|
||||
|
||||
public abstract void execute(Client client, String[] params);
|
||||
public abstract void execute(Client client, String[] params, CommandContext ctx);
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
|
||||
19
src/main/java/client/command/CommandContext.java
Normal file
19
src/main/java/client/command/CommandContext.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package client.command;
|
||||
|
||||
import database.character.CharacterSaver;
|
||||
import database.drop.DropProvider;
|
||||
import server.shop.ShopFactory;
|
||||
import service.BanService;
|
||||
import service.TransitionService;
|
||||
|
||||
/**
|
||||
* @author Ponk
|
||||
*/
|
||||
public record CommandContext(CommandsExecutor commandsExecutor, DropProvider dropProvider, ShopFactory shopFactory,
|
||||
CharacterSaver characterSaver, TransitionService transitionService, BanService banService
|
||||
) {
|
||||
|
||||
public CommandContext with(CommandsExecutor ce) {
|
||||
return new CommandContext(ce, dropProvider, shopFactory, characterSaver, transitionService, banService);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
package client.command;
|
||||
|
||||
import client.Client;
|
||||
import client.command.commands.gm0.ChangeLanguageCommand;
|
||||
import client.command.commands.gm0.DisposeCommand;
|
||||
import client.command.commands.gm0.DropLimitCommand;
|
||||
import client.command.commands.gm0.EnableAuthCommand;
|
||||
@@ -38,7 +37,6 @@ import client.command.commands.gm0.MapOwnerClaimCommand;
|
||||
import client.command.commands.gm0.OnlineCommand;
|
||||
import client.command.commands.gm0.RanksCommand;
|
||||
import client.command.commands.gm0.RatesCommand;
|
||||
import client.command.commands.gm0.ReadPointsCommand;
|
||||
import client.command.commands.gm0.ReportBugCommand;
|
||||
import client.command.commands.gm0.ShowRatesCommand;
|
||||
import client.command.commands.gm0.StaffCommand;
|
||||
@@ -106,8 +104,6 @@ import client.command.commands.gm3.FameCommand;
|
||||
import client.command.commands.gm3.FlyCommand;
|
||||
import client.command.commands.gm3.GiveMesosCommand;
|
||||
import client.command.commands.gm3.GiveNxCommand;
|
||||
import client.command.commands.gm3.GiveRpCommand;
|
||||
import client.command.commands.gm3.GiveVpCommand;
|
||||
import client.command.commands.gm3.HairCommand;
|
||||
import client.command.commands.gm3.HealMapCommand;
|
||||
import client.command.commands.gm3.HealPersonCommand;
|
||||
@@ -189,15 +185,10 @@ import client.command.commands.gm6.EraseAllPNpcsCommand;
|
||||
import client.command.commands.gm6.GetAccCommand;
|
||||
import client.command.commands.gm6.MapPlayersCommand;
|
||||
import client.command.commands.gm6.SaveAllCommand;
|
||||
import client.command.commands.gm6.ServerAddChannelCommand;
|
||||
import client.command.commands.gm6.ServerAddWorldCommand;
|
||||
import client.command.commands.gm6.ServerRemoveChannelCommand;
|
||||
import client.command.commands.gm6.ServerRemoveWorldCommand;
|
||||
import client.command.commands.gm6.SetGmLevelCommand;
|
||||
import client.command.commands.gm6.ShutdownCommand;
|
||||
import client.command.commands.gm6.SpawnAllPNpcsCommand;
|
||||
import client.command.commands.gm6.SupplyRateCouponCommand;
|
||||
import client.command.commands.gm6.WarpWorldCommand;
|
||||
import constants.id.MapId;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -210,16 +201,27 @@ import java.util.List;
|
||||
|
||||
public class CommandsExecutor {
|
||||
private static final Logger log = LoggerFactory.getLogger(CommandsExecutor.class);
|
||||
private static final CommandsExecutor instance = new CommandsExecutor();
|
||||
private static final char USER_HEADING = '@';
|
||||
private static final char GM_HEADING = '!';
|
||||
|
||||
private final HashMap<String, Command> registeredCommands = new HashMap<>();
|
||||
private final List<Pair<List<String>, List<String>>> commandsNameDesc = new ArrayList<>();
|
||||
private final CommandContext commandContext;
|
||||
private Pair<List<String>, List<String>> levelCommandsCursor;
|
||||
|
||||
public static CommandsExecutor getInstance() {
|
||||
return instance;
|
||||
public CommandsExecutor(CommandContext commandContext) {
|
||||
this.commandContext = commandContext.with(this);
|
||||
registerCommands();
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
registerLv0Commands();
|
||||
registerLv1Commands();
|
||||
registerLv2Commands();
|
||||
registerLv3Commands();
|
||||
registerLv4Commands();
|
||||
registerLv5Commands();
|
||||
registerLv6Commands();
|
||||
}
|
||||
|
||||
public static boolean isCommand(Client client, String content) {
|
||||
@@ -230,16 +232,6 @@ public class CommandsExecutor {
|
||||
return heading == USER_HEADING;
|
||||
}
|
||||
|
||||
private CommandsExecutor() {
|
||||
registerLv0Commands();
|
||||
registerLv1Commands();
|
||||
registerLv2Commands();
|
||||
registerLv3Commands();
|
||||
registerLv4Commands();
|
||||
registerLv5Commands();
|
||||
registerLv6Commands();
|
||||
}
|
||||
|
||||
public List<Pair<List<String>, List<String>>> getGmCommands() {
|
||||
return commandsNameDesc;
|
||||
}
|
||||
@@ -287,7 +279,7 @@ public class CommandsExecutor {
|
||||
params = new String[]{};
|
||||
}
|
||||
|
||||
command.execute(client, params);
|
||||
command.execute(client, params, commandContext);
|
||||
log.info("Chr {} used command {}", client.getPlayer().getName(), command.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@@ -347,14 +339,12 @@ public class CommandsExecutor {
|
||||
addCommand("uptime", UptimeCommand.class);
|
||||
addCommand("gacha", GachaCommand.class);
|
||||
addCommand("dispose", DisposeCommand.class);
|
||||
addCommand("changel", ChangeLanguageCommand.class);
|
||||
addCommand("equiplv", EquipLvCommand.class);
|
||||
addCommand("showrates", ShowRatesCommand.class);
|
||||
addCommand("rates", RatesCommand.class);
|
||||
addCommand("online", OnlineCommand.class);
|
||||
addCommand("gm", GmCommand.class);
|
||||
addCommand("reportbug", ReportBugCommand.class);
|
||||
addCommand("points", ReadPointsCommand.class);
|
||||
addCommand("joinevent", JoinEventCommand.class);
|
||||
addCommand("leaveevent", LeaveEventCommand.class);
|
||||
addCommand("ranks", RanksCommand.class);
|
||||
@@ -454,9 +444,7 @@ public class CommandsExecutor {
|
||||
addCommand("togglewhitechat", 3, ChatCommand.class);
|
||||
addCommand("fame", 3, FameCommand.class);
|
||||
addCommand("givenx", 3, GiveNxCommand.class);
|
||||
addCommand("givevp", 3, GiveVpCommand.class);
|
||||
addCommand("givems", 3, GiveMesosCommand.class);
|
||||
addCommand("giverp", 3, GiveRpCommand.class);
|
||||
addCommand("expeds", 3, ExpedsCommand.class);
|
||||
addCommand("kill", 3, KillCommand.class);
|
||||
addCommand("seed", 3, SeedCommand.class);
|
||||
@@ -542,7 +530,6 @@ public class CommandsExecutor {
|
||||
levelCommandsCursor = new Pair<>(new ArrayList<String>(), new ArrayList<String>());
|
||||
|
||||
addCommand("setgmlevel", 6, SetGmLevelCommand.class);
|
||||
addCommand("warpworld", 6, WarpWorldCommand.class);
|
||||
addCommand("saveall", 6, SaveAllCommand.class);
|
||||
addCommand("dcall", 6, DCAllCommand.class);
|
||||
addCommand("mapplayers", 6, MapPlayersCommand.class);
|
||||
@@ -553,10 +540,6 @@ public class CommandsExecutor {
|
||||
addCommand("supplyratecoupon", 6, SupplyRateCouponCommand.class);
|
||||
addCommand("spawnallpnpcs", 6, SpawnAllPNpcsCommand.class);
|
||||
addCommand("eraseallpnpcs", 6, EraseAllPNpcsCommand.class);
|
||||
addCommand("addchannel", 6, ServerAddChannelCommand.class);
|
||||
addCommand("addworld", 6, ServerAddWorldCommand.class);
|
||||
addCommand("removechannel", 6, ServerRemoveChannelCommand.class);
|
||||
addCommand("removeworld", 6, ServerRemoveWorldCommand.class);
|
||||
addCommand("devtest", 6, DevtestCommand.class);
|
||||
|
||||
commandsNameDesc.add(levelCommandsCursor);
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
This file is part of the HeavenMS MapleStory Server, commands OdinMS-based
|
||||
Copyleft (L) 2016 - 2019 RonanLana
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
@Author: Arthur L - Refactored command content into modules
|
||||
*/
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class ChangeLanguageCommand extends Command {
|
||||
{
|
||||
setDescription("Change language settings.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
if (params.length < 1) {
|
||||
c.getPlayer().yellowMessage("Syntax: !changel <0=ptb, 1=esp, 2=eng>");
|
||||
return;
|
||||
}
|
||||
c.setLanguage(Integer.parseInt(params[0]));
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import scripting.npc.NPCScriptManager;
|
||||
import scripting.quest.QuestScriptManager;
|
||||
import tools.PacketCreator;
|
||||
@@ -35,7 +36,7 @@ public class DisposeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
NPCScriptManager.getInstance().dispose(c);
|
||||
QuestScriptManager.getInstance().dispose(c);
|
||||
c.sendPacket(PacketCreator.enableActions());
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class DropLimitCommand extends Command {
|
||||
@@ -33,7 +34,7 @@ public class DropLimitCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
int dropCount = c.getPlayer().getMap().getDroppedItemCount();
|
||||
if (((float) dropCount) / YamlConfig.config.server.ITEM_LIMIT_ON_MAP < 0.75f) {
|
||||
c.getPlayer().showHint("Current drop count: #b" + dropCount + "#k / #e" + YamlConfig.config.server.ITEM_LIMIT_ON_MAP + "#n", 300);
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.coordinator.login.LoginBypassCoordinator;
|
||||
|
||||
public class EnableAuthCommand extends Command {
|
||||
@@ -33,7 +34,7 @@ public class EnableAuthCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
LoginBypassCoordinator.getInstance().unregisterLoginBypassEntry(c.getHwid(), c.getAccID());
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class EquipLvCommand extends Command {
|
||||
{
|
||||
@@ -32,7 +33,7 @@ public class EquipLvCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
c.getPlayer().showAllEquipFeatures();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.gachapon.Gachapon;
|
||||
@@ -35,7 +36,7 @@ public class GachaCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Gachapon.GachaponType gacha = null;
|
||||
String search = c.getPlayer().getLastCommandMessage();
|
||||
String gachaName = "";
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -40,7 +41,7 @@ public class GmCommand extends Command {
|
||||
private static final Logger log = LoggerFactory.getLogger(GmCommand.class);
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
String[] tips = {
|
||||
"Please only use @gm in emergencies or to report somebody.",
|
||||
"To report a bug or make a suggestion, use the forum.",
|
||||
|
||||
@@ -25,15 +25,19 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class HelpCommand extends Command {
|
||||
{
|
||||
setDescription("Show available commands.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
client.getAbstractPlayerInteraction().openNpc(NpcId.STEWARD, "commands");
|
||||
public void execute(Client client, String[] params, CommandContext ctx) {
|
||||
Map<String, Object> bindings = Map.of("ce", ctx.commandsExecutor());
|
||||
client.getAbstractPlayerInteraction().openNpc(NpcId.STEWARD, "commands", bindings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.MapId;
|
||||
import server.events.gm.Event;
|
||||
import server.maps.FieldLimit;
|
||||
@@ -36,7 +37,7 @@ public class JoinEventCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (!FieldLimit.CANNOTMIGRATE.check(player.getMap().getFieldLimit())) {
|
||||
Event event = c.getChannelServer().getEvent();
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class LeaveEventCommand extends Command {
|
||||
{
|
||||
@@ -33,7 +34,7 @@ public class LeaveEventCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int returnMap = player.getSavedLocation("EVENT");
|
||||
if (returnMap != -1) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
import server.maps.MapleMap;
|
||||
|
||||
@@ -35,7 +36,7 @@ public class MapOwnerClaimCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
Character chr = c.getPlayer();
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
import net.server.channel.Channel;
|
||||
|
||||
@@ -35,7 +36,7 @@ public class OnlineCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
for (Channel ch : Server.getInstance().getChannelsFromWorld(player.getWorld())) {
|
||||
player.yellowMessage("Players in Channel " + ch.getId() + ":");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import net.server.Server;
|
||||
import net.server.guild.GuildPackets;
|
||||
@@ -39,7 +40,7 @@ public class RanksCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
List<Pair<String, Integer>> worldRanking = Server.getInstance().getWorldPlayerRanking(player.getWorld());
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class RatesCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class RatesCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
// travel rates not applicable since it's intrinsically a server/environment rate rather than a character rate
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package client.command.commands.gm0;
|
||||
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
|
||||
public class ReadPointsCommand extends Command {
|
||||
{
|
||||
setDescription("Show point total.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
|
||||
Character player = client.getPlayer();
|
||||
if (params.length > 2) {
|
||||
player.yellowMessage("Syntax: @points (rp|vp|all)");
|
||||
return;
|
||||
} else if (params.length == 0) {
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints() + " | "
|
||||
+ "VotePoints: " + player.getClient().getVotePoints());
|
||||
return;
|
||||
}
|
||||
|
||||
switch (params[0]) {
|
||||
case "rp":
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints());
|
||||
break;
|
||||
case "vp":
|
||||
player.yellowMessage("VotePoints: " + player.getClient().getVotePoints());
|
||||
break;
|
||||
default:
|
||||
player.yellowMessage("RewardPoints: " + player.getRewardPoints() + " | "
|
||||
+ "VotePoints: " + player.getClient().getVotePoints());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -39,7 +40,7 @@ public class ReportBugCommand extends Command {
|
||||
private static final Logger log = LoggerFactory.getLogger(ReportBugCommand.class);
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
|
||||
if (params.length < 1) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class ShowRatesCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class ShowRatesCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
String showMsg = "#eEXP RATE#n" + "\r\n";
|
||||
showMsg += "World EXP Rate: #k" + c.getWorldServer().getExpRate() + "x#k" + "\r\n";
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
|
||||
public class StaffCommand extends Command {
|
||||
@@ -33,7 +34,7 @@ public class StaffCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
c.getAbstractPlayerInteraction().openNpc(NpcId.HERACLE, "credits");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatDexCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class StatDexCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatIntCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class StatIntCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatLukCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class StatLukCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm0;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class StatStrCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class StatStrCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
int remainingAp = player.getRemainingAp();
|
||||
int amount;
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -37,7 +38,7 @@ public class TimeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client client, String[] params) {
|
||||
public void execute(Client client, String[] params, CommandContext ctx) {
|
||||
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
|
||||
dateFormat.setTimeZone(TimeZone.getDefault());
|
||||
client.getPlayer().yellowMessage("Cosmic Server Time: " + dateFormat.format(new Date()));
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class ToggleExpCommand extends Command {
|
||||
{
|
||||
@@ -32,7 +33,7 @@ public class ToggleExpCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
if (c.tryacquireClient()) {
|
||||
try {
|
||||
c.getPlayer().toggleExpGain(); // Vcoc's idea
|
||||
|
||||
@@ -25,6 +25,7 @@ package client.command.commands.gm0;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import net.server.Server;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.DAYS;
|
||||
@@ -38,7 +39,7 @@ public class UptimeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
long milliseconds = System.currentTimeMillis() - Server.uptime;
|
||||
int seconds = (int) (milliseconds / SECONDS.toMillis(1)) % 60;
|
||||
int minutes = (int) ((milliseconds / MINUTES.toMillis(1)) % 60);
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.life.Monster;
|
||||
|
||||
public class BossHpCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class BossHpCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
for (Monster monster : player.getMap().getAllMonsters()) {
|
||||
if (monster != null && monster.isBoss() && monster.getHp() > 0) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class BuffMeCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class BuffMeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(4101004).getEffect(SkillFactory.getSkill(4101004).getMaxLevel()).applyTo(player);
|
||||
SkillFactory.getSkill(2311003).getEffect(SkillFactory.getSkill(2311003).getMaxLevel()).applyTo(player);
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.game.GameConstants;
|
||||
import constants.id.NpcId;
|
||||
import server.maps.FieldLimit;
|
||||
@@ -77,7 +78,7 @@ public class GotoCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
String sendStr = "Syntax: #b@goto <map name>#k. Available areas:\r\n\r\n#rTowns:#k\r\n" + GOTO_TOWNS_INFO;
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.life.Monster;
|
||||
|
||||
public class MobHpCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class MobHpCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
for (Monster monster : player.getMap().getAllMonsters()) {
|
||||
if (monster != null && monster.getHp() > 0) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.life.MonsterDropEntry;
|
||||
@@ -40,7 +41,7 @@ public class WhatDropsFromCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.dropMessage(5, "Please do @whatdropsfrom <monster name>");
|
||||
@@ -56,7 +57,7 @@ public class WhatDropsFromCommand extends Command {
|
||||
int mobId = data.getLeft();
|
||||
String mobName = data.getRight();
|
||||
output += mobName + " drops the following items:\r\n\r\n";
|
||||
for (MonsterDropEntry drop : MonsterInformationProvider.getInstance().retrieveDrop(mobId)) {
|
||||
for (MonsterDropEntry drop : ctx.dropProvider().getMonsterDropEntries(mobId)) {
|
||||
try {
|
||||
String name = ItemInformationProvider.getInstance().getName(drop.itemId);
|
||||
if (name == null || name.equals("null") || drop.chance == 0) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm1;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.NpcId;
|
||||
import server.ItemInformationProvider;
|
||||
import server.life.MonsterInformationProvider;
|
||||
@@ -43,7 +44,7 @@ public class WhoDropsCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.dropMessage(5, "Please do @whodrops <item name>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import config.YamlConfig;
|
||||
|
||||
public class ApCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class ApCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !ap [<playername>] <newap>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import constants.id.MobId;
|
||||
import net.server.Server;
|
||||
import server.life.LifeFactory;
|
||||
@@ -37,7 +38,7 @@ public class BombCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length > 0) {
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
|
||||
@@ -28,6 +28,7 @@ import client.Client;
|
||||
import client.Skill;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class BuffCommand extends Command {
|
||||
{
|
||||
@@ -35,7 +36,7 @@ public class BuffCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !buff <buffid>");
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class BuffMapCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class BuffMapCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
SkillFactory.getSkill(9101001).getEffect(SkillFactory.getSkill(9101001).getMaxLevel()).applyTo(player, true);
|
||||
SkillFactory.getSkill(9101002).getEffect(SkillFactory.getSkill(9101002).getMaxLevel()).applyTo(player, true);
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class ClearDropsCommand extends Command {
|
||||
{
|
||||
@@ -33,7 +34,7 @@ public class ClearDropsCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
player.getMap().clearDrops(player);
|
||||
player.dropMessage(5, "Cleared dropped items");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import server.maps.SavedLocationType;
|
||||
|
||||
public class ClearSavedLocationsCommand extends Command {
|
||||
@@ -34,7 +35,7 @@ public class ClearSavedLocationsCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer(), victim;
|
||||
|
||||
if (params.length > 0) {
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
import client.inventory.InventoryType;
|
||||
import client.inventory.Item;
|
||||
import client.inventory.manipulator.InventoryManipulator;
|
||||
@@ -36,7 +37,7 @@ public class ClearSlotCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !clearslot <all, equip, use, setup, etc or cash.>");
|
||||
|
||||
@@ -26,6 +26,7 @@ package client.command.commands.gm2;
|
||||
import client.Character;
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class DcCommand extends Command {
|
||||
{
|
||||
@@ -33,21 +34,22 @@ public class DcCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
if (params.length < 1) {
|
||||
player.yellowMessage("Syntax: !dc <playername>");
|
||||
return;
|
||||
}
|
||||
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
String chrName = params[0];
|
||||
Character victim = c.getWorldServer().getPlayerStorage().getCharacterByName(chrName);
|
||||
if (victim == null) {
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(params[0]);
|
||||
victim = c.getChannelServer().getPlayerStorage().getCharacterByName(chrName);
|
||||
if (victim == null) {
|
||||
victim = player.getMap().getCharacterByName(params[0]);
|
||||
victim = player.getMap().getCharacterByName(chrName);
|
||||
if (victim != null) {
|
||||
try {//sometimes bugged because the map = null
|
||||
victim.getClient().disconnect(true, false);
|
||||
ctx.transitionService().disconnect(victim.getClient(), true);
|
||||
player.getMap().removePlayer(victim);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -60,6 +62,6 @@ public class DcCommand extends Command {
|
||||
if (player.gmLevel() < victim.gmLevel()) {
|
||||
victim = player;
|
||||
}
|
||||
victim.getClient().disconnect(false, false);
|
||||
ctx.transitionService().disconnect(victim.getClient(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import client.Character;
|
||||
import client.Client;
|
||||
import client.SkillFactory;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class EmpowerMeCommand extends Command {
|
||||
{
|
||||
@@ -34,7 +35,7 @@ public class EmpowerMeCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
Character player = c.getPlayer();
|
||||
final int[] array = {2311003, 2301004, 1301007, 4101004, 2001002, 1101007, 1005, 2301003, 5121009, 1111002, 4111001, 4111002, 4211003, 4211005, 1321000, 2321004, 3121002};
|
||||
for (int i : array) {
|
||||
|
||||
@@ -21,6 +21,7 @@ package client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import client.command.CommandContext;
|
||||
|
||||
/**
|
||||
* @author Ronan
|
||||
@@ -31,7 +32,7 @@ public class GachaListCommand extends Command {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
c.getAbstractPlayerInteraction().openNpc(10000, "gachaponInfo");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,17 @@ package client.command.commands.gm2;
|
||||
|
||||
import client.Client;
|
||||
import client.command.Command;
|
||||
import server.ShopFactory;
|
||||
import client.command.CommandContext;
|
||||
|
||||
public class GmShopCommand extends Command {
|
||||
{
|
||||
setDescription("Open the GM shop.");
|
||||
}
|
||||
|
||||
private static final int GM_SHOP_ID = 1337;
|
||||
|
||||
@Override
|
||||
public void execute(Client c, String[] params) {
|
||||
ShopFactory.getInstance().getShop(1337).sendShop(c);
|
||||
public void execute(Client c, String[] params, CommandContext ctx) {
|
||||
ctx.shopFactory().getShop(GM_SHOP_ID).ifPresent(shop -> shop.sendShop(c));
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user