mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-07-04 14:03:33 +00:00
Compare commits
96 Commits
Author | SHA1 | Date | |
---|---|---|---|
8c2d00fcd3 | |||
308686d9e7 | |||
83d447cfc2 | |||
4ec274f5c5 | |||
30d093f348 | |||
9fd5f7665c | |||
55840bcdb6 | |||
e706cce802 | |||
b58caf0632 | |||
97b28b13fe | |||
4ebe6fbf63 | |||
06d5bf7098 | |||
9d94888da3 | |||
86036682d7 | |||
762e7ae301 | |||
31cef88ef7 | |||
c3339de184 | |||
e382c6d691 | |||
6b3f19e588 | |||
47172c995f | |||
6da5343df0 | |||
89376d58bf | |||
248af4abfb | |||
a7f78c7759 | |||
baac48c4a0 | |||
6c89998759 | |||
3cc5e6b4e8 | |||
0f43e18d70 | |||
1c9f32cbef | |||
d933ca6d02 | |||
3d62e72aa0 | |||
15699e562a | |||
2788206934 | |||
9dbeb2172d | |||
55cb7ab967 | |||
944db42762 | |||
1ed89598ff | |||
4093420c90 | |||
a1f75e1537 | |||
e6d32f5599 | |||
b412a24657 | |||
b4b0b8d2a8 | |||
d8d31f3afe | |||
7fb9913c4f | |||
8472c36490 | |||
ddb76a0c2a | |||
c40213affc | |||
f389d2fb28 | |||
b5595c3fab | |||
ecb6145e54 | |||
eb17d65330 | |||
22e953b636 | |||
6080297be9 | |||
6d6e6a041d | |||
b09c0d48bf | |||
b050337216 | |||
ac3ccf93f3 | |||
0167709070 | |||
63ccff8755 | |||
494cd3b28c | |||
f9dffba27a | |||
f85070abdc | |||
4de21d4a40 | |||
56f09e87a1 | |||
9dae3cbcc7 | |||
d18a8c31a6 | |||
f977679c1c | |||
8fc17ede99 | |||
73e181df9b | |||
5441094e47 | |||
7fc7b5087c | |||
e28575c80f | |||
853a67d48e | |||
e8bfdc3c01 | |||
8870675dcd | |||
43fa6efec9 | |||
d9e8810a5c | |||
82189e03ed | |||
cef8b53dd6 | |||
43f3494073 | |||
20f0cda3e0 | |||
8692405363 | |||
9dd514a73b | |||
1940b22dc5 | |||
bb1729c227 | |||
4870871b2c | |||
2c7c8bf4fd | |||
deaa13c2af | |||
fd40575cb4 | |||
3c0e834348 | |||
27be6c31e6 | |||
87269e9ded | |||
46fee38217 | |||
6e5971df62 | |||
98375deac9 | |||
97c70f7877 |
62
README.md
62
README.md
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
@ -22,51 +22,23 @@
|
|||||||
|
|
||||||
**Note**: For support please join our [Discord](https://discord.gg/T5vZU6UyeG).
|
**Note**: For support please join our [Discord](https://discord.gg/T5vZU6UyeG).
|
||||||
|
|
||||||
### Requirements
|
### Quick Start (automatic)
|
||||||
|
|
||||||
* [Java SE - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) or higher
|
- Get Java 17: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
|
||||||
|
- Get [MongoDB Community Server](https://www.mongodb.com/try/download/community)
|
||||||
|
- Get game version REL3.7 (3.7 client can be found here if you don't have it): https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md)
|
||||||
|
|
||||||
**Note:** If you just want to **run it**, then **jre** only is fine.
|
- Download the [latest Cultivation version](https://github.com/Grasscutters/Cultivation/releases/latest). Use the `.msi` installer.
|
||||||
|
- After opening Culivation (as admin), press the download button in the upper right corner.
|
||||||
|
- Click `Download All-in-One`
|
||||||
|
- Click the gear in the upper right corner
|
||||||
|
- Set the game Install path to where your game is located.
|
||||||
|
- Set the Custom Java Path to `C:\Program Files\Java\jdk-17\bin\java.exe`
|
||||||
|
- Leave all other settings on default
|
||||||
|
|
||||||
* [MongoDB](https://www.mongodb.com/try/download/community) (recommended 4.0+)
|
- Click the small button next to launch.
|
||||||
|
- Click the launch button.
|
||||||
* Proxy Daemon: [mitmproxy](https://mitmproxy.org/) (mitmdump, recommended), [Fiddler Classic](https://telerik-fiddler.s3.amazonaws.com/fiddler/FiddlerSetup.exe), etc.
|
- Log in with whatever username you want. Password doesn't matter.
|
||||||
|
|
||||||
### Running
|
|
||||||
|
|
||||||
**Note:** If you updated from an older version, delete `config.json` to regenerate it.
|
|
||||||
|
|
||||||
1. Get `grasscutter.jar`
|
|
||||||
- Download from [releases](https://github.com/Grasscutters/Grasscutter/releases/latest) or [actions](https://github.com/Grasscutters/Grasscutter/actions/workflows/build.yml) or [build the server by yourself](#building).
|
|
||||||
2. Create a `resources` folder in the directory where grasscutter.jar is located and move your `BinOutput, ExcelBinOutput, Readables, Scripts, Subtitle, TextMap` folders there *(Check the [wiki](https://github.com/Grasscutters/Grasscutter/wiki) for more details how to get those.)*
|
|
||||||
3. Run Grasscutter with `java -jar grasscutter.jar`. **Make sure mongodb service is running as well.**
|
|
||||||
|
|
||||||
### Connecting with the client
|
|
||||||
|
|
||||||
½. Create an account in the server console using this [command](https://github.com/Grasscutters/Grasscutter/wiki/Commands#:~:text=account%20%3Ccreate|delete%3E%20%3Cusername%3E%20[UID]).
|
|
||||||
|
|
||||||
1. Redirect traffic: (choose one only)
|
|
||||||
- mitmdump: `mitmdump -s proxy.py -k`
|
|
||||||
|
|
||||||
- Trust CA certificate:
|
|
||||||
|
|
||||||
- The CA certificate is usually stored in `%USERPROFILE%\.mitmproxy`, double click `mitmproxy-ca-cert.cer` to [install](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) or...
|
|
||||||
|
|
||||||
- Via command line *(needs administration privileges)*
|
|
||||||
|
|
||||||
```shell
|
|
||||||
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
|
||||||
```
|
|
||||||
|
|
||||||
- Fiddler Classic: Run Fiddler Classic, turn on `Decrypt HTTPS traffic` in (Tools -> Options -> HTTPS) and change the default port in (Tools -> Options -> Connections) to anything other than `8888`, load [this script](https://github.com/Grasscutters/Grasscutter/wiki/Resources#fiddler-classic-jscript) (copy and paste the script in the `FiddlerScript` tab) and click the `Save Script` button.
|
|
||||||
|
|
||||||
- [Hosts file](https://github.com/Grasscutters/Grasscutter/wiki/Resources#hosts-file)
|
|
||||||
|
|
||||||
2. Set network proxy to `127.0.0.1:8080` or the proxy port you specified.
|
|
||||||
|
|
||||||
- For mitmproxy: After setting up the network proxy and installing the certificate, check http://mitm.it/ if traffic is passing through mitmproxy.
|
|
||||||
|
|
||||||
**You can also use `start.cmd` to start servers and proxy daemons automatically, but you have to set up `JAVA_HOME` environment and configure the `start_config.cmd` file.**
|
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
@ -80,7 +52,7 @@ Grasscutter uses Gradle to handle dependencies & building.
|
|||||||
##### Windows
|
##### Windows
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git clone --recurse-submodules -b unstable https://github.com/Grasscutters/Grasscutter.git
|
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
|
||||||
cd Grasscutter
|
cd Grasscutter
|
||||||
.\gradlew.bat # Setting up environments
|
.\gradlew.bat # Setting up environments
|
||||||
.\gradlew jar # Compile
|
.\gradlew jar # Compile
|
||||||
@ -89,7 +61,7 @@ cd Grasscutter
|
|||||||
##### Linux (GNU)
|
##### Linux (GNU)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone --recurse-submodules -b unstable https://github.com/Grasscutters/Grasscutter.git
|
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
|
||||||
cd Grasscutter
|
cd Grasscutter
|
||||||
chmod +x gradlew
|
chmod +x gradlew
|
||||||
./gradlew jar # Compile
|
./gradlew jar # Compile
|
||||||
|
42
build.gradle
42
build.gradle
@ -57,7 +57,7 @@ sourceCompatibility = JavaVersion.VERSION_17
|
|||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
|
||||||
group = 'io.grasscutter'
|
group = 'io.grasscutter'
|
||||||
version = '2.0.0-unstable'
|
version = '1.6.1'
|
||||||
|
|
||||||
java {
|
java {
|
||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
@ -335,18 +335,48 @@ tasks.register('generateHandbook') {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
def nodeVersion = {
|
def npmVersion = {
|
||||||
try {
|
try {
|
||||||
return 'node --version'.execute().text.trim()
|
return 'npm --version'.execute().text.trim()
|
||||||
} catch (ignored) {
|
} catch (ignored) {
|
||||||
return 'NODE_NOT_FOUND'
|
return 'NPM_NOT_FOUND'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if Node is installed.
|
// Check if Node is installed.
|
||||||
if (nodeVersion() == 'NODE_NOT_FOUND') {
|
if (npmVersion() == 'NPM_NOT_FOUND') {
|
||||||
println('Node is not installed. Skipping handbook generation.')
|
println('NPM is not installed. Skipping handbook generation.')
|
||||||
} else {
|
} else {
|
||||||
|
// Check if the handbook resources are present.
|
||||||
|
if (!file('src/handbook/data/commands.json')) {
|
||||||
|
println('Command data was not found. Skipping handbook generation.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!file('src/handbook/data/avatars.csv')) {
|
||||||
|
println('Avatar data was not found. Skipping handbook generation.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!file('src/handbook/data/entities.csv')) {
|
||||||
|
println('Entity data was not found. Skipping handbook generation.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!file('src/handbook/data/items.csv')) {
|
||||||
|
println('Item data was not found. Skipping handbook generation.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!file('src/handbook/data/mainquests.csv')) {
|
||||||
|
println('Main quest data was not found. Skipping handbook generation.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!file('src/handbook/data/quests.csv')) {
|
||||||
|
println('Quest data was not found. Skipping handbook generation.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!file('src/handbook/data/scenes.csv')) {
|
||||||
|
println('Scene data was not found. Skipping handbook generation.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Build the handbook.
|
// Build the handbook.
|
||||||
var npm = 'npm'
|
var npm = 'npm'
|
||||||
if (Os.isFamily(Os.FAMILY_WINDOWS))
|
if (Os.isFamily(Os.FAMILY_WINDOWS))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md)
|
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md)
|
||||||
|
|
||||||
**请注意:** 欢迎成为本项目的贡献者。但在提交 PR 之前, 请仔细阅读 [代码规范](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。
|
**注意:** 我们始终欢迎项目的贡献者。但在做贡献之前,请仔细阅读我们的[代码规范](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。
|
||||||
|
|
||||||
## 当前功能
|
## 当前功能
|
||||||
|
|
||||||
@ -16,92 +16,59 @@
|
|||||||
* 祈愿
|
* 祈愿
|
||||||
* 多人游戏 *部分* 可用
|
* 多人游戏 *部分* 可用
|
||||||
* 从控制台生成魔物
|
* 从控制台生成魔物
|
||||||
* 物品 (接收或升级角色、武器等)
|
* 背包功能(接收或升级物品、角色等)。
|
||||||
|
|
||||||
|
## 快速安装指南
|
||||||
|
|
||||||
## 快速设置指南
|
**注意:** 如需帮助,请加入我们的[Discord](https://discord.gg/T5vZU6UyeG)。
|
||||||
|
|
||||||
**注意:** 如需帮助请加入 [Discord](https://discord.gg/T5vZU6UyeG)
|
### 快速开始(全自动)
|
||||||
|
|
||||||
### 环境需求
|
- 获取Java 17:https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
|
||||||
|
- 获取[MongoDB社区版](https://www.mongodb.com/try/download/community)
|
||||||
|
- 获取游戏3.7正式版 (如果你没有3.7的客户端,可以在这里找到):https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md)
|
||||||
|
|
||||||
* [Java SE - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
- 下载[最新的Cultivation版本](https://github.com/Grasscutters/Cultivation/releases/latest)(使用以“.msi”为后缀的安装包)。
|
||||||
|
- 以管理员身份打开Culivation,按右上角的下载按钮。
|
||||||
|
- 点击“下载 Grasscutter 一体化”
|
||||||
|
- 点击右上角的齿轮
|
||||||
|
- 将游戏安装路径设置为你游戏所在的位置。
|
||||||
|
- 将自定义Java路径设置为`C:\Program Files\Java\jdk-17\bin\java.exe`
|
||||||
|
- 保持所有其它设置为默认值
|
||||||
|
|
||||||
**注意:** 如果想仅**运行服务端**, 只下载 **jre** 即可
|
- 点击“启动”按钮旁边的小按钮。
|
||||||
|
- 点击“启动”按钮。
|
||||||
* [MongoDB](https://www.mongodb.com/try/download/community) (推荐 4.0+)
|
- 随便想一个用户名登录,不需要密码。
|
||||||
|
|
||||||
* 代理程序: [mitmproxy](https://mitmproxy.org/) (仅需 mitmdump;推荐使用), [Fiddler Classic](https://telerik-fiddler.s3.amazonaws.com/fiddler/FiddlerSetup.exe) 等
|
|
||||||
|
|
||||||
### 运行服务端
|
|
||||||
|
|
||||||
**注意:** 从旧版本升级到新版本, 需要删除 `config.json` 使其重新生成
|
|
||||||
|
|
||||||
1. 获取 `grasscutter.jar`
|
|
||||||
- 从 [actions](https://github.com/Grasscutters/Grasscutter/actions) 下载,或 [自行编译](#构建)
|
|
||||||
2. 在 JAR 文件根目录中创建 `resources` 文件夹并复制 `BinOutput` 和 `ExcelBinOutput` *(查看 [Wiki](https://github.com/Grasscutters/Grasscutter/wiki) 了解更多)*
|
|
||||||
3. **确认 MongoDB 服务运行正常后**,使用命令行 `java -jar grasscutter.jar` 运行 Grasscutter。
|
|
||||||
|
|
||||||
### 客户端连接
|
|
||||||
|
|
||||||
½. 在服务器控制台 [创建账户](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting)
|
|
||||||
|
|
||||||
1. 重定向流量: (选择其中一个)
|
|
||||||
- mitmdump: `mitmdump -s proxy.py -k`
|
|
||||||
|
|
||||||
信任 CA 证书:
|
|
||||||
|
|
||||||
**注意:** mitmproxy 的 CA 证书通常存放在 `%USERPROFILE%\ .mitmproxy`, 或者从 `http://mitm.it` 下载证书
|
|
||||||
|
|
||||||
双击 [安装根证书](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate)或者...
|
|
||||||
|
|
||||||
- 使用命令行
|
|
||||||
|
|
||||||
```shell
|
|
||||||
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
|
||||||
```
|
|
||||||
|
|
||||||
- Fiddler Classic: 运行 Fiddler Classic, 在设置中开启 `解密 https 通信` 并将端口设为除 `8888` 以外的任意端口 (工具 -> 选项 -> 连接) 并加载 [此脚本](https://github.lunatic.moe/fiddlerscript)
|
|
||||||
|
|
||||||
- [Hosts 文件](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
|
|
||||||
|
|
||||||
2. 设置代理为 `127.0.0.1:8080` 或你设置的端口
|
|
||||||
|
|
||||||
**也可直接运行 `start.cmd` 一键启动服务端并设置代理, 但设置 `JAVA_HOME` 环境变量并配置 `start_config.cmd`**
|
|
||||||
|
|
||||||
### 构建
|
### 构建
|
||||||
|
|
||||||
Grasscutter 使用 Gradle 来处理依赖及编译。
|
Grasscutter使用Gradle来处理依赖和构建。
|
||||||
|
|
||||||
**前置依赖:**
|
**前置:**
|
||||||
|
|
||||||
- [Java SE Development Kits - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
- [Java SE Development Kits - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)或更高版本
|
||||||
- [Git](https://git-scm.com/downloads)
|
- [Git](https://git-scm.com/downloads)
|
||||||
|
|
||||||
##### Windows
|
##### Windows
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git clone https://github.com/Grasscutters/Grasscutter.git
|
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
|
||||||
cd Grasscutter
|
cd Grasscutter
|
||||||
.\gradlew.bat # 建立开发环境
|
.\gradlew.bat # 设置开发环境
|
||||||
.\gradlew jar # 编译
|
.\gradlew jar # 编译
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Linux
|
##### Linux(GNU)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/Grasscutters/Grasscutter.git
|
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
|
||||||
cd Grasscutter
|
cd Grasscutter
|
||||||
chmod +x gradlew
|
chmod +x gradlew
|
||||||
./gradlew jar # 编译
|
./gradlew jar # 编译
|
||||||
```
|
```
|
||||||
|
|
||||||
* 编译后的 JAR 文件会在源码根目录生成
|
你可以在项目的根目录找到输出的jar。
|
||||||
|
|
||||||
### 命令列表请到 [wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands) 查看
|
### 故障排除
|
||||||
|
|
||||||
# 快速问题排除
|
获取常见问题的解决方案或寻求帮助,请加入[我们的Discord服务器](https://discord.gg/T5vZU6UyeG)并进入“support”频道。
|
||||||
|
|
||||||
* 如果编译失败, 请检查 JDK 安装是否正确 (需要 JDK 17 并确认 JDK 的 bin 文件夹处于环境变量 `PATH` 中)
|
|
||||||
* 客户端无法登录、连接、错误 4206 等其他问题... - 大部分情况是因为代理设置出现了*问题*。
|
|
||||||
如果使用 Fiddler,请确认 Fiddler 监听端口不是 `8888`
|
|
||||||
* 启动顺序: MongoDB > Grasscutter > 代理程序 (mitmdump, Fiddler 等) > 客户端
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/Grasscutters/Grasscutter/Build?logo=github&style=for-the-badge"></div>
|
<div align="center"><img alt="Documention" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
|
||||||
|
|
||||||
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
|
||||||
|
|
||||||
|
@ -0,0 +1,539 @@
|
|||||||
|
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||||
|
// source: AbilityActionSetRandomOverrideMapValue.proto
|
||||||
|
|
||||||
|
package emu.grasscutter.net.proto;
|
||||||
|
|
||||||
|
public final class AbilityActionSetRandomOverrideMapValueOuterClass {
|
||||||
|
private AbilityActionSetRandomOverrideMapValueOuterClass() {}
|
||||||
|
public static void registerAllExtensions(
|
||||||
|
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerAllExtensions(
|
||||||
|
com.google.protobuf.ExtensionRegistry registry) {
|
||||||
|
registerAllExtensions(
|
||||||
|
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||||
|
}
|
||||||
|
public interface AbilityActionSetRandomOverrideMapValueOrBuilder extends
|
||||||
|
// @@protoc_insertion_point(interface_extends:AbilityActionSetRandomOverrideMapValue)
|
||||||
|
com.google.protobuf.MessageOrBuilder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>float random_value = 1;</code>
|
||||||
|
* @return The randomValue.
|
||||||
|
*/
|
||||||
|
float getRandomValue();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Protobuf type {@code AbilityActionSetRandomOverrideMapValue}
|
||||||
|
*/
|
||||||
|
public static final class AbilityActionSetRandomOverrideMapValue extends
|
||||||
|
com.google.protobuf.GeneratedMessageV3 implements
|
||||||
|
// @@protoc_insertion_point(message_implements:AbilityActionSetRandomOverrideMapValue)
|
||||||
|
AbilityActionSetRandomOverrideMapValueOrBuilder {
|
||||||
|
private static final long serialVersionUID = 0L;
|
||||||
|
// Use AbilityActionSetRandomOverrideMapValue.newBuilder() to construct.
|
||||||
|
private AbilityActionSetRandomOverrideMapValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
|
||||||
|
super(builder);
|
||||||
|
}
|
||||||
|
private AbilityActionSetRandomOverrideMapValue() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
@SuppressWarnings({"unused"})
|
||||||
|
protected java.lang.Object newInstance(
|
||||||
|
UnusedPrivateParameter unused) {
|
||||||
|
return new AbilityActionSetRandomOverrideMapValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public final com.google.protobuf.UnknownFieldSet
|
||||||
|
getUnknownFields() {
|
||||||
|
return this.unknownFields;
|
||||||
|
}
|
||||||
|
private AbilityActionSetRandomOverrideMapValue(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
this();
|
||||||
|
if (extensionRegistry == null) {
|
||||||
|
throw new java.lang.NullPointerException();
|
||||||
|
}
|
||||||
|
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||||
|
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||||
|
try {
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int tag = input.readTag();
|
||||||
|
switch (tag) {
|
||||||
|
case 0:
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
case 13: {
|
||||||
|
|
||||||
|
randomValue_ = input.readFloat();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
if (!parseUnknownField(
|
||||||
|
input, unknownFields, extensionRegistry, tag)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
throw e.setUnfinishedMessage(this);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||||
|
e).setUnfinishedMessage(this);
|
||||||
|
} finally {
|
||||||
|
this.unknownFields = unknownFields.build();
|
||||||
|
makeExtensionsImmutable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.internal_static_AbilityActionSetRandomOverrideMapValue_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.internal_static_AbilityActionSetRandomOverrideMapValue_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue.class, emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int RANDOM_VALUE_FIELD_NUMBER = 1;
|
||||||
|
private float randomValue_;
|
||||||
|
/**
|
||||||
|
* <code>float random_value = 1;</code>
|
||||||
|
* @return The randomValue.
|
||||||
|
*/
|
||||||
|
@java.lang.Override
|
||||||
|
public float getRandomValue() {
|
||||||
|
return randomValue_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte memoizedIsInitialized = -1;
|
||||||
|
@java.lang.Override
|
||||||
|
public final boolean isInitialized() {
|
||||||
|
byte isInitialized = memoizedIsInitialized;
|
||||||
|
if (isInitialized == 1) return true;
|
||||||
|
if (isInitialized == 0) return false;
|
||||||
|
|
||||||
|
memoizedIsInitialized = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||||
|
throws java.io.IOException {
|
||||||
|
if (randomValue_ != 0F) {
|
||||||
|
output.writeFloat(1, randomValue_);
|
||||||
|
}
|
||||||
|
unknownFields.writeTo(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public int getSerializedSize() {
|
||||||
|
int size = memoizedSize;
|
||||||
|
if (size != -1) return size;
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
if (randomValue_ != 0F) {
|
||||||
|
size += com.google.protobuf.CodedOutputStream
|
||||||
|
.computeFloatSize(1, randomValue_);
|
||||||
|
}
|
||||||
|
size += unknownFields.getSerializedSize();
|
||||||
|
memoizedSize = size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public boolean equals(final java.lang.Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue)) {
|
||||||
|
return super.equals(obj);
|
||||||
|
}
|
||||||
|
emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue other = (emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue) obj;
|
||||||
|
|
||||||
|
if (java.lang.Float.floatToIntBits(getRandomValue())
|
||||||
|
!= java.lang.Float.floatToIntBits(
|
||||||
|
other.getRandomValue())) return false;
|
||||||
|
if (!unknownFields.equals(other.unknownFields)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (memoizedHashCode != 0) {
|
||||||
|
return memoizedHashCode;
|
||||||
|
}
|
||||||
|
int hash = 41;
|
||||||
|
hash = (19 * hash) + getDescriptor().hashCode();
|
||||||
|
hash = (37 * hash) + RANDOM_VALUE_FIELD_NUMBER;
|
||||||
|
hash = (53 * hash) + java.lang.Float.floatToIntBits(
|
||||||
|
getRandomValue());
|
||||||
|
hash = (29 * hash) + unknownFields.hashCode();
|
||||||
|
memoizedHashCode = hash;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(
|
||||||
|
java.nio.ByteBuffer data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(
|
||||||
|
java.nio.ByteBuffer data,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(
|
||||||
|
com.google.protobuf.ByteString data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(
|
||||||
|
com.google.protobuf.ByteString data,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(byte[] data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(
|
||||||
|
byte[] data,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(java.io.InputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseWithIOException(PARSER, input);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(
|
||||||
|
java.io.InputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseDelimitedFrom(java.io.InputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseDelimitedWithIOException(PARSER, input);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseDelimitedFrom(
|
||||||
|
java.io.InputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseWithIOException(PARSER, input);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parseFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder newBuilderForType() { return newBuilder(); }
|
||||||
|
public static Builder newBuilder() {
|
||||||
|
return DEFAULT_INSTANCE.toBuilder();
|
||||||
|
}
|
||||||
|
public static Builder newBuilder(emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue prototype) {
|
||||||
|
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return this == DEFAULT_INSTANCE
|
||||||
|
? new Builder() : new Builder().mergeFrom(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
protected Builder newBuilderForType(
|
||||||
|
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
|
||||||
|
Builder builder = new Builder(parent);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Protobuf type {@code AbilityActionSetRandomOverrideMapValue}
|
||||||
|
*/
|
||||||
|
public static final class Builder extends
|
||||||
|
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
|
||||||
|
// @@protoc_insertion_point(builder_implements:AbilityActionSetRandomOverrideMapValue)
|
||||||
|
emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValueOrBuilder {
|
||||||
|
public static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.internal_static_AbilityActionSetRandomOverrideMapValue_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.internal_static_AbilityActionSetRandomOverrideMapValue_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue.class, emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct using emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue.newBuilder()
|
||||||
|
private Builder() {
|
||||||
|
maybeForceBuilderInitialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(
|
||||||
|
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
|
||||||
|
super(parent);
|
||||||
|
maybeForceBuilderInitialization();
|
||||||
|
}
|
||||||
|
private void maybeForceBuilderInitialization() {
|
||||||
|
if (com.google.protobuf.GeneratedMessageV3
|
||||||
|
.alwaysUseFieldBuilders) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder clear() {
|
||||||
|
super.clear();
|
||||||
|
randomValue_ = 0F;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptorForType() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.internal_static_AbilityActionSetRandomOverrideMapValue_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue getDefaultInstanceForType() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue.getDefaultInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue build() {
|
||||||
|
emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue result = buildPartial();
|
||||||
|
if (!result.isInitialized()) {
|
||||||
|
throw newUninitializedMessageException(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue buildPartial() {
|
||||||
|
emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue result = new emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue(this);
|
||||||
|
result.randomValue_ = randomValue_;
|
||||||
|
onBuilt();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder clone() {
|
||||||
|
return super.clone();
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder setField(
|
||||||
|
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||||
|
java.lang.Object value) {
|
||||||
|
return super.setField(field, value);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder clearField(
|
||||||
|
com.google.protobuf.Descriptors.FieldDescriptor field) {
|
||||||
|
return super.clearField(field);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder clearOneof(
|
||||||
|
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
|
||||||
|
return super.clearOneof(oneof);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder setRepeatedField(
|
||||||
|
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||||
|
int index, java.lang.Object value) {
|
||||||
|
return super.setRepeatedField(field, index, value);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder addRepeatedField(
|
||||||
|
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||||
|
java.lang.Object value) {
|
||||||
|
return super.addRepeatedField(field, value);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||||
|
if (other instanceof emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue) {
|
||||||
|
return mergeFrom((emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue)other);
|
||||||
|
} else {
|
||||||
|
super.mergeFrom(other);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue other) {
|
||||||
|
if (other == emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue.getDefaultInstance()) return this;
|
||||||
|
if (other.getRandomValue() != 0F) {
|
||||||
|
setRandomValue(other.getRandomValue());
|
||||||
|
}
|
||||||
|
this.mergeUnknownFields(other.unknownFields);
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public final boolean isInitialized() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder mergeFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue parsedMessage = null;
|
||||||
|
try {
|
||||||
|
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||||
|
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
parsedMessage = (emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue) e.getUnfinishedMessage();
|
||||||
|
throw e.unwrapIOException();
|
||||||
|
} finally {
|
||||||
|
if (parsedMessage != null) {
|
||||||
|
mergeFrom(parsedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float randomValue_ ;
|
||||||
|
/**
|
||||||
|
* <code>float random_value = 1;</code>
|
||||||
|
* @return The randomValue.
|
||||||
|
*/
|
||||||
|
@java.lang.Override
|
||||||
|
public float getRandomValue() {
|
||||||
|
return randomValue_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>float random_value = 1;</code>
|
||||||
|
* @param value The randomValue to set.
|
||||||
|
* @return This builder for chaining.
|
||||||
|
*/
|
||||||
|
public Builder setRandomValue(float value) {
|
||||||
|
|
||||||
|
randomValue_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>float random_value = 1;</code>
|
||||||
|
* @return This builder for chaining.
|
||||||
|
*/
|
||||||
|
public Builder clearRandomValue() {
|
||||||
|
|
||||||
|
randomValue_ = 0F;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public final Builder setUnknownFields(
|
||||||
|
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||||
|
return super.setUnknownFields(unknownFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public final Builder mergeUnknownFields(
|
||||||
|
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||||
|
return super.mergeUnknownFields(unknownFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(builder_scope:AbilityActionSetRandomOverrideMapValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(class_scope:AbilityActionSetRandomOverrideMapValue)
|
||||||
|
private static final emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue DEFAULT_INSTANCE;
|
||||||
|
static {
|
||||||
|
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue getDefaultInstance() {
|
||||||
|
return DEFAULT_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final com.google.protobuf.Parser<AbilityActionSetRandomOverrideMapValue>
|
||||||
|
PARSER = new com.google.protobuf.AbstractParser<AbilityActionSetRandomOverrideMapValue>() {
|
||||||
|
@java.lang.Override
|
||||||
|
public AbilityActionSetRandomOverrideMapValue parsePartialFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return new AbilityActionSetRandomOverrideMapValue(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static com.google.protobuf.Parser<AbilityActionSetRandomOverrideMapValue> parser() {
|
||||||
|
return PARSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public com.google.protobuf.Parser<AbilityActionSetRandomOverrideMapValue> getParserForType() {
|
||||||
|
return PARSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue getDefaultInstanceForType() {
|
||||||
|
return DEFAULT_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
internal_static_AbilityActionSetRandomOverrideMapValue_descriptor;
|
||||||
|
private static final
|
||||||
|
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||||
|
internal_static_AbilityActionSetRandomOverrideMapValue_fieldAccessorTable;
|
||||||
|
|
||||||
|
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
descriptor;
|
||||||
|
static {
|
||||||
|
java.lang.String[] descriptorData = {
|
||||||
|
"\n,AbilityActionSetRandomOverrideMapValue" +
|
||||||
|
".proto\">\n&AbilityActionSetRandomOverride" +
|
||||||
|
"MapValue\022\024\n\014random_value\030\001 \001(\002B\033\n\031emu.gr" +
|
||||||
|
"asscutter.net.protob\006proto3"
|
||||||
|
};
|
||||||
|
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
.internalBuildGeneratedFileFrom(descriptorData,
|
||||||
|
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||||
|
});
|
||||||
|
internal_static_AbilityActionSetRandomOverrideMapValue_descriptor =
|
||||||
|
getDescriptor().getMessageTypes().get(0);
|
||||||
|
internal_static_AbilityActionSetRandomOverrideMapValue_fieldAccessorTable = new
|
||||||
|
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||||
|
internal_static_AbilityActionSetRandomOverrideMapValue_descriptor,
|
||||||
|
new java.lang.String[] { "RandomValue", });
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(outer_class_scope)
|
||||||
|
}
|
@ -0,0 +1,545 @@
|
|||||||
|
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||||
|
// source: AbilityMetaSetKilledState.proto
|
||||||
|
|
||||||
|
package emu.grasscutter.net.proto;
|
||||||
|
|
||||||
|
public final class AbilityMetaSetKilledStateOuterClass {
|
||||||
|
private AbilityMetaSetKilledStateOuterClass() {}
|
||||||
|
public static void registerAllExtensions(
|
||||||
|
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerAllExtensions(
|
||||||
|
com.google.protobuf.ExtensionRegistry registry) {
|
||||||
|
registerAllExtensions(
|
||||||
|
(com.google.protobuf.ExtensionRegistryLite) registry);
|
||||||
|
}
|
||||||
|
public interface AbilityMetaSetKilledStateOrBuilder extends
|
||||||
|
// @@protoc_insertion_point(interface_extends:AbilityMetaSetKilledState)
|
||||||
|
com.google.protobuf.MessageOrBuilder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>bool killed = 6;</code>
|
||||||
|
* @return The killed.
|
||||||
|
*/
|
||||||
|
boolean getKilled();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* Handcrafted by Magix!
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* Protobuf type {@code AbilityMetaSetKilledState}
|
||||||
|
*/
|
||||||
|
public static final class AbilityMetaSetKilledState extends
|
||||||
|
com.google.protobuf.GeneratedMessageV3 implements
|
||||||
|
// @@protoc_insertion_point(message_implements:AbilityMetaSetKilledState)
|
||||||
|
AbilityMetaSetKilledStateOrBuilder {
|
||||||
|
private static final long serialVersionUID = 0L;
|
||||||
|
// Use AbilityMetaSetKilledState.newBuilder() to construct.
|
||||||
|
private AbilityMetaSetKilledState(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
|
||||||
|
super(builder);
|
||||||
|
}
|
||||||
|
private AbilityMetaSetKilledState() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
@SuppressWarnings({"unused"})
|
||||||
|
protected java.lang.Object newInstance(
|
||||||
|
UnusedPrivateParameter unused) {
|
||||||
|
return new AbilityMetaSetKilledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public final com.google.protobuf.UnknownFieldSet
|
||||||
|
getUnknownFields() {
|
||||||
|
return this.unknownFields;
|
||||||
|
}
|
||||||
|
private AbilityMetaSetKilledState(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
this();
|
||||||
|
if (extensionRegistry == null) {
|
||||||
|
throw new java.lang.NullPointerException();
|
||||||
|
}
|
||||||
|
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||||
|
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||||
|
try {
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int tag = input.readTag();
|
||||||
|
switch (tag) {
|
||||||
|
case 0:
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
case 48: {
|
||||||
|
|
||||||
|
killed_ = input.readBool();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
if (!parseUnknownField(
|
||||||
|
input, unknownFields, extensionRegistry, tag)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
throw e.setUnfinishedMessage(this);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||||
|
e).setUnfinishedMessage(this);
|
||||||
|
} finally {
|
||||||
|
this.unknownFields = unknownFields.build();
|
||||||
|
makeExtensionsImmutable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.internal_static_AbilityMetaSetKilledState_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.internal_static_AbilityMetaSetKilledState_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState.class, emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int KILLED_FIELD_NUMBER = 6;
|
||||||
|
private boolean killed_;
|
||||||
|
/**
|
||||||
|
* <code>bool killed = 6;</code>
|
||||||
|
* @return The killed.
|
||||||
|
*/
|
||||||
|
@java.lang.Override
|
||||||
|
public boolean getKilled() {
|
||||||
|
return killed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte memoizedIsInitialized = -1;
|
||||||
|
@java.lang.Override
|
||||||
|
public final boolean isInitialized() {
|
||||||
|
byte isInitialized = memoizedIsInitialized;
|
||||||
|
if (isInitialized == 1) return true;
|
||||||
|
if (isInitialized == 0) return false;
|
||||||
|
|
||||||
|
memoizedIsInitialized = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||||
|
throws java.io.IOException {
|
||||||
|
if (killed_ != false) {
|
||||||
|
output.writeBool(6, killed_);
|
||||||
|
}
|
||||||
|
unknownFields.writeTo(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public int getSerializedSize() {
|
||||||
|
int size = memoizedSize;
|
||||||
|
if (size != -1) return size;
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
if (killed_ != false) {
|
||||||
|
size += com.google.protobuf.CodedOutputStream
|
||||||
|
.computeBoolSize(6, killed_);
|
||||||
|
}
|
||||||
|
size += unknownFields.getSerializedSize();
|
||||||
|
memoizedSize = size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public boolean equals(final java.lang.Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState)) {
|
||||||
|
return super.equals(obj);
|
||||||
|
}
|
||||||
|
emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState other = (emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState) obj;
|
||||||
|
|
||||||
|
if (getKilled()
|
||||||
|
!= other.getKilled()) return false;
|
||||||
|
if (!unknownFields.equals(other.unknownFields)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public int hashCode() {
|
||||||
|
if (memoizedHashCode != 0) {
|
||||||
|
return memoizedHashCode;
|
||||||
|
}
|
||||||
|
int hash = 41;
|
||||||
|
hash = (19 * hash) + getDescriptor().hashCode();
|
||||||
|
hash = (37 * hash) + KILLED_FIELD_NUMBER;
|
||||||
|
hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
|
||||||
|
getKilled());
|
||||||
|
hash = (29 * hash) + unknownFields.hashCode();
|
||||||
|
memoizedHashCode = hash;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(
|
||||||
|
java.nio.ByteBuffer data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(
|
||||||
|
java.nio.ByteBuffer data,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(
|
||||||
|
com.google.protobuf.ByteString data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(
|
||||||
|
com.google.protobuf.ByteString data,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(byte[] data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(
|
||||||
|
byte[] data,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(java.io.InputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseWithIOException(PARSER, input);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(
|
||||||
|
java.io.InputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseDelimitedFrom(java.io.InputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseDelimitedWithIOException(PARSER, input);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseDelimitedFrom(
|
||||||
|
java.io.InputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseWithIOException(PARSER, input);
|
||||||
|
}
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parseFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return com.google.protobuf.GeneratedMessageV3
|
||||||
|
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder newBuilderForType() { return newBuilder(); }
|
||||||
|
public static Builder newBuilder() {
|
||||||
|
return DEFAULT_INSTANCE.toBuilder();
|
||||||
|
}
|
||||||
|
public static Builder newBuilder(emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState prototype) {
|
||||||
|
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return this == DEFAULT_INSTANCE
|
||||||
|
? new Builder() : new Builder().mergeFrom(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
protected Builder newBuilderForType(
|
||||||
|
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
|
||||||
|
Builder builder = new Builder(parent);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* Handcrafted by Magix!
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* Protobuf type {@code AbilityMetaSetKilledState}
|
||||||
|
*/
|
||||||
|
public static final class Builder extends
|
||||||
|
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
|
||||||
|
// @@protoc_insertion_point(builder_implements:AbilityMetaSetKilledState)
|
||||||
|
emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledStateOrBuilder {
|
||||||
|
public static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.internal_static_AbilityMetaSetKilledState_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.internal_static_AbilityMetaSetKilledState_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState.class, emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct using emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState.newBuilder()
|
||||||
|
private Builder() {
|
||||||
|
maybeForceBuilderInitialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(
|
||||||
|
com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
|
||||||
|
super(parent);
|
||||||
|
maybeForceBuilderInitialization();
|
||||||
|
}
|
||||||
|
private void maybeForceBuilderInitialization() {
|
||||||
|
if (com.google.protobuf.GeneratedMessageV3
|
||||||
|
.alwaysUseFieldBuilders) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder clear() {
|
||||||
|
super.clear();
|
||||||
|
killed_ = false;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptorForType() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.internal_static_AbilityMetaSetKilledState_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState getDefaultInstanceForType() {
|
||||||
|
return emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState.getDefaultInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState build() {
|
||||||
|
emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState result = buildPartial();
|
||||||
|
if (!result.isInitialized()) {
|
||||||
|
throw newUninitializedMessageException(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState buildPartial() {
|
||||||
|
emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState result = new emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState(this);
|
||||||
|
result.killed_ = killed_;
|
||||||
|
onBuilt();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder clone() {
|
||||||
|
return super.clone();
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder setField(
|
||||||
|
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||||
|
java.lang.Object value) {
|
||||||
|
return super.setField(field, value);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder clearField(
|
||||||
|
com.google.protobuf.Descriptors.FieldDescriptor field) {
|
||||||
|
return super.clearField(field);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder clearOneof(
|
||||||
|
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
|
||||||
|
return super.clearOneof(oneof);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder setRepeatedField(
|
||||||
|
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||||
|
int index, java.lang.Object value) {
|
||||||
|
return super.setRepeatedField(field, index, value);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder addRepeatedField(
|
||||||
|
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||||
|
java.lang.Object value) {
|
||||||
|
return super.addRepeatedField(field, value);
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||||
|
if (other instanceof emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState) {
|
||||||
|
return mergeFrom((emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState)other);
|
||||||
|
} else {
|
||||||
|
super.mergeFrom(other);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState other) {
|
||||||
|
if (other == emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState.getDefaultInstance()) return this;
|
||||||
|
if (other.getKilled() != false) {
|
||||||
|
setKilled(other.getKilled());
|
||||||
|
}
|
||||||
|
this.mergeUnknownFields(other.unknownFields);
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public final boolean isInitialized() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public Builder mergeFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState parsedMessage = null;
|
||||||
|
try {
|
||||||
|
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||||
|
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
parsedMessage = (emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState) e.getUnfinishedMessage();
|
||||||
|
throw e.unwrapIOException();
|
||||||
|
} finally {
|
||||||
|
if (parsedMessage != null) {
|
||||||
|
mergeFrom(parsedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean killed_ ;
|
||||||
|
/**
|
||||||
|
* <code>bool killed = 6;</code>
|
||||||
|
* @return The killed.
|
||||||
|
*/
|
||||||
|
@java.lang.Override
|
||||||
|
public boolean getKilled() {
|
||||||
|
return killed_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>bool killed = 6;</code>
|
||||||
|
* @param value The killed to set.
|
||||||
|
* @return This builder for chaining.
|
||||||
|
*/
|
||||||
|
public Builder setKilled(boolean value) {
|
||||||
|
|
||||||
|
killed_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>bool killed = 6;</code>
|
||||||
|
* @return This builder for chaining.
|
||||||
|
*/
|
||||||
|
public Builder clearKilled() {
|
||||||
|
|
||||||
|
killed_ = false;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
@java.lang.Override
|
||||||
|
public final Builder setUnknownFields(
|
||||||
|
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||||
|
return super.setUnknownFields(unknownFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public final Builder mergeUnknownFields(
|
||||||
|
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||||
|
return super.mergeUnknownFields(unknownFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(builder_scope:AbilityMetaSetKilledState)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(class_scope:AbilityMetaSetKilledState)
|
||||||
|
private static final emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState DEFAULT_INSTANCE;
|
||||||
|
static {
|
||||||
|
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState getDefaultInstance() {
|
||||||
|
return DEFAULT_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final com.google.protobuf.Parser<AbilityMetaSetKilledState>
|
||||||
|
PARSER = new com.google.protobuf.AbstractParser<AbilityMetaSetKilledState>() {
|
||||||
|
@java.lang.Override
|
||||||
|
public AbilityMetaSetKilledState parsePartialFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return new AbilityMetaSetKilledState(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static com.google.protobuf.Parser<AbilityMetaSetKilledState> parser() {
|
||||||
|
return PARSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public com.google.protobuf.Parser<AbilityMetaSetKilledState> getParserForType() {
|
||||||
|
return PARSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState getDefaultInstanceForType() {
|
||||||
|
return DEFAULT_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
internal_static_AbilityMetaSetKilledState_descriptor;
|
||||||
|
private static final
|
||||||
|
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
|
||||||
|
internal_static_AbilityMetaSetKilledState_fieldAccessorTable;
|
||||||
|
|
||||||
|
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
descriptor;
|
||||||
|
static {
|
||||||
|
java.lang.String[] descriptorData = {
|
||||||
|
"\n\037AbilityMetaSetKilledState.proto\"+\n\031Abi" +
|
||||||
|
"lityMetaSetKilledState\022\016\n\006killed\030\006 \001(\010B\033" +
|
||||||
|
"\n\031emu.grasscutter.net.protob\006proto3"
|
||||||
|
};
|
||||||
|
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
.internalBuildGeneratedFileFrom(descriptorData,
|
||||||
|
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||||
|
});
|
||||||
|
internal_static_AbilityMetaSetKilledState_descriptor =
|
||||||
|
getDescriptor().getMessageTypes().get(0);
|
||||||
|
internal_static_AbilityMetaSetKilledState_fieldAccessorTable = new
|
||||||
|
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||||
|
internal_static_AbilityMetaSetKilledState_descriptor,
|
||||||
|
new java.lang.String[] { "Killed", });
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(outer_class_scope)
|
||||||
|
}
|
@ -19,11 +19,11 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
com.google.protobuf.MessageOrBuilder {
|
com.google.protobuf.MessageOrBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
int getOldFightPropMapCount();
|
int getOldFightPropMapCount();
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
boolean containsOldFightPropMap(
|
boolean containsOldFightPropMap(
|
||||||
int key);
|
int key);
|
||||||
@ -34,19 +34,19 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
java.util.Map<java.lang.Integer, java.lang.Float>
|
java.util.Map<java.lang.Integer, java.lang.Float>
|
||||||
getOldFightPropMap();
|
getOldFightPropMap();
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
java.util.Map<java.lang.Integer, java.lang.Float>
|
java.util.Map<java.lang.Integer, java.lang.Float>
|
||||||
getOldFightPropMapMap();
|
getOldFightPropMapMap();
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float getOldFightPropMapOrDefault(
|
float getOldFightPropMapOrDefault(
|
||||||
int key,
|
int key,
|
||||||
float defaultValue);
|
float defaultValue);
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float getOldFightPropMapOrThrow(
|
float getOldFightPropMapOrThrow(
|
||||||
@ -65,11 +65,11 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
int getCurLevel();
|
int getCurLevel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
int getCurFightPropMapCount();
|
int getCurFightPropMapCount();
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
boolean containsCurFightPropMap(
|
boolean containsCurFightPropMap(
|
||||||
int key);
|
int key);
|
||||||
@ -80,19 +80,19 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
java.util.Map<java.lang.Integer, java.lang.Float>
|
java.util.Map<java.lang.Integer, java.lang.Float>
|
||||||
getCurFightPropMap();
|
getCurFightPropMap();
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
java.util.Map<java.lang.Integer, java.lang.Float>
|
java.util.Map<java.lang.Integer, java.lang.Float>
|
||||||
getCurFightPropMapMap();
|
getCurFightPropMapMap();
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float getCurFightPropMapOrDefault(
|
float getCurFightPropMapOrDefault(
|
||||||
int key,
|
int key,
|
||||||
float defaultValue);
|
float defaultValue);
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
float getCurFightPropMapOrThrow(
|
float getCurFightPropMapOrThrow(
|
||||||
@ -177,19 +177,6 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 98: {
|
case 98: {
|
||||||
if (!((mutable_bitField0_ & 0x00000001) != 0)) {
|
|
||||||
oldFightPropMap_ = com.google.protobuf.MapField.newMapField(
|
|
||||||
OldFightPropMapDefaultEntryHolder.defaultEntry);
|
|
||||||
mutable_bitField0_ |= 0x00000001;
|
|
||||||
}
|
|
||||||
com.google.protobuf.MapEntry<java.lang.Integer, java.lang.Float>
|
|
||||||
oldFightPropMap__ = input.readMessage(
|
|
||||||
OldFightPropMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
|
|
||||||
oldFightPropMap_.getMutableMap().put(
|
|
||||||
oldFightPropMap__.getKey(), oldFightPropMap__.getValue());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 106: {
|
|
||||||
if (!((mutable_bitField0_ & 0x00000002) != 0)) {
|
if (!((mutable_bitField0_ & 0x00000002) != 0)) {
|
||||||
curFightPropMap_ = com.google.protobuf.MapField.newMapField(
|
curFightPropMap_ = com.google.protobuf.MapField.newMapField(
|
||||||
CurFightPropMapDefaultEntryHolder.defaultEntry);
|
CurFightPropMapDefaultEntryHolder.defaultEntry);
|
||||||
@ -202,6 +189,19 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
curFightPropMap__.getKey(), curFightPropMap__.getValue());
|
curFightPropMap__.getKey(), curFightPropMap__.getValue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 106: {
|
||||||
|
if (!((mutable_bitField0_ & 0x00000001) != 0)) {
|
||||||
|
oldFightPropMap_ = com.google.protobuf.MapField.newMapField(
|
||||||
|
OldFightPropMapDefaultEntryHolder.defaultEntry);
|
||||||
|
mutable_bitField0_ |= 0x00000001;
|
||||||
|
}
|
||||||
|
com.google.protobuf.MapEntry<java.lang.Integer, java.lang.Float>
|
||||||
|
oldFightPropMap__ = input.readMessage(
|
||||||
|
OldFightPropMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry);
|
||||||
|
oldFightPropMap_.getMutableMap().put(
|
||||||
|
oldFightPropMap__.getKey(), oldFightPropMap__.getValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 112: {
|
case 112: {
|
||||||
|
|
||||||
curLevel_ = input.readUInt32();
|
curLevel_ = input.readUInt32();
|
||||||
@ -236,9 +236,9 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
protected com.google.protobuf.MapField internalGetMapField(
|
protected com.google.protobuf.MapField internalGetMapField(
|
||||||
int number) {
|
int number) {
|
||||||
switch (number) {
|
switch (number) {
|
||||||
case 12:
|
|
||||||
return internalGetOldFightPropMap();
|
|
||||||
case 13:
|
case 13:
|
||||||
|
return internalGetOldFightPropMap();
|
||||||
|
case 12:
|
||||||
return internalGetCurFightPropMap();
|
return internalGetCurFightPropMap();
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
@ -253,7 +253,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
emu.grasscutter.net.proto.AvatarUpgradeRspOuterClass.AvatarUpgradeRsp.class, emu.grasscutter.net.proto.AvatarUpgradeRspOuterClass.AvatarUpgradeRsp.Builder.class);
|
emu.grasscutter.net.proto.AvatarUpgradeRspOuterClass.AvatarUpgradeRsp.class, emu.grasscutter.net.proto.AvatarUpgradeRspOuterClass.AvatarUpgradeRsp.Builder.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int OLD_FIGHT_PROP_MAP_FIELD_NUMBER = 12;
|
public static final int OLD_FIGHT_PROP_MAP_FIELD_NUMBER = 13;
|
||||||
private static final class OldFightPropMapDefaultEntryHolder {
|
private static final class OldFightPropMapDefaultEntryHolder {
|
||||||
static final com.google.protobuf.MapEntry<
|
static final com.google.protobuf.MapEntry<
|
||||||
java.lang.Integer, java.lang.Float> defaultEntry =
|
java.lang.Integer, java.lang.Float> defaultEntry =
|
||||||
@ -280,7 +280,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetOldFightPropMap().getMap().size();
|
return internalGetOldFightPropMap().getMap().size();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
@ -298,7 +298,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return getOldFightPropMapMap();
|
return getOldFightPropMapMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -306,7 +306,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetOldFightPropMap().getMap();
|
return internalGetOldFightPropMap().getMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return map.containsKey(key) ? map.get(key) : defaultValue;
|
return map.containsKey(key) ? map.get(key) : defaultValue;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -356,7 +356,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return curLevel_;
|
return curLevel_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int CUR_FIGHT_PROP_MAP_FIELD_NUMBER = 13;
|
public static final int CUR_FIGHT_PROP_MAP_FIELD_NUMBER = 12;
|
||||||
private static final class CurFightPropMapDefaultEntryHolder {
|
private static final class CurFightPropMapDefaultEntryHolder {
|
||||||
static final com.google.protobuf.MapEntry<
|
static final com.google.protobuf.MapEntry<
|
||||||
java.lang.Integer, java.lang.Float> defaultEntry =
|
java.lang.Integer, java.lang.Float> defaultEntry =
|
||||||
@ -383,7 +383,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetCurFightPropMap().getMap().size();
|
return internalGetCurFightPropMap().getMap().size();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
@ -401,7 +401,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return getCurFightPropMapMap();
|
return getCurFightPropMapMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -409,7 +409,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetCurFightPropMap().getMap();
|
return internalGetCurFightPropMap().getMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -422,7 +422,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return map.containsKey(key) ? map.get(key) : defaultValue;
|
return map.containsKey(key) ? map.get(key) : defaultValue;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -485,14 +485,14 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
com.google.protobuf.GeneratedMessageV3
|
com.google.protobuf.GeneratedMessageV3
|
||||||
.serializeIntegerMapTo(
|
.serializeIntegerMapTo(
|
||||||
output,
|
output,
|
||||||
internalGetOldFightPropMap(),
|
internalGetCurFightPropMap(),
|
||||||
OldFightPropMapDefaultEntryHolder.defaultEntry,
|
CurFightPropMapDefaultEntryHolder.defaultEntry,
|
||||||
12);
|
12);
|
||||||
com.google.protobuf.GeneratedMessageV3
|
com.google.protobuf.GeneratedMessageV3
|
||||||
.serializeIntegerMapTo(
|
.serializeIntegerMapTo(
|
||||||
output,
|
output,
|
||||||
internalGetCurFightPropMap(),
|
internalGetOldFightPropMap(),
|
||||||
CurFightPropMapDefaultEntryHolder.defaultEntry,
|
OldFightPropMapDefaultEntryHolder.defaultEntry,
|
||||||
13);
|
13);
|
||||||
if (curLevel_ != 0) {
|
if (curLevel_ != 0) {
|
||||||
output.writeUInt32(14, curLevel_);
|
output.writeUInt32(14, curLevel_);
|
||||||
@ -518,16 +518,6 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
.computeInt32Size(10, retcode_);
|
.computeInt32Size(10, retcode_);
|
||||||
}
|
}
|
||||||
for (java.util.Map.Entry<java.lang.Integer, java.lang.Float> entry
|
|
||||||
: internalGetOldFightPropMap().getMap().entrySet()) {
|
|
||||||
com.google.protobuf.MapEntry<java.lang.Integer, java.lang.Float>
|
|
||||||
oldFightPropMap__ = OldFightPropMapDefaultEntryHolder.defaultEntry.newBuilderForType()
|
|
||||||
.setKey(entry.getKey())
|
|
||||||
.setValue(entry.getValue())
|
|
||||||
.build();
|
|
||||||
size += com.google.protobuf.CodedOutputStream
|
|
||||||
.computeMessageSize(12, oldFightPropMap__);
|
|
||||||
}
|
|
||||||
for (java.util.Map.Entry<java.lang.Integer, java.lang.Float> entry
|
for (java.util.Map.Entry<java.lang.Integer, java.lang.Float> entry
|
||||||
: internalGetCurFightPropMap().getMap().entrySet()) {
|
: internalGetCurFightPropMap().getMap().entrySet()) {
|
||||||
com.google.protobuf.MapEntry<java.lang.Integer, java.lang.Float>
|
com.google.protobuf.MapEntry<java.lang.Integer, java.lang.Float>
|
||||||
@ -536,7 +526,17 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
.setValue(entry.getValue())
|
.setValue(entry.getValue())
|
||||||
.build();
|
.build();
|
||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
.computeMessageSize(13, curFightPropMap__);
|
.computeMessageSize(12, curFightPropMap__);
|
||||||
|
}
|
||||||
|
for (java.util.Map.Entry<java.lang.Integer, java.lang.Float> entry
|
||||||
|
: internalGetOldFightPropMap().getMap().entrySet()) {
|
||||||
|
com.google.protobuf.MapEntry<java.lang.Integer, java.lang.Float>
|
||||||
|
oldFightPropMap__ = OldFightPropMapDefaultEntryHolder.defaultEntry.newBuilderForType()
|
||||||
|
.setKey(entry.getKey())
|
||||||
|
.setValue(entry.getValue())
|
||||||
|
.build();
|
||||||
|
size += com.google.protobuf.CodedOutputStream
|
||||||
|
.computeMessageSize(13, oldFightPropMap__);
|
||||||
}
|
}
|
||||||
if (curLevel_ != 0) {
|
if (curLevel_ != 0) {
|
||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
@ -713,9 +713,9 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
protected com.google.protobuf.MapField internalGetMapField(
|
protected com.google.protobuf.MapField internalGetMapField(
|
||||||
int number) {
|
int number) {
|
||||||
switch (number) {
|
switch (number) {
|
||||||
case 12:
|
|
||||||
return internalGetOldFightPropMap();
|
|
||||||
case 13:
|
case 13:
|
||||||
|
return internalGetOldFightPropMap();
|
||||||
|
case 12:
|
||||||
return internalGetCurFightPropMap();
|
return internalGetCurFightPropMap();
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
@ -726,9 +726,9 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
protected com.google.protobuf.MapField internalGetMutableMapField(
|
protected com.google.protobuf.MapField internalGetMutableMapField(
|
||||||
int number) {
|
int number) {
|
||||||
switch (number) {
|
switch (number) {
|
||||||
case 12:
|
|
||||||
return internalGetMutableOldFightPropMap();
|
|
||||||
case 13:
|
case 13:
|
||||||
|
return internalGetMutableOldFightPropMap();
|
||||||
|
case 12:
|
||||||
return internalGetMutableCurFightPropMap();
|
return internalGetMutableCurFightPropMap();
|
||||||
default:
|
default:
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
@ -927,7 +927,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetOldFightPropMap().getMap().size();
|
return internalGetOldFightPropMap().getMap().size();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
@ -945,7 +945,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return getOldFightPropMapMap();
|
return getOldFightPropMapMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -953,7 +953,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetOldFightPropMap().getMap();
|
return internalGetOldFightPropMap().getMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -966,7 +966,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return map.containsKey(key) ? map.get(key) : defaultValue;
|
return map.containsKey(key) ? map.get(key) : defaultValue;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -987,7 +987,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public Builder removeOldFightPropMap(
|
public Builder removeOldFightPropMap(
|
||||||
@ -1006,7 +1006,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetMutableOldFightPropMap().getMutableMap();
|
return internalGetMutableOldFightPropMap().getMutableMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
public Builder putOldFightPropMap(
|
public Builder putOldFightPropMap(
|
||||||
int key,
|
int key,
|
||||||
@ -1018,7 +1018,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> old_fight_prop_map = 12;</code>
|
* <code>map<uint32, float> old_fight_prop_map = 13;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public Builder putAllOldFightPropMap(
|
public Builder putAllOldFightPropMap(
|
||||||
@ -1117,7 +1117,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetCurFightPropMap().getMap().size();
|
return internalGetCurFightPropMap().getMap().size();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
@ -1135,7 +1135,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return getCurFightPropMapMap();
|
return getCurFightPropMapMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -1143,7 +1143,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetCurFightPropMap().getMap();
|
return internalGetCurFightPropMap().getMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -1156,7 +1156,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return map.containsKey(key) ? map.get(key) : defaultValue;
|
return map.containsKey(key) ? map.get(key) : defaultValue;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
|
|
||||||
@ -1177,7 +1177,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public Builder removeCurFightPropMap(
|
public Builder removeCurFightPropMap(
|
||||||
@ -1196,7 +1196,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return internalGetMutableCurFightPropMap().getMutableMap();
|
return internalGetMutableCurFightPropMap().getMutableMap();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
public Builder putCurFightPropMap(
|
public Builder putCurFightPropMap(
|
||||||
int key,
|
int key,
|
||||||
@ -1208,7 +1208,7 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>map<uint32, float> cur_fight_prop_map = 13;</code>
|
* <code>map<uint32, float> cur_fight_prop_map = 12;</code>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public Builder putAllCurFightPropMap(
|
public Builder putAllCurFightPropMap(
|
||||||
@ -1357,10 +1357,10 @@ public final class AvatarUpgradeRspOuterClass {
|
|||||||
static {
|
static {
|
||||||
java.lang.String[] descriptorData = {
|
java.lang.String[] descriptorData = {
|
||||||
"\n\026AvatarUpgradeRsp.proto\"\326\002\n\020AvatarUpgra" +
|
"\n\026AvatarUpgradeRsp.proto\"\326\002\n\020AvatarUpgra" +
|
||||||
"deRsp\022B\n\022old_fight_prop_map\030\014 \003(\0132&.Avat" +
|
"deRsp\022B\n\022old_fight_prop_map\030\r \003(\0132&.Avat" +
|
||||||
"arUpgradeRsp.OldFightPropMapEntry\022\023\n\013ava" +
|
"arUpgradeRsp.OldFightPropMapEntry\022\023\n\013ava" +
|
||||||
"tar_guid\030\010 \001(\004\022\021\n\tcur_level\030\016 \001(\r\022B\n\022cur" +
|
"tar_guid\030\010 \001(\004\022\021\n\tcur_level\030\016 \001(\r\022B\n\022cur" +
|
||||||
"_fight_prop_map\030\r \003(\0132&.AvatarUpgradeRsp" +
|
"_fight_prop_map\030\014 \003(\0132&.AvatarUpgradeRsp" +
|
||||||
".CurFightPropMapEntry\022\017\n\007retcode\030\n \001(\005\022\021" +
|
".CurFightPropMapEntry\022\017\n\007retcode\030\n \001(\005\022\021" +
|
||||||
"\n\told_level\030\004 \001(\r\0326\n\024OldFightPropMapEntr" +
|
"\n\told_level\030\004 \001(\r\0326\n\024OldFightPropMapEntr" +
|
||||||
"y\022\013\n\003key\030\001 \001(\r\022\r\n\005value\030\002 \001(\002:\0028\001\0326\n\024Cur" +
|
"y\022\013\n\003key\030\001 \001(\r\022\r\n\005value\030\002 \001(\002:\0028\001\0326\n\024Cur" +
|
||||||
|
@ -224,6 +224,123 @@ public final class ChatInfoOuterClass {
|
|||||||
emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.class, emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.Builder.class);
|
emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.class, emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.Builder.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protobuf enum {@code ChatInfo.SystemHintType}
|
||||||
|
*/
|
||||||
|
public enum SystemHintType
|
||||||
|
implements com.google.protobuf.ProtocolMessageEnum {
|
||||||
|
/**
|
||||||
|
* <code>SYSTEM_HINT_TYPE_CHAT_NONE = 0;</code>
|
||||||
|
*/
|
||||||
|
SYSTEM_HINT_TYPE_CHAT_NONE(0),
|
||||||
|
/**
|
||||||
|
* <code>SYSTEM_HINT_TYPE_CHAT_ENTER_WORLD = 1;</code>
|
||||||
|
*/
|
||||||
|
SYSTEM_HINT_TYPE_CHAT_ENTER_WORLD(1),
|
||||||
|
/**
|
||||||
|
* <code>SYSTEM_HINT_TYPE_CHAT_LEAVE_WORLD = 2;</code>
|
||||||
|
*/
|
||||||
|
SYSTEM_HINT_TYPE_CHAT_LEAVE_WORLD(2),
|
||||||
|
UNRECOGNIZED(-1),
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>SYSTEM_HINT_TYPE_CHAT_NONE = 0;</code>
|
||||||
|
*/
|
||||||
|
public static final int SYSTEM_HINT_TYPE_CHAT_NONE_VALUE = 0;
|
||||||
|
/**
|
||||||
|
* <code>SYSTEM_HINT_TYPE_CHAT_ENTER_WORLD = 1;</code>
|
||||||
|
*/
|
||||||
|
public static final int SYSTEM_HINT_TYPE_CHAT_ENTER_WORLD_VALUE = 1;
|
||||||
|
/**
|
||||||
|
* <code>SYSTEM_HINT_TYPE_CHAT_LEAVE_WORLD = 2;</code>
|
||||||
|
*/
|
||||||
|
public static final int SYSTEM_HINT_TYPE_CHAT_LEAVE_WORLD_VALUE = 2;
|
||||||
|
|
||||||
|
|
||||||
|
public final int getNumber() {
|
||||||
|
if (this == UNRECOGNIZED) {
|
||||||
|
throw new java.lang.IllegalArgumentException(
|
||||||
|
"Can't get the number of an unknown enum value.");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value The numeric wire value of the corresponding enum entry.
|
||||||
|
* @return The enum associated with the given numeric wire value.
|
||||||
|
* @deprecated Use {@link #forNumber(int)} instead.
|
||||||
|
*/
|
||||||
|
@java.lang.Deprecated
|
||||||
|
public static SystemHintType valueOf(int value) {
|
||||||
|
return forNumber(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value The numeric wire value of the corresponding enum entry.
|
||||||
|
* @return The enum associated with the given numeric wire value.
|
||||||
|
*/
|
||||||
|
public static SystemHintType forNumber(int value) {
|
||||||
|
switch (value) {
|
||||||
|
case 0: return SYSTEM_HINT_TYPE_CHAT_NONE;
|
||||||
|
case 1: return SYSTEM_HINT_TYPE_CHAT_ENTER_WORLD;
|
||||||
|
case 2: return SYSTEM_HINT_TYPE_CHAT_LEAVE_WORLD;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.google.protobuf.Internal.EnumLiteMap<SystemHintType>
|
||||||
|
internalGetValueMap() {
|
||||||
|
return internalValueMap;
|
||||||
|
}
|
||||||
|
private static final com.google.protobuf.Internal.EnumLiteMap<
|
||||||
|
SystemHintType> internalValueMap =
|
||||||
|
new com.google.protobuf.Internal.EnumLiteMap<SystemHintType>() {
|
||||||
|
public SystemHintType findValueByNumber(int number) {
|
||||||
|
return SystemHintType.forNumber(number);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public final com.google.protobuf.Descriptors.EnumValueDescriptor
|
||||||
|
getValueDescriptor() {
|
||||||
|
if (this == UNRECOGNIZED) {
|
||||||
|
throw new java.lang.IllegalStateException(
|
||||||
|
"Can't get the descriptor of an unrecognized enum value.");
|
||||||
|
}
|
||||||
|
return getDescriptor().getValues().get(ordinal());
|
||||||
|
}
|
||||||
|
public final com.google.protobuf.Descriptors.EnumDescriptor
|
||||||
|
getDescriptorForType() {
|
||||||
|
return getDescriptor();
|
||||||
|
}
|
||||||
|
public static final com.google.protobuf.Descriptors.EnumDescriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.getDescriptor().getEnumTypes().get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final SystemHintType[] VALUES = values();
|
||||||
|
|
||||||
|
public static SystemHintType valueOf(
|
||||||
|
com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
|
||||||
|
if (desc.getType() != getDescriptor()) {
|
||||||
|
throw new java.lang.IllegalArgumentException(
|
||||||
|
"EnumValueDescriptor is not for this type.");
|
||||||
|
}
|
||||||
|
if (desc.getIndex() == -1) {
|
||||||
|
return UNRECOGNIZED;
|
||||||
|
}
|
||||||
|
return VALUES[desc.getIndex()];
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private SystemHintType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(enum_scope:ChatInfo.SystemHintType)
|
||||||
|
}
|
||||||
|
|
||||||
public interface SystemHintOrBuilder extends
|
public interface SystemHintOrBuilder extends
|
||||||
// @@protoc_insertion_point(interface_extends:ChatInfo.SystemHint)
|
// @@protoc_insertion_point(interface_extends:ChatInfo.SystemHint)
|
||||||
com.google.protobuf.MessageOrBuilder {
|
com.google.protobuf.MessageOrBuilder {
|
||||||
@ -1907,13 +2024,16 @@ public final class ChatInfoOuterClass {
|
|||||||
descriptor;
|
descriptor;
|
||||||
static {
|
static {
|
||||||
java.lang.String[] descriptorData = {
|
java.lang.String[] descriptorData = {
|
||||||
"\n\016ChatInfo.proto\"\317\001\n\010ChatInfo\022\014\n\004time\030\007 " +
|
"\n\016ChatInfo.proto\"\317\002\n\010ChatInfo\022\014\n\004time\030\007 " +
|
||||||
"\001(\r\022\016\n\006to_uid\030\006 \001(\r\022\017\n\007is_read\030\004 \001(\010\022\013\n\003" +
|
"\001(\r\022\016\n\006to_uid\030\006 \001(\r\022\017\n\007is_read\030\004 \001(\010\022\013\n\003" +
|
||||||
"uid\030\005 \001(\r\022\020\n\010sequence\030\014 \001(\r\022\017\n\004text\030\230\003 \001" +
|
"uid\030\005 \001(\r\022\020\n\010sequence\030\014 \001(\r\022\017\n\004text\030\230\003 \001" +
|
||||||
"(\tH\000\022\017\n\004icon\030\234\n \001(\rH\000\022,\n\013system_hint\030\246\001 " +
|
"(\tH\000\022\017\n\004icon\030\234\n \001(\rH\000\022,\n\013system_hint\030\246\001 " +
|
||||||
"\001(\0132\024.ChatInfo.SystemHintH\000\032\032\n\nSystemHin" +
|
"\001(\0132\024.ChatInfo.SystemHintH\000\032\032\n\nSystemHin" +
|
||||||
"t\022\014\n\004type\030\r \001(\rB\t\n\007contentB\033\n\031emu.grassc" +
|
"t\022\014\n\004type\030\r \001(\r\"~\n\016SystemHintType\022\036\n\032SYS" +
|
||||||
"utter.net.protob\006proto3"
|
"TEM_HINT_TYPE_CHAT_NONE\020\000\022%\n!SYSTEM_HINT" +
|
||||||
|
"_TYPE_CHAT_ENTER_WORLD\020\001\022%\n!SYSTEM_HINT_" +
|
||||||
|
"TYPE_CHAT_LEAVE_WORLD\020\002B\t\n\007contentB\033\n\031em" +
|
||||||
|
"u.grasscutter.net.protob\006proto3"
|
||||||
};
|
};
|
||||||
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
descriptor = com.google.protobuf.Descriptors.FileDescriptor
|
||||||
.internalBuildGeneratedFileFrom(descriptorData,
|
.internalBuildGeneratedFileFrom(descriptorData,
|
||||||
|
@ -8,7 +8,7 @@ import emu.grasscutter.auth.*;
|
|||||||
import emu.grasscutter.command.*;
|
import emu.grasscutter.command.*;
|
||||||
import emu.grasscutter.config.ConfigContainer;
|
import emu.grasscutter.config.ConfigContainer;
|
||||||
import emu.grasscutter.data.ResourceLoader;
|
import emu.grasscutter.data.ResourceLoader;
|
||||||
import emu.grasscutter.database.DatabaseManager;
|
import emu.grasscutter.database.*;
|
||||||
import emu.grasscutter.plugin.PluginManager;
|
import emu.grasscutter.plugin.PluginManager;
|
||||||
import emu.grasscutter.plugin.api.ServerHelper;
|
import emu.grasscutter.plugin.api.ServerHelper;
|
||||||
import emu.grasscutter.server.dispatch.DispatchServer;
|
import emu.grasscutter.server.dispatch.DispatchServer;
|
||||||
@ -183,6 +183,25 @@ public final class Grasscutter {
|
|||||||
private static void onShutdown() {
|
private static void onShutdown() {
|
||||||
// Disable all plugins.
|
// Disable all plugins.
|
||||||
if (pluginManager != null) pluginManager.disablePlugins();
|
if (pluginManager != null) pluginManager.disablePlugins();
|
||||||
|
// Shutdown the game server.
|
||||||
|
if (gameServer != null) gameServer.onServerShutdown();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Wait for Grasscutter's thread pool to finish.
|
||||||
|
var executor = Grasscutter.getThreadPool();
|
||||||
|
executor.shutdown();
|
||||||
|
if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for database operations to finish.
|
||||||
|
var dbExecutor = DatabaseHelper.getEventExecutor();
|
||||||
|
dbExecutor.shutdown();
|
||||||
|
if (!dbExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||||
|
dbExecutor.shutdownNow();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5,8 +5,7 @@ import static emu.grasscutter.config.Configuration.SERVER;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.*;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ import lombok.val;
|
|||||||
label = "cutscene",
|
label = "cutscene",
|
||||||
aliases = {"c"},
|
aliases = {"c"},
|
||||||
usage = {"[<cutsceneId>]"},
|
usage = {"[<cutsceneId>]"},
|
||||||
permission = "player.group",
|
permission = "player.cutscene",
|
||||||
permissionTargeted = "player.group.others")
|
permissionTargeted = "player.cutscene.others")
|
||||||
public final class CutsceneCommand implements CommandHandler {
|
public final class CutsceneCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -12,7 +12,7 @@ import java.util.Map;
|
|||||||
@Command(
|
@Command(
|
||||||
label = "list",
|
label = "list",
|
||||||
aliases = {"players"},
|
aliases = {"players"},
|
||||||
usage = {"[<UID>]"},
|
usage = {"[uid]"},
|
||||||
targetRequirement = Command.TargetRequirement.NONE)
|
targetRequirement = Command.TargetRequirement.NONE)
|
||||||
public final class ListCommand implements CommandHandler {
|
public final class ListCommand implements CommandHandler {
|
||||||
|
|
||||||
|
@ -2,23 +2,23 @@ package emu.grasscutter.command.commands;
|
|||||||
|
|
||||||
import static emu.grasscutter.utils.lang.Language.translate;
|
import static emu.grasscutter.utils.lang.Language.translate;
|
||||||
|
|
||||||
import emu.grasscutter.command.Command;
|
import emu.grasscutter.command.*;
|
||||||
import emu.grasscutter.command.CommandHandler;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
label = "quest",
|
label = "quest",
|
||||||
aliases = {"q"},
|
aliases = {"q"},
|
||||||
usage = {"(add|finish) [<questId>]"},
|
usage = {"(add|finish|running|talking|debug|triggers|grouptriggers) [<questId>]", "dungeons"},
|
||||||
permission = "player.quest",
|
permission = "player.quest",
|
||||||
permissionTargeted = "player.quest.others")
|
permissionTargeted = "player.quest.others")
|
||||||
public final class QuestCommand implements CommandHandler {
|
public final class QuestCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||||
if (args.size() != 2) {
|
if (args.size() != 2 || (args.size() == 1 && !args.get(0).toLowerCase().equals("dungeons"))) {
|
||||||
sendUsageMessage(sender);
|
sendUsageMessage(sender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -112,7 +112,7 @@ public final class QuestCommand implements CommandHandler {
|
|||||||
var shouldAdd = !loggedQuests.contains(questId);
|
var shouldAdd = !loggedQuests.contains(questId);
|
||||||
|
|
||||||
if (shouldAdd) loggedQuests.add(questId);
|
if (shouldAdd) loggedQuests.add(questId);
|
||||||
else loggedQuests.remove(questId);
|
else loggedQuests.remove(loggedQuests.indexOf(questId));
|
||||||
|
|
||||||
CommandHandler.sendMessage(
|
CommandHandler.sendMessage(
|
||||||
sender,
|
sender,
|
||||||
@ -131,6 +131,22 @@ public final class QuestCommand implements CommandHandler {
|
|||||||
"Triggers registered for %s: %s."
|
"Triggers registered for %s: %s."
|
||||||
.formatted(questId, String.join(", ", quest.getTriggers().keySet())));
|
.formatted(questId, String.join(", ", quest.getTriggers().keySet())));
|
||||||
}
|
}
|
||||||
|
case "grouptriggers" -> {
|
||||||
|
var scene = targetPlayer.getScene();
|
||||||
|
var scriptManager = scene.getScriptManager();
|
||||||
|
|
||||||
|
var group = scriptManager.getGroupById(questId);
|
||||||
|
if (group == null) {
|
||||||
|
CommandHandler.sendMessage(sender, "The group does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandHandler.sendMessage(
|
||||||
|
sender,
|
||||||
|
group.triggers.entrySet().stream()
|
||||||
|
.map(entry -> "%s: %s".formatted(entry.getKey(), entry.getValue()))
|
||||||
|
.collect(Collectors.joining(", ")));
|
||||||
|
}
|
||||||
default -> this.sendUsageMessage(sender);
|
default -> this.sendUsageMessage(sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
@ -107,6 +108,7 @@ public final class SetPropCommand implements CommandHandler {
|
|||||||
case "on", "true" -> 1;
|
case "on", "true" -> 1;
|
||||||
case "off", "false" -> 0;
|
case "off", "false" -> 0;
|
||||||
case "toggle" -> -1;
|
case "toggle" -> -1;
|
||||||
|
case "all" -> -2;
|
||||||
default -> Integer.parseInt(valueStr);
|
default -> Integer.parseInt(valueStr);
|
||||||
};
|
};
|
||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
@ -126,7 +128,7 @@ public final class SetPropCommand implements CommandHandler {
|
|||||||
sender, targetPlayer, prop.pseudoProp, value);
|
sender, targetPlayer, prop.pseudoProp, value);
|
||||||
case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1);
|
case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1);
|
||||||
case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0);
|
case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0);
|
||||||
case UNLOCK_MAP -> unlockMap(targetPlayer);
|
case UNLOCK_MAP -> unlockMap(targetPlayer, value);
|
||||||
default -> targetPlayer.setProperty(prop.prop, value);
|
default -> targetPlayer.setProperty(prop.prop, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -217,13 +219,30 @@ public final class SetPropCommand implements CommandHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean unlockMap(Player targetPlayer) {
|
private boolean unlockMap(Player targetPlayer, int value) {
|
||||||
// Unlock.
|
// Unlock.
|
||||||
GameData.getScenePointsPerScene()
|
GameData.getScenePointsPerScene()
|
||||||
.forEach(
|
.forEach(
|
||||||
(sceneId, scenePoints) -> {
|
(sceneId, scenePoints) -> {
|
||||||
// Unlock trans points.
|
if (value == -2) {
|
||||||
targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints);
|
// Unlock trans points.
|
||||||
|
targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints);
|
||||||
|
} else {
|
||||||
|
var scenePointsBackup = new CopyOnWriteArrayList<>(scenePoints);
|
||||||
|
for (var p : scenePointsBackup) {
|
||||||
|
var scenePointEentry = GameData.getScenePointEntryById(sceneId, p);
|
||||||
|
var pointData = scenePointEentry.getPointData();
|
||||||
|
|
||||||
|
boolean forbidSimpleUnlock = pointData.isForbidSimpleUnlock();
|
||||||
|
boolean sceneBuildingPointLocked =
|
||||||
|
pointData.getType().equals("SceneBuildingPoint") && !pointData.isUnlocked();
|
||||||
|
|
||||||
|
if (forbidSimpleUnlock || sceneBuildingPointLocked) scenePointsBackup.remove(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock trans points.
|
||||||
|
targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePointsBackup);
|
||||||
|
}
|
||||||
|
|
||||||
// Unlock map areas.
|
// Unlock map areas.
|
||||||
targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas);
|
targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas);
|
||||||
|
@ -14,8 +14,8 @@ import lombok.val;
|
|||||||
label = "sound",
|
label = "sound",
|
||||||
aliases = {"s", "audio"},
|
aliases = {"s", "audio"},
|
||||||
usage = {"[<audioname>] [<x><y><z>]"},
|
usage = {"[<audioname>] [<x><y><z>]"},
|
||||||
permission = "player.group",
|
permission = "player.sound",
|
||||||
permissionTargeted = "player.group.others")
|
permissionTargeted = "player.sound.others")
|
||||||
public final class SoundCommand implements CommandHandler {
|
public final class SoundCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,19 +17,21 @@ import static emu.grasscutter.Grasscutter.*;
|
|||||||
public class ConfigContainer {
|
public class ConfigContainer {
|
||||||
/*
|
/*
|
||||||
* Configuration changes:
|
* Configuration changes:
|
||||||
* Version 5 - 'questing' has been changed from a boolean
|
* Version 5 - 'questing' has been changed from a boolean
|
||||||
* to a container of options ('questOptions').
|
* to a container of options ('questOptions').
|
||||||
* This field will be removed in future versions.
|
* This field will be removed in future versions.
|
||||||
* Version 6 - 'questing' has been fully replaced with 'questOptions'.
|
* Version 6 - 'questing' has been fully replaced with 'questOptions'.
|
||||||
* The field for 'legacyResources' has been removed.
|
* The field for 'legacyResources' has been removed.
|
||||||
* Version 7 - 'regionKey' is being added for authentication
|
* Version 7 - 'regionKey' is being added for authentication
|
||||||
* with the new dispatch server.
|
* with the new dispatch server.
|
||||||
* Version 8 - 'server' is being added for enforcing handbook server
|
* Version 8 - 'server' is being added for enforcing handbook server
|
||||||
* addresses.
|
* addresses.
|
||||||
* Version 9 - 'limits' was added for handbook requests.
|
* Version 9 - 'limits' was added for handbook requests.
|
||||||
|
* Version 10 - 'trialCostumes' was added for enabling costumes
|
||||||
|
* on trial avatars.
|
||||||
*/
|
*/
|
||||||
private static int version() {
|
private static int version() {
|
||||||
return 9;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,6 +257,8 @@ public class ConfigContainer {
|
|||||||
public boolean staminaUsage = true;
|
public boolean staminaUsage = true;
|
||||||
public boolean energyUsage = true;
|
public boolean energyUsage = true;
|
||||||
public boolean fishhookTeleport = true;
|
public boolean fishhookTeleport = true;
|
||||||
|
public boolean trialCostumes = false;
|
||||||
|
|
||||||
@SerializedName(value = "questing", alternate = "questOptions")
|
@SerializedName(value = "questing", alternate = "questOptions")
|
||||||
public Questing questing = new Questing();
|
public Questing questing = new Questing();
|
||||||
public ResinOptions resinOptions = new ResinOptions();
|
public ResinOptions resinOptions = new ResinOptions();
|
||||||
|
@ -37,8 +37,11 @@ import emu.grasscutter.data.excels.world.WeatherData;
|
|||||||
import emu.grasscutter.data.excels.world.WorldAreaData;
|
import emu.grasscutter.data.excels.world.WorldAreaData;
|
||||||
import emu.grasscutter.data.excels.world.WorldLevelData;
|
import emu.grasscutter.data.excels.world.WorldLevelData;
|
||||||
import emu.grasscutter.data.server.ActivityCondGroup;
|
import emu.grasscutter.data.server.ActivityCondGroup;
|
||||||
|
import emu.grasscutter.data.server.DropSubfieldMapping;
|
||||||
|
import emu.grasscutter.data.server.DropTableExcelConfigData;
|
||||||
import emu.grasscutter.data.server.GadgetMapping;
|
import emu.grasscutter.data.server.GadgetMapping;
|
||||||
import emu.grasscutter.data.server.MonsterMapping;
|
import emu.grasscutter.data.server.MonsterMapping;
|
||||||
|
import emu.grasscutter.data.server.SubfieldMapping;
|
||||||
import emu.grasscutter.game.dungeons.DungeonDropEntry;
|
import emu.grasscutter.game.dungeons.DungeonDropEntry;
|
||||||
import emu.grasscutter.game.quest.QuestEncryptionKey;
|
import emu.grasscutter.game.quest.QuestEncryptionKey;
|
||||||
import emu.grasscutter.game.quest.RewindData;
|
import emu.grasscutter.game.quest.RewindData;
|
||||||
@ -451,6 +454,18 @@ public final class GameData {
|
|||||||
private static final Int2ObjectMap<GadgetMapping> gadgetMappingMap =
|
private static final Int2ObjectMap<GadgetMapping> gadgetMappingMap =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Int2ObjectMap<SubfieldMapping> subfieldMappingMap =
|
||||||
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Int2ObjectMap<DropSubfieldMapping> dropSubfieldMappingMap =
|
||||||
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static final Int2ObjectMap<DropTableExcelConfigData> dropTableExcelConfigDataMap =
|
||||||
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static final Int2ObjectMap<MonsterMapping> monsterMappingMap =
|
private static final Int2ObjectMap<MonsterMapping> monsterMappingMap =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
@ -116,6 +116,7 @@ public final class ResourceLoader {
|
|||||||
loadConfigLevelEntityData();
|
loadConfigLevelEntityData();
|
||||||
loadQuestShareConfig();
|
loadQuestShareConfig();
|
||||||
loadGadgetMappings();
|
loadGadgetMappings();
|
||||||
|
loadSubfieldMappings();
|
||||||
loadMonsterMappings();
|
loadMonsterMappings();
|
||||||
loadActivityCondGroups();
|
loadActivityCondGroups();
|
||||||
loadGroupReplacements();
|
loadGroupReplacements();
|
||||||
@ -805,6 +806,51 @@ public final class ResourceLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void loadSubfieldMappings() {
|
||||||
|
try {
|
||||||
|
val subfieldMap = GameData.getSubfieldMappingMap();
|
||||||
|
try {
|
||||||
|
JsonUtils.loadToList(getResourcePath("Server/SubfieldMapping.json"), SubfieldMapping.class)
|
||||||
|
.forEach(entry -> subfieldMap.put(entry.getEntityId(), entry));
|
||||||
|
;
|
||||||
|
} catch (IOException | NullPointerException ignored) {
|
||||||
|
}
|
||||||
|
Grasscutter.getLogger().debug("Loaded {} subfield mappings.", subfieldMap.size());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().error("Unable to load subfield mappings.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val dropSubfieldMap = GameData.getDropSubfieldMappingMap();
|
||||||
|
try {
|
||||||
|
JsonUtils.loadToList(
|
||||||
|
getResourcePath("Server/DropSubfieldMapping.json"), DropSubfieldMapping.class)
|
||||||
|
.forEach(entry -> dropSubfieldMap.put(entry.getDropId(), entry));
|
||||||
|
;
|
||||||
|
} catch (IOException | NullPointerException ignored) {
|
||||||
|
}
|
||||||
|
Grasscutter.getLogger().debug("Loaded {} drop subfield mappings.", dropSubfieldMap.size());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().error("Unable to load drop subfield mappings.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val dropTableExcelConfigDataMap = GameData.getDropTableExcelConfigDataMap();
|
||||||
|
try {
|
||||||
|
JsonUtils.loadToList(
|
||||||
|
getResourcePath("Server/DropTableExcelConfigData.json"),
|
||||||
|
DropTableExcelConfigData.class)
|
||||||
|
.forEach(entry -> dropTableExcelConfigDataMap.put(entry.getId(), entry));
|
||||||
|
;
|
||||||
|
} catch (IOException | NullPointerException ignored) {
|
||||||
|
}
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.debug("Loaded {} drop table configs.", dropTableExcelConfigDataMap.size());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().error("Unable to load drop table config data.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void loadMonsterMappings() {
|
private static void loadMonsterMappings() {
|
||||||
try {
|
try {
|
||||||
var monsterMap = GameData.getMonsterMappingMap();
|
var monsterMap = GameData.getMonsterMappingMap();
|
||||||
|
@ -87,7 +87,10 @@ public class AbilityData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeModifiers() {
|
private void initializeModifiers() {
|
||||||
if (modifiers == null) return;
|
if (modifiers == null) {
|
||||||
|
this.modifiers = new HashMap<>();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var _modifiers =
|
var _modifiers =
|
||||||
modifiers.entrySet().stream()
|
modifiers.entrySet().stream()
|
||||||
|
@ -323,9 +323,28 @@ public class AbilityModifier implements Serializable {
|
|||||||
|
|
||||||
public int skillID;
|
public int skillID;
|
||||||
|
|
||||||
|
public AbilityModifierAction[] actions;
|
||||||
|
public AbilityModifierAction[] successActions;
|
||||||
|
public AbilityModifierAction[] failActions;
|
||||||
|
|
||||||
|
public DropType dropType = DropType.LevelControl;
|
||||||
|
public DynamicFloat baseEnergy;
|
||||||
|
public DynamicFloat ratio = DynamicFloat.ONE;
|
||||||
|
public int configID;
|
||||||
|
|
||||||
|
public DynamicFloat valueRangeMin;
|
||||||
|
public DynamicFloat valueRangeMax;
|
||||||
|
public String overrideMapKey;
|
||||||
|
|
||||||
public int param1;
|
public int param1;
|
||||||
public int param2;
|
public int param2;
|
||||||
public int param3;
|
public int param3;
|
||||||
|
|
||||||
|
public enum DropType {
|
||||||
|
LevelControl,
|
||||||
|
BigWorldOnly,
|
||||||
|
ForceDrop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following should be implemented into DynamicFloat if older resource formats need to be
|
// The following should be implemented into DynamicFloat if older resource formats need to be
|
||||||
|
@ -11,4 +11,6 @@ public class ConfigLevelEntity {
|
|||||||
@Getter private List<ConfigAbilityData> avatarAbilities;
|
@Getter private List<ConfigAbilityData> avatarAbilities;
|
||||||
@Getter private List<ConfigAbilityData> teamAbilities;
|
@Getter private List<ConfigAbilityData> teamAbilities;
|
||||||
@Getter private List<Integer> preloadMonsterEntityIDs;
|
@Getter private List<Integer> preloadMonsterEntityIDs;
|
||||||
|
|
||||||
|
@Getter private String dropElemControlType;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ public final class PointData {
|
|||||||
@Getter private Position pos;
|
@Getter private Position pos;
|
||||||
@Getter private Position rot;
|
@Getter private Position rot;
|
||||||
@Getter private Position size;
|
@Getter private Position size;
|
||||||
|
@Getter private boolean forbidSimpleUnlock;
|
||||||
|
@Getter private boolean unlocked;
|
||||||
|
|
||||||
@SerializedName(
|
@SerializedName(
|
||||||
value = "dungeonIds",
|
value = "dungeonIds",
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package emu.grasscutter.data.excels;
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.*;
|
||||||
import emu.grasscutter.data.ResourceType;
|
|
||||||
import emu.grasscutter.game.talk.TalkExec;
|
import emu.grasscutter.game.talk.TalkExec;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Data;
|
import lombok.*;
|
||||||
import lombok.EqualsAndHashCode;
|
|
||||||
|
|
||||||
@ResourceType(name = "TalkExcelConfigData.json")
|
@ResourceType(name = "TalkExcelConfigData.json")
|
||||||
@EqualsAndHashCode(callSuper = false)
|
@EqualsAndHashCode(callSuper = false)
|
||||||
@ -38,6 +36,11 @@ public final class TalkConfigData extends GameResource {
|
|||||||
this.finishExec == null
|
this.finishExec == null
|
||||||
? List.of()
|
? List.of()
|
||||||
: this.finishExec.stream().filter(x -> x.getType() != null).toList();
|
: this.finishExec.stream().filter(x -> x.getType() != null).toList();
|
||||||
|
|
||||||
|
if (this.questId <= 0) {
|
||||||
|
var id = String.valueOf(this.getId());
|
||||||
|
this.questId = Integer.parseInt(id.length() < 5 ? "0" : id.substring(0, 3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@ -32,6 +32,7 @@ public class DungeonData extends GameResource {
|
|||||||
@Getter private int passRewardPreviewID;
|
@Getter private int passRewardPreviewID;
|
||||||
@Getter private int statueCostID;
|
@Getter private int statueCostID;
|
||||||
@Getter private int statueCostCount;
|
@Getter private int statueCostCount;
|
||||||
|
@Getter private int statueDrop;
|
||||||
|
|
||||||
// not part of DungeonExcelConfigData
|
// not part of DungeonExcelConfigData
|
||||||
@Getter private RewardPreviewData rewardPreviewData;
|
@Getter private RewardPreviewData rewardPreviewData;
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package emu.grasscutter.data.server;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public final class DropSubfieldMapping {
|
||||||
|
private int dropId;
|
||||||
|
private int levelLimit;
|
||||||
|
private int itemId;
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package emu.grasscutter.data.server;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public final class DropTableExcelConfigData {
|
||||||
|
private int id;
|
||||||
|
private int randomType;
|
||||||
|
private int dropLevel;
|
||||||
|
private DropVectorEntry[] dropVec;
|
||||||
|
private int nodeType;
|
||||||
|
private boolean fallToGround;
|
||||||
|
private int sourceType;
|
||||||
|
private int everydayLimit;
|
||||||
|
private int historyLimit;
|
||||||
|
private int activityLimit;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class DropVectorEntry {
|
||||||
|
private int itemId;
|
||||||
|
private String countRange;
|
||||||
|
private int weight;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package emu.grasscutter.data.server;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public final class SubfieldMapping {
|
||||||
|
private int entityId;
|
||||||
|
private SubfieldMappingEntry[] subfields;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class SubfieldMappingEntry {
|
||||||
|
private String subfieldName;
|
||||||
|
private int drop_id;
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,9 @@ package emu.grasscutter.database;
|
|||||||
|
|
||||||
import static com.mongodb.client.model.Filters.eq;
|
import static com.mongodb.client.model.Filters.eq;
|
||||||
|
|
||||||
import dev.morphia.query.FindOptions;
|
import dev.morphia.query.*;
|
||||||
import dev.morphia.query.Sort;
|
|
||||||
import dev.morphia.query.experimental.filters.Filters;
|
import dev.morphia.query.experimental.filters.Filters;
|
||||||
import emu.grasscutter.GameConstants;
|
import emu.grasscutter.*;
|
||||||
import emu.grasscutter.Grasscutter;
|
|
||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import emu.grasscutter.game.achievement.Achievements;
|
import emu.grasscutter.game.achievement.Achievements;
|
||||||
import emu.grasscutter.game.activity.PlayerActivityData;
|
import emu.grasscutter.game.activity.PlayerActivityData;
|
||||||
@ -26,8 +24,10 @@ import io.netty.util.concurrent.FastThreadLocalThread;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public final class DatabaseHelper {
|
public final class DatabaseHelper {
|
||||||
|
@Getter
|
||||||
private static final ExecutorService eventExecutor =
|
private static final ExecutorService eventExecutor =
|
||||||
new ThreadPoolExecutor(
|
new ThreadPoolExecutor(
|
||||||
6,
|
6,
|
||||||
|
@ -30,30 +30,50 @@ public class AbilityLocalIdGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initializeActionLocalIds(
|
public void initializeActionLocalIds(
|
||||||
AbilityModifierAction[] actions, Map<Integer, AbilityModifierAction> localIdToAction) {
|
AbilityModifierAction actions[], Map<Integer, AbilityModifierAction> localIdToAction) {
|
||||||
|
this.initializeActionLocalIds(actions, localIdToAction, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initializeActionLocalIds(
|
||||||
|
AbilityModifierAction[] actions,
|
||||||
|
Map<Integer, AbilityModifierAction> localIdToAction,
|
||||||
|
boolean preserveActionIndex) {
|
||||||
if (actions == null) return;
|
if (actions == null) return;
|
||||||
actionIndex = 0;
|
if (!preserveActionIndex) this.actionIndex = 0;
|
||||||
for (AbilityModifierAction action : actions) {
|
for (int i = 0; i < actions.length; i++) {
|
||||||
actionIndex++;
|
this.actionIndex++;
|
||||||
long id = GetLocalId();
|
|
||||||
localIdToAction.put((int) id, action);
|
var id = GetLocalId();
|
||||||
|
localIdToAction.put((int) id, actions[i]);
|
||||||
|
|
||||||
|
if (actions[i].actions != null)
|
||||||
|
this.initializeActionLocalIds(actions[i].actions, localIdToAction, true);
|
||||||
|
else {
|
||||||
|
if (actions[i].successActions != null)
|
||||||
|
this.initializeActionLocalIds(
|
||||||
|
actions[i].successActions,
|
||||||
|
localIdToAction,
|
||||||
|
true); // Need to check this specific order
|
||||||
|
if (actions[i].failActions != null)
|
||||||
|
this.initializeActionLocalIds(actions[i].failActions, localIdToAction, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actionIndex = 0;
|
if (!preserveActionIndex) actionIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initializeMixinsLocalIds(
|
public void initializeMixinsLocalIds(
|
||||||
AbilityMixinData[] mixins, Map<Integer, AbilityMixinData> localIdToAction) {
|
AbilityMixinData[] mixins, Map<Integer, AbilityMixinData> localIdToAction) {
|
||||||
if (mixins == null) return;
|
if (mixins == null) return;
|
||||||
mixinIndex = 0;
|
this.mixinIndex = 0;
|
||||||
for (AbilityMixinData mixin : mixins) {
|
for (var mixin : mixins) {
|
||||||
long id = GetLocalId();
|
var id = GetLocalId();
|
||||||
localIdToAction.put((int) id, mixin);
|
localIdToAction.put((int) id, mixin);
|
||||||
|
|
||||||
mixinIndex++;
|
this.mixinIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mixinIndex = 0;
|
this.mixinIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetLocalId() {
|
public long GetLocalId() {
|
||||||
|
@ -9,10 +9,12 @@ import emu.grasscutter.game.ability.actions.*;
|
|||||||
import emu.grasscutter.game.ability.mixins.*;
|
import emu.grasscutter.game.ability.mixins.*;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
import emu.grasscutter.game.player.*;
|
import emu.grasscutter.game.player.*;
|
||||||
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
||||||
import emu.grasscutter.net.proto.AbilityMetaAddAbilityOuterClass.AbilityMetaAddAbility;
|
import emu.grasscutter.net.proto.AbilityMetaAddAbilityOuterClass.AbilityMetaAddAbility;
|
||||||
import emu.grasscutter.net.proto.AbilityMetaModifierChangeOuterClass.AbilityMetaModifierChange;
|
import emu.grasscutter.net.proto.AbilityMetaModifierChangeOuterClass.AbilityMetaModifierChange;
|
||||||
import emu.grasscutter.net.proto.AbilityMetaReInitOverrideMapOuterClass.AbilityMetaReInitOverrideMap;
|
import emu.grasscutter.net.proto.AbilityMetaReInitOverrideMapOuterClass.AbilityMetaReInitOverrideMap;
|
||||||
|
import emu.grasscutter.net.proto.AbilityMetaSetKilledStateOuterClass.AbilityMetaSetKilledState;
|
||||||
import emu.grasscutter.net.proto.AbilityScalarTypeOuterClass.AbilityScalarType;
|
import emu.grasscutter.net.proto.AbilityScalarTypeOuterClass.AbilityScalarType;
|
||||||
import emu.grasscutter.net.proto.AbilityScalarValueEntryOuterClass.AbilityScalarValueEntry;
|
import emu.grasscutter.net.proto.AbilityScalarValueEntryOuterClass.AbilityScalarValueEntry;
|
||||||
import emu.grasscutter.net.proto.ModifierActionOuterClass.ModifierAction;
|
import emu.grasscutter.net.proto.ModifierActionOuterClass.ModifierAction;
|
||||||
@ -174,6 +176,7 @@ public final class AbilityManager extends BasePlayerManager {
|
|||||||
case ABILITY_INVOKE_ARGUMENT_META_MODIFIER_DURABILITY_CHANGE -> this
|
case ABILITY_INVOKE_ARGUMENT_META_MODIFIER_DURABILITY_CHANGE -> this
|
||||||
.handleModifierDurabilityChange(invoke);
|
.handleModifierDurabilityChange(invoke);
|
||||||
case ABILITY_INVOKE_ARGUMENT_META_ADD_NEW_ABILITY -> this.handleAddNewAbility(invoke);
|
case ABILITY_INVOKE_ARGUMENT_META_ADD_NEW_ABILITY -> this.handleAddNewAbility(invoke);
|
||||||
|
case ABILITY_INVOKE_ARGUMENT_META_SET_KILLED_SETATE -> this.handleKillState(invoke);
|
||||||
default -> {}
|
default -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,6 +538,25 @@ public final class AbilityManager extends BasePlayerManager {
|
|||||||
entity.getInstancedAbilities().size());
|
entity.getInstancedAbilities().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleKillState(AbilityInvokeEntry invoke) throws InvalidProtocolBufferException {
|
||||||
|
var scene = this.getPlayer().getScene();
|
||||||
|
var entity = scene.getEntityById(invoke.getEntityId());
|
||||||
|
if (entity == null) {
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.trace("Entity of ID {} was not found in the scene.", invoke.getEntityId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var killState = AbilityMetaSetKilledState.parseFrom(invoke.getAbilityData());
|
||||||
|
if (killState.getKilled()) {
|
||||||
|
scene.killEntity(entity);
|
||||||
|
} else if (!entity.isAlive()) {
|
||||||
|
entity.setFightProperty(
|
||||||
|
FightProperty.FIGHT_PROP_CUR_HP,
|
||||||
|
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addAbilityToEntity(GameEntity entity, String name) {
|
public void addAbilityToEntity(GameEntity entity, String name) {
|
||||||
AbilityData data = GameData.getAbilityData(name);
|
AbilityData data = GameData.getAbilityData(name);
|
||||||
if (data != null) addAbilityToEntity(entity, data);
|
if (data != null) addAbilityToEntity(entity, data);
|
||||||
|
@ -3,7 +3,7 @@ package emu.grasscutter.game.ability.actions;
|
|||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||||
import emu.grasscutter.game.ability.Ability;
|
import emu.grasscutter.game.ability.Ability;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.*;
|
||||||
|
|
||||||
@AbilityAction(AbilityModifierAction.Type.ExecuteGadgetLua)
|
@AbilityAction(AbilityModifierAction.Type.ExecuteGadgetLua)
|
||||||
public class ActionExecuteGadgetLua extends AbilityActionHandler {
|
public class ActionExecuteGadgetLua extends AbilityActionHandler {
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
package emu.grasscutter.game.ability.actions;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||||
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction.DropType;
|
||||||
|
import emu.grasscutter.data.binout.config.ConfigLevelEntity;
|
||||||
|
import emu.grasscutter.game.ability.Ability;
|
||||||
|
import emu.grasscutter.game.entity.EntityAvatar;
|
||||||
|
import emu.grasscutter.game.entity.EntityItem;
|
||||||
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
|
import emu.grasscutter.game.props.SceneType;
|
||||||
|
import emu.grasscutter.game.world.Position;
|
||||||
|
import emu.grasscutter.net.proto.AbilityActionGenerateElemBallOuterClass.AbilityActionGenerateElemBall;
|
||||||
|
|
||||||
|
@AbilityAction(AbilityModifierAction.Type.GenerateElemBall)
|
||||||
|
public final class ActionGenerateElemBall extends AbilityActionHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(
|
||||||
|
Ability ability, AbilityModifierAction action, ByteString abilityData, GameEntity target) {
|
||||||
|
GameEntity owner = ability.getOwner();
|
||||||
|
|
||||||
|
AbilityActionGenerateElemBall generateElemBall;
|
||||||
|
try {
|
||||||
|
generateElemBall = AbilityActionGenerateElemBall.parseFrom(abilityData);
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we should allow elem ball generation
|
||||||
|
if (action.dropType == DropType.LevelControl) {
|
||||||
|
String levelEntityConfig = owner.getScene().getSceneData().getLevelEntityConfig();
|
||||||
|
ConfigLevelEntity config = GameData.getConfigLevelEntityDataMap().get(levelEntityConfig);
|
||||||
|
if (config != null
|
||||||
|
&& config.getDropElemControlType() != null
|
||||||
|
&& config.getDropElemControlType().compareTo("None") == 0) {
|
||||||
|
Grasscutter.getLogger().warn("This level config don't allow element balls");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (action.dropType == DropType.BigWorldOnly) {
|
||||||
|
if (owner.getScene().getSceneData().getSceneType() != SceneType.SCENE_WORLD) {
|
||||||
|
Grasscutter.getLogger().warn("This level config only allows element balls on big world");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // Else the drop is forced
|
||||||
|
|
||||||
|
var energy = action.baseEnergy.get(ability) * action.ratio.get(ability);
|
||||||
|
if (energy <= 0.0) return true;
|
||||||
|
|
||||||
|
var itemData = GameData.getItemDataMap().get(action.configID);
|
||||||
|
if (itemData == null) {
|
||||||
|
Grasscutter.getLogger().warn("configID {} not found", action.configID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemData.getItemUse() == null || itemData.getItemUse().isEmpty()) {
|
||||||
|
Grasscutter.getLogger().warn("Item {} has no item use array", action.configID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var itemUse = itemData.getItemUse().get(0);
|
||||||
|
double requiredEnergy;
|
||||||
|
switch (itemUse.getUseOp()) {
|
||||||
|
case ITEM_USE_ADD_ELEM_ENERGY:
|
||||||
|
requiredEnergy = Integer.parseInt(itemUse.getUseParam()[1]);
|
||||||
|
break;
|
||||||
|
case ITEM_USE_ADD_ALL_ENERGY:
|
||||||
|
requiredEnergy = Integer.parseInt(itemUse.getUseParam()[0]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Grasscutter.getLogger().warn("UseOp not implemented", itemUse.getUseOp());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var amountGenerated = (int) Math.ceil(energy / requiredEnergy);
|
||||||
|
if (amountGenerated >= 21) {
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.warn("Attempt to generate more than 20 element balls {}", amountGenerated);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.debug("Generating {} of {} element balls", amountGenerated, action.configID);
|
||||||
|
for (int i = 0; i < amountGenerated; i++) {
|
||||||
|
EntityItem energyBall =
|
||||||
|
new EntityItem(
|
||||||
|
owner.getScene(),
|
||||||
|
(owner instanceof EntityAvatar avatar) ? avatar.getPlayer() : null,
|
||||||
|
itemData,
|
||||||
|
new Position(generateElemBall.getPos()),
|
||||||
|
new Position(generateElemBall.getRot()),
|
||||||
|
1);
|
||||||
|
owner.getScene().addEntity(energyBall);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package emu.grasscutter.game.ability.actions;
|
package emu.grasscutter.game.ability.actions;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||||
import emu.grasscutter.game.ability.Ability;
|
import emu.grasscutter.game.ability.Ability;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
@ -10,9 +11,14 @@ public final class ActionKillSelf extends AbilityActionHandler {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
Ability ability, AbilityModifierAction action, ByteString abilityData, GameEntity target) {
|
Ability ability, AbilityModifierAction action, ByteString abilityData, GameEntity target) {
|
||||||
GameEntity owner = ability.getOwner();
|
// KillSelf should not have a target field, so target it's the actual entity to be applied.
|
||||||
owner.getScene().killEntity(owner);
|
// TODO: Check if this is always true.
|
||||||
|
if (target == null) {
|
||||||
|
Grasscutter.getLogger().warn("Tried killing null target");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.getScene().killEntity(target);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package emu.grasscutter.game.ability.actions;
|
package emu.grasscutter.game.ability.actions;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||||
import emu.grasscutter.game.ability.Ability;
|
import emu.grasscutter.game.ability.Ability;
|
||||||
import emu.grasscutter.game.entity.EntityClientGadget;
|
import emu.grasscutter.game.entity.*;
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
|
||||||
|
|
||||||
@AbilityAction(AbilityModifierAction.Type.SetGlobalValueToOverrideMap)
|
@AbilityAction(AbilityModifierAction.Type.SetGlobalValueToOverrideMap)
|
||||||
public class ActionSetGlobalValueToOverrideMap extends AbilityActionHandler {
|
public class ActionSetGlobalValueToOverrideMap extends AbilityActionHandler {
|
||||||
@ -23,15 +22,20 @@ public class ActionSetGlobalValueToOverrideMap extends AbilityActionHandler {
|
|||||||
var globalValueKey = action.globalValueKey;
|
var globalValueKey = action.globalValueKey;
|
||||||
var abilityFormula = action.abilityFormula;
|
var abilityFormula = action.abilityFormula;
|
||||||
|
|
||||||
if (!entity.getGlobalAbilityValues().containsKey(globalValueKey)) return false;
|
if (!entity.getGlobalAbilityValues().containsKey(globalValueKey)) {
|
||||||
|
Grasscutter.getLogger().debug("Action does not contains {} global key", globalValueKey);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var globalValue = entity.getGlobalAbilityValues().getOrDefault(globalValueKey, 0.0f);
|
var globalValue = entity.getGlobalAbilityValues().getOrDefault(globalValueKey, 0.0f);
|
||||||
if (abilityFormula.compareTo("DummyThrowSpeed") == 0) {
|
if (abilityFormula.compareTo("DummyThrowSpeed") == 0) {
|
||||||
globalValue = ((globalValue * 30.0f) / ((float) Math.sin(0.9424778) * 100.0f)) - 1.0f;
|
globalValue = ((globalValue * 30.0f) / ((float) Math.sin(0.9424778) * 100.0f)) - 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.getGlobalAbilityValues().put(globalValueKey, globalValue);
|
entity.getGlobalAbilityValues().put(globalValueKey, globalValue); // Research if this is needed.
|
||||||
entity.onAbilityValueUpdate();
|
ability
|
||||||
|
.getAbilitySpecials()
|
||||||
|
.put(action.overrideMapKey, globalValue.floatValue()); // Override our own.
|
||||||
|
|
||||||
// TODO: ChangeServerGlobalValueNotify
|
// TODO: ChangeServerGlobalValueNotify
|
||||||
|
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package emu.grasscutter.game.ability.actions;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||||
|
import emu.grasscutter.game.ability.Ability;
|
||||||
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
|
import emu.grasscutter.net.proto.AbilityActionSetRandomOverrideMapValueOuterClass.AbilityActionSetRandomOverrideMapValue;
|
||||||
|
|
||||||
|
@AbilityAction(AbilityModifierAction.Type.SetRandomOverrideMapValue)
|
||||||
|
public class ActionSetRandomOverrideMapValue extends AbilityActionHandler {
|
||||||
|
@Override
|
||||||
|
public boolean execute(
|
||||||
|
Ability ability, AbilityModifierAction action, ByteString abilityData, GameEntity target) {
|
||||||
|
AbilityActionSetRandomOverrideMapValue valueProto;
|
||||||
|
try {
|
||||||
|
valueProto = AbilityActionSetRandomOverrideMapValue.parseFrom(abilityData);
|
||||||
|
} catch (InvalidProtocolBufferException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float value = valueProto.getRandomValue();
|
||||||
|
float valueRangeMin = action.valueRangeMin.get(ability);
|
||||||
|
float valueRangeMax = action.valueRangeMax.get(ability);
|
||||||
|
|
||||||
|
if (value < valueRangeMin || value > valueRangeMax) {
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.warn(
|
||||||
|
"Tried setting value out of range: {} inside [{}, {}]",
|
||||||
|
value,
|
||||||
|
valueRangeMin,
|
||||||
|
valueRangeMax);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ability.getAbilitySpecials().put(action.overrideMapKey, value);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1243,13 +1243,15 @@ public class Avatar {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Add costume if avatar has a costume.
|
// Add costume if avatar has a costume.
|
||||||
GameData.getAvatarCostumeDataItemIdMap()
|
if (GAME_OPTIONS.trialCostumes) {
|
||||||
.values()
|
GameData.getAvatarCostumeDataItemIdMap()
|
||||||
.forEach(
|
.values()
|
||||||
costumeData -> {
|
.forEach(
|
||||||
if (costumeData.getCharacterId() != this.getAvatarId()) return;
|
costumeData -> {
|
||||||
this.setCostume(costumeData.getId());
|
if (costumeData.getCharacterId() != this.getAvatarId()) return;
|
||||||
});
|
this.setCostume(costumeData.getId());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Equips the items applied from {@link Avatar#applyTrialItems()}. */
|
/** Equips the items applied from {@link Avatar#applyTrialItems()}. */
|
||||||
|
@ -80,6 +80,14 @@ public final class DropSystem extends BaseGameSystem {
|
|||||||
return dropData.getDropId();
|
return dropData.getDropId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<GameItem> handleDungeonRewardDrop(int dropId, boolean doubleReward) {
|
||||||
|
if (!dropTable.containsKey(dropId)) return List.of();
|
||||||
|
var dropData = dropTable.get(dropId);
|
||||||
|
List<GameItem> items = new ArrayList<>();
|
||||||
|
processDrop(dropData, doubleReward ? 2 : 1, items);
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean handleMonsterDrop(EntityMonster monster) {
|
public boolean handleMonsterDrop(EntityMonster monster) {
|
||||||
int dropId;
|
int dropId;
|
||||||
int level = monster.getLevel();
|
int level = monster.getLevel();
|
||||||
|
@ -134,7 +134,16 @@ public final class DungeonManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get and roll rewards.
|
// Get and roll rewards.
|
||||||
List<GameItem> rewards = new ArrayList<>(this.rollRewards(useCondensed));
|
List<GameItem> rewards =
|
||||||
|
player
|
||||||
|
.getServer()
|
||||||
|
.getDropSystem()
|
||||||
|
.handleDungeonRewardDrop(dungeonData.getStatueDrop(), useCondensed);
|
||||||
|
if (rewards.isEmpty()) {
|
||||||
|
// fallback to legacy drop system
|
||||||
|
Grasscutter.getLogger().debug("dungeon drop failed for {}", dungeonData.getId());
|
||||||
|
rewards = new ArrayList<>(this.rollRewards(useCondensed));
|
||||||
|
}
|
||||||
// Add rewards to player and send notification.
|
// Add rewards to player and send notification.
|
||||||
player.getInventory().addItems(rewards, ActionReason.DungeonStatueDrop);
|
player.getInventory().addItems(rewards, ActionReason.DungeonStatueDrop);
|
||||||
player.sendPacket(new PacketGadgetAutoPickDropInfoNotify(rewards));
|
player.sendPacket(new PacketGadgetAutoPickDropInfoNotify(rewards));
|
||||||
@ -187,7 +196,7 @@ public final class DungeonManager {
|
|||||||
amount += Utils.drawRandomListElement(candidateAmounts, entry.getProbabilities());
|
amount += Utils.drawRandomListElement(candidateAmounts, entry.getProbabilities());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double rewards in multiplay mode, if specified.
|
// Double rewards in multiply mode, if specified.
|
||||||
if (entry.isMpDouble() && this.getScene().getPlayerCount() > 1) {
|
if (entry.isMpDouble() && this.getScene().getPlayerCount() > 1) {
|
||||||
amount *= 2;
|
amount *= 2;
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,9 @@ import emu.grasscutter.data.excels.GadgetData;
|
|||||||
import emu.grasscutter.game.entity.gadget.*;
|
import emu.grasscutter.game.entity.gadget.*;
|
||||||
import emu.grasscutter.game.entity.gadget.platform.BaseRoute;
|
import emu.grasscutter.game.entity.gadget.platform.BaseRoute;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.EntityIdType;
|
import emu.grasscutter.game.props.*;
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.world.*;
|
||||||
import emu.grasscutter.game.world.Position;
|
import emu.grasscutter.net.proto.*;
|
||||||
import emu.grasscutter.game.world.Scene;
|
|
||||||
import emu.grasscutter.game.world.SceneGroupInstance;
|
|
||||||
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||||
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
||||||
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
||||||
@ -20,31 +18,21 @@ import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
|
|||||||
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
||||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
||||||
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
import emu.grasscutter.net.proto.PlatformInfoOuterClass;
|
|
||||||
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
||||||
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
|
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
|
||||||
import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
|
import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
|
||||||
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
||||||
import emu.grasscutter.net.proto.VisionTypeOuterClass;
|
|
||||||
import emu.grasscutter.scripts.EntityControllerScriptManager;
|
import emu.grasscutter.scripts.EntityControllerScriptManager;
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
import emu.grasscutter.scripts.data.SceneGadget;
|
import emu.grasscutter.scripts.data.*;
|
||||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetStateNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketPlatformStartRouteNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketPlatformStopRouteNotify;
|
|
||||||
import emu.grasscutter.server.packet.send.PacketSceneTimeNotify;
|
|
||||||
import emu.grasscutter.utils.helpers.ProtoHelper;
|
import emu.grasscutter.utils.helpers.ProtoHelper;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
|
import java.util.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import lombok.Getter;
|
import lombok.*;
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class EntityGadget extends EntityBaseGadget {
|
public class EntityGadget extends EntityBaseGadget {
|
||||||
|
@ -37,14 +37,30 @@ public class EntityItem extends EntityBaseGadget {
|
|||||||
this(scene, player, itemData, pos, count, true);
|
this(scene, player, itemData, pos, count, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityItem(
|
||||||
|
Scene scene, Player player, ItemData itemData, Position pos, Position rotation, int count) {
|
||||||
|
this(scene, player, itemData, pos, rotation, count, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityItem(
|
||||||
|
Scene scene, Player player, ItemData itemData, Position pos, int count, boolean share) {
|
||||||
|
this(scene, player, itemData, pos, null, count, share);
|
||||||
|
}
|
||||||
|
|
||||||
// In official game, some drop items are shared to all players, and some other items are
|
// In official game, some drop items are shared to all players, and some other items are
|
||||||
// independent to all players
|
// independent to all players
|
||||||
// For example, if you killed a monster in MP mode, all players could get drops but rarity and
|
// For example, if you killed a monster in MP mode, all players could get drops but rarity and
|
||||||
// number of them are different
|
// number of them are different
|
||||||
// but if you broke regional mine, when someone picked up the drop then it disappeared
|
// but if you broke regional mine, when someone picked up the drop then it disappeared
|
||||||
public EntityItem(
|
public EntityItem(
|
||||||
Scene scene, Player player, ItemData itemData, Position pos, int count, boolean share) {
|
Scene scene,
|
||||||
super(scene, pos, null);
|
Player player,
|
||||||
|
ItemData itemData,
|
||||||
|
Position pos,
|
||||||
|
Position rotation,
|
||||||
|
int count,
|
||||||
|
boolean share) {
|
||||||
|
super(scene, pos, rotation);
|
||||||
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
this.id = getScene().getWorld().getNextEntityId(EntityIdType.GADGET);
|
||||||
this.guid =
|
this.guid =
|
||||||
player == null ? scene.getWorld().getHost().getNextGameGuid() : player.getNextGameGuid();
|
player == null ? scene.getWorld().getHost().getNextGameGuid() : player.getNextGameGuid();
|
||||||
|
@ -113,7 +113,13 @@ public class EntityMonster extends GameEntity {
|
|||||||
if(monster != null) affixes = monster.affix;
|
if(monster != null) affixes = monster.affix;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (affixes != null) {
|
if (monsterData != null) {
|
||||||
|
// TODO: Research if group affixes goes first
|
||||||
|
if (affixes == null) affixes = monsterData.getAffix();
|
||||||
|
else affixes.addAll(monsterData.getAffix());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(affixes != null) {
|
||||||
for(var affixId : affixes) {
|
for(var affixId : affixes) {
|
||||||
var affix = GameData.getMonsterAffixDataMap().get(affixId.intValue());
|
var affix = GameData.getMonsterAffixDataMap().get(affixId.intValue());
|
||||||
if (!affix.isPreAdd()) continue;
|
if (!affix.isPreAdd()) continue;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package emu.grasscutter.game.entity;
|
package emu.grasscutter.game.entity;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.game.ability.*;
|
import emu.grasscutter.game.ability.*;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.*;
|
import emu.grasscutter.game.props.*;
|
||||||
@ -51,8 +52,8 @@ public abstract class GameEntity {
|
|||||||
|
|
||||||
public abstract void initAbilities();
|
public abstract void initAbilities();
|
||||||
|
|
||||||
public int getEntityType() {
|
public EntityType getEntityType() {
|
||||||
return this.getId() >> 24;
|
return EntityIdType.toEntityType(this.getId() >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract int getEntityTypeId();
|
public abstract int getEntityTypeId();
|
||||||
@ -226,6 +227,82 @@ public abstract class GameEntity {
|
|||||||
|
|
||||||
public void onRemoved() {}
|
public void onRemoved() {}
|
||||||
|
|
||||||
|
private int[] parseCountRange(String range) {
|
||||||
|
var split = range.split(";");
|
||||||
|
if (split.length == 1)
|
||||||
|
return new int[] {Integer.parseInt(split[0]), Integer.parseInt(split[0])};
|
||||||
|
return new int[] {Integer.parseInt(split[0]), Integer.parseInt(split[1])};
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean dropSubfieldItem(int dropId) {
|
||||||
|
var drop = GameData.getDropSubfieldMappingMap().get(dropId);
|
||||||
|
if (drop == null) return false;
|
||||||
|
var dropTableEntry = GameData.getDropTableExcelConfigDataMap().get(drop.getItemId());
|
||||||
|
if (dropTableEntry == null) return false;
|
||||||
|
|
||||||
|
Int2ObjectMap<Integer> itemsToDrop = new Int2ObjectOpenHashMap<>();
|
||||||
|
switch (dropTableEntry.getRandomType()) {
|
||||||
|
case 0: // select one
|
||||||
|
{
|
||||||
|
int weightCount = 0;
|
||||||
|
for (var entry : dropTableEntry.getDropVec()) weightCount += entry.getWeight();
|
||||||
|
|
||||||
|
int randomValue = new Random().nextInt(weightCount);
|
||||||
|
|
||||||
|
weightCount = 0;
|
||||||
|
for (var entry : dropTableEntry.getDropVec()) {
|
||||||
|
if (randomValue >= weightCount && randomValue < (weightCount + entry.getWeight())) {
|
||||||
|
var countRange = parseCountRange(entry.getCountRange());
|
||||||
|
itemsToDrop.put(
|
||||||
|
entry.getItemId(),
|
||||||
|
Integer.valueOf((new Random().nextBoolean() ? countRange[0] : countRange[1])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: // Select various
|
||||||
|
{
|
||||||
|
for (var entry : dropTableEntry.getDropVec()) {
|
||||||
|
if (entry.getWeight() < new Random().nextInt(10000)) {
|
||||||
|
var countRange = parseCountRange(entry.getCountRange());
|
||||||
|
itemsToDrop.put(
|
||||||
|
entry.getItemId(),
|
||||||
|
Integer.valueOf((new Random().nextBoolean() ? countRange[0] : countRange[1])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var entry : itemsToDrop.int2ObjectEntrySet()) {
|
||||||
|
var item =
|
||||||
|
new EntityItem(
|
||||||
|
scene,
|
||||||
|
null,
|
||||||
|
GameData.getItemDataMap().get(entry.getIntKey()),
|
||||||
|
getPosition().nearby2d(1f).addY(0.5f),
|
||||||
|
entry.getValue(),
|
||||||
|
true);
|
||||||
|
|
||||||
|
scene.addEntity(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean dropSubfield(String subfieldName) {
|
||||||
|
var subfieldMapping = GameData.getSubfieldMappingMap().get(getEntityTypeId());
|
||||||
|
if (subfieldMapping == null || subfieldMapping.getSubfields() == null) return false;
|
||||||
|
|
||||||
|
for (var entry : subfieldMapping.getSubfields()) {
|
||||||
|
if (entry.getSubfieldName().compareTo(subfieldName) == 0) {
|
||||||
|
return dropSubfieldItem(entry.getDrop_id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void onTick(int sceneTime) {
|
public void onTick(int sceneTime) {
|
||||||
if (entityController != null) {
|
if (entityController != null) {
|
||||||
entityController.onTimer(this, sceneTime);
|
entityController.onTimer(this, sceneTime);
|
||||||
|
@ -75,6 +75,7 @@ public class GadgetChest extends GadgetContent {
|
|||||||
} else if (chest.chest_drop_id != 0) {
|
} else if (chest.chest_drop_id != 0) {
|
||||||
status = dropSystem.handleChestDrop(chest.chest_drop_id, chest.drop_count, getGadget());
|
status = dropSystem.handleChestDrop(chest.chest_drop_id, chest.drop_count, getGadget());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
getGadget().updateState(ScriptGadgetState.ChestOpened);
|
getGadget().updateState(ScriptGadgetState.ChestOpened);
|
||||||
player.sendPacket(
|
player.sendPacket(
|
||||||
|
@ -14,6 +14,8 @@ import emu.grasscutter.net.proto.GadgetInteractReqOuterClass.GadgetInteractReq;
|
|||||||
import emu.grasscutter.net.proto.GatherGadgetInfoOuterClass.GatherGadgetInfo;
|
import emu.grasscutter.net.proto.GatherGadgetInfoOuterClass.GatherGadgetInfo;
|
||||||
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
|
|
||||||
@ -57,6 +59,13 @@ public final class GadgetGatherObject extends GadgetContent {
|
|||||||
GameItem item = new GameItem(itemData, 1);
|
GameItem item = new GameItem(itemData, 1);
|
||||||
player.getInventory().addItem(item, ActionReason.Gather);
|
player.getInventory().addItem(item, ActionReason.Gather);
|
||||||
|
|
||||||
|
getGadget()
|
||||||
|
.getScene()
|
||||||
|
.getScriptManager()
|
||||||
|
.callEvent(
|
||||||
|
new ScriptArgs(
|
||||||
|
getGadget().getGroupId(), EventType.EVENT_GATHER, getGadget().getConfigId()));
|
||||||
|
|
||||||
getGadget()
|
getGadget()
|
||||||
.getScene()
|
.getScene()
|
||||||
.broadcastPacket(
|
.broadcastPacket(
|
||||||
|
@ -133,13 +133,9 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
|||||||
for (var item : items) {
|
for (var item : items) {
|
||||||
if (item.getItemId() == 0) continue;
|
if (item.getItemId() == 0) continue;
|
||||||
GameItem result = null;
|
GameItem result = null;
|
||||||
try {
|
|
||||||
// putItem might throw exception
|
result = putItem(item);
|
||||||
// ignore that exception and continue
|
|
||||||
result = putItem(item);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
this.triggerAddItemEvents(result);
|
this.triggerAddItemEvents(result);
|
||||||
changedItems.add(result);
|
changedItems.add(result);
|
||||||
@ -155,22 +151,33 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void triggerAddItemEvents(GameItem result) {
|
private void triggerAddItemEvents(GameItem result) {
|
||||||
getPlayer()
|
try {
|
||||||
.getBattlePassManager()
|
getPlayer()
|
||||||
.triggerMission(
|
.getBattlePassManager()
|
||||||
WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM, result.getItemId(), result.getCount());
|
.triggerMission(
|
||||||
getPlayer()
|
WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM,
|
||||||
.getQuestManager()
|
result.getItemId(),
|
||||||
.queueEvent(QuestContent.QUEST_CONTENT_OBTAIN_ITEM, result.getItemId(), result.getCount());
|
result.getCount());
|
||||||
|
getPlayer()
|
||||||
|
.getQuestManager()
|
||||||
|
.queueEvent(
|
||||||
|
QuestContent.QUEST_CONTENT_OBTAIN_ITEM, result.getItemId(), result.getCount());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().debug("triggerAddItemEvents failed", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void triggerRemItemEvents(GameItem item, int removeCount) {
|
private void triggerRemItemEvents(GameItem item, int removeCount) {
|
||||||
getPlayer()
|
try {
|
||||||
.getBattlePassManager()
|
getPlayer()
|
||||||
.triggerMission(WatcherTriggerType.TRIGGER_COST_MATERIAL, item.getItemId(), removeCount);
|
.getBattlePassManager()
|
||||||
getPlayer()
|
.triggerMission(WatcherTriggerType.TRIGGER_COST_MATERIAL, item.getItemId(), removeCount);
|
||||||
.getQuestManager()
|
getPlayer()
|
||||||
.queueEvent(QuestContent.QUEST_CONTENT_ITEM_LESS_THAN, item.getItemId(), item.getCount());
|
.getQuestManager()
|
||||||
|
.queueEvent(QuestContent.QUEST_CONTENT_ITEM_LESS_THAN, item.getItemId(), item.getCount());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().debug("triggerRemItemEvents failed", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addItemParams(Collection<ItemParam> items) {
|
public void addItemParams(Collection<ItemParam> items) {
|
||||||
@ -193,8 +200,11 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
|
|||||||
// Dont add items that dont have a valid item definition.
|
// Dont add items that dont have a valid item definition.
|
||||||
var data = item.getItemData();
|
var data = item.getItemData();
|
||||||
if (data == null) return null;
|
if (data == null) return null;
|
||||||
|
try {
|
||||||
this.player.getProgressManager().addItemObtainedHistory(item.getItemId(), item.getCount());
|
this.player.getProgressManager().addItemObtainedHistory(item.getItemId(), item.getCount());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().debug("addItemObtainedHistory failed", e);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.isUseOnGain()) {
|
if (data.isUseOnGain()) {
|
||||||
var params = new UseItemParams(this.player, data.getUseTarget());
|
var params = new UseItemParams(this.player, data.getUseTarget());
|
||||||
|
@ -317,7 +317,9 @@ public class StaminaManager extends BasePlayerManager {
|
|||||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
|
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
|
||||||
entity.getWorld().broadcastPacket(new PacketLifeStateChangeNotify(0, entity, LifeState.LIFE_DEAD));
|
entity.getWorld().broadcastPacket(new PacketLifeStateChangeNotify(0, entity, LifeState.LIFE_DEAD));
|
||||||
player.getScene().removeEntity(entity);
|
player.getScene().removeEntity(entity);
|
||||||
((EntityAvatar) entity).onDeath(dieType, 0);
|
|
||||||
|
if (entity instanceof EntityAvatar avatar)
|
||||||
|
avatar.onDeath(dieType, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startSustainedStaminaHandler() {
|
public void startSustainedStaminaHandler() {
|
||||||
|
@ -345,16 +345,11 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
this.playerGameTime = gameTime;
|
this.playerGameTime = gameTime;
|
||||||
|
|
||||||
// If the player is the host of the world, update the game time as well.
|
// If the player is the host of the world, update the game time as well.
|
||||||
if (this.getWorld().getHost() == this) {
|
var world = this.getWorld();
|
||||||
this.getWorld().changeTime(gameTime);
|
if (world != null && world.getHost() == this) {
|
||||||
|
world.changeTime(gameTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger the script event for game time update.
|
|
||||||
var questManager = this.getQuestManager();
|
|
||||||
questManager.queueEvent(QuestCond.QUEST_COND_IS_DAYTIME);
|
|
||||||
questManager.queueEvent(QuestCond.QUEST_COND_TIME_VAR_GT_EQ);
|
|
||||||
questManager.queueEvent(QuestCond.QUEST_COND_TIME_VAR_PASS_DAY);
|
|
||||||
|
|
||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,14 +702,16 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onEnterRegion(SceneRegion region) {
|
public void onEnterRegion(SceneRegion region) {
|
||||||
|
var enterRegionName = "ENTER_REGION_" + region.config_id;
|
||||||
this.getQuestManager().forEachActiveQuest(quest -> {
|
this.getQuestManager().forEachActiveQuest(quest -> {
|
||||||
if (quest.getTriggerData() != null &&
|
if (quest.getTriggerData() != null &&
|
||||||
quest.getTriggers().containsKey("ENTER_REGION_"+ region.config_id)) {
|
quest.getTriggers().containsKey(enterRegionName) &&
|
||||||
|
region.getGroupId() == quest.getTriggerData().get(enterRegionName).getGroupId()) {
|
||||||
// If trigger hasn't been fired yet
|
// If trigger hasn't been fired yet
|
||||||
if (!Boolean.TRUE.equals(quest.getTriggers().put("ENTER_REGION_" + region.config_id, true))) {
|
if (!Boolean.TRUE.equals(quest.getTriggers().put(enterRegionName, true))) {
|
||||||
this.getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
|
this.getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
|
||||||
this.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_TRIGGER_FIRE,
|
this.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_TRIGGER_FIRE,
|
||||||
quest.getTriggerData().get("ENTER_REGION_" + region.config_id).getId(), 0);
|
quest.getTriggerData().get(enterRegionName).getId(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -722,13 +719,15 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onLeaveRegion(SceneRegion region) {
|
public void onLeaveRegion(SceneRegion region) {
|
||||||
|
var leaveRegionName = "LEAVE_REGION_" + region.config_id;
|
||||||
this.getQuestManager().forEachActiveQuest(quest -> {
|
this.getQuestManager().forEachActiveQuest(quest -> {
|
||||||
if (quest.getTriggers().containsKey("LEAVE_REGION_" + region.config_id)) {
|
if (quest.getTriggers().containsKey(leaveRegionName) &&
|
||||||
|
region.getGroupId() == quest.getTriggerData().get(leaveRegionName).getGroupId()) {
|
||||||
// If trigger hasn't been fired yet
|
// If trigger hasn't been fired yet
|
||||||
if (!Boolean.TRUE.equals(quest.getTriggers().put("LEAVE_REGION_" + region.config_id, true))) {
|
if (!Boolean.TRUE.equals(quest.getTriggers().put(leaveRegionName, true))) {
|
||||||
this.getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
|
this.getSession().send(new PacketServerCondMeetQuestListUpdateNotify());
|
||||||
this.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_TRIGGER_FIRE,
|
this.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_TRIGGER_FIRE,
|
||||||
quest.getTriggerData().get("LEAVE_REGION_" + region.config_id).getId(), 0);
|
quest.getTriggerData().get(leaveRegionName).getId(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -4,10 +4,10 @@ import dev.morphia.annotations.Entity;
|
|||||||
import dev.morphia.annotations.Transient;
|
import dev.morphia.annotations.Transient;
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@ -29,10 +29,10 @@ public class PlayerProgress {
|
|||||||
// keep track of EXEC_ADD_QUEST_PROGRESS count, will be used in CONTENT_ADD_QUEST_PROGRESS
|
// keep track of EXEC_ADD_QUEST_PROGRESS count, will be used in CONTENT_ADD_QUEST_PROGRESS
|
||||||
// not sure where to put this, this should be saved to DB but not to individual quest, since
|
// not sure where to put this, this should be saved to DB but not to individual quest, since
|
||||||
// it will be hard to loop and compare
|
// it will be hard to loop and compare
|
||||||
private Map<Integer, Integer> questProgressCountMap;
|
private Map<String, Integer> questProgressCountMap;
|
||||||
|
|
||||||
public PlayerProgress() {
|
public PlayerProgress() {
|
||||||
this.questProgressCountMap = new Int2IntOpenHashMap();
|
this.questProgressCountMap = new ConcurrentHashMap<>();
|
||||||
this.completedDungeons = new IntArrayList();
|
this.completedDungeons = new IntArrayList();
|
||||||
this.itemHistory = new Int2ObjectOpenHashMap<>();
|
this.itemHistory = new Int2ObjectOpenHashMap<>();
|
||||||
}
|
}
|
||||||
@ -70,15 +70,15 @@ public class PlayerProgress {
|
|||||||
return itemEntry.addToObtainedCount(count);
|
return itemEntry.addToObtainedCount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCurrentProgress(int progressId) {
|
public int getCurrentProgress(String progressId) {
|
||||||
return questProgressCountMap.getOrDefault(progressId, -1);
|
return questProgressCountMap.getOrDefault(progressId, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int addToCurrentProgress(int progressId, int count) {
|
public int addToCurrentProgress(String progressId, int count) {
|
||||||
return questProgressCountMap.merge(progressId, count, Integer::sum);
|
return questProgressCountMap.merge(progressId, count, Integer::sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int resetCurrentProgress(int progressId) {
|
public int resetCurrentProgress(String progressId) {
|
||||||
return questProgressCountMap.merge(progressId, 0, Integer::min);
|
return questProgressCountMap.merge(progressId, 0, Integer::min);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ public final class PlayerProgressManager extends BasePlayerDataManager {
|
|||||||
|
|
||||||
/** Quest progress */
|
/** Quest progress */
|
||||||
public void addQuestProgress(int id, int count) {
|
public void addQuestProgress(int id, int count) {
|
||||||
var newCount = player.getPlayerProgress().addToCurrentProgress(id, count);
|
var newCount = player.getPlayerProgress().addToCurrentProgress(String.valueOf(id), count);
|
||||||
player.save();
|
player.save();
|
||||||
player
|
player
|
||||||
.getQuestManager()
|
.getQuestManager()
|
||||||
|
@ -5,8 +5,7 @@ import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
|||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam;
|
import emu.grasscutter.net.proto.AvatarTeamOuterClass.AvatarTeam;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public final class TeamInfo {
|
public final class TeamInfo {
|
||||||
@ -87,6 +86,8 @@ public final class TeamInfo {
|
|||||||
|
|
||||||
for (int i = 0; i < this.getAvatars().size(); i++) {
|
for (int i = 0; i < this.getAvatars().size(); i++) {
|
||||||
Avatar avatar = player.getAvatars().getAvatarById(this.getAvatars().get(i));
|
Avatar avatar = player.getAvatars().getAvatarById(this.getAvatars().get(i));
|
||||||
|
if (avatar == null) continue;
|
||||||
|
|
||||||
avatarTeam.addAvatarGuidList(avatar.getGuid());
|
avatarTeam.addAvatarGuidList(avatar.getGuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package emu.grasscutter.game.props;
|
package emu.grasscutter.game.props;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public enum EntityIdType {
|
public enum EntityIdType {
|
||||||
AVATAR(0x01),
|
AVATAR(0x01),
|
||||||
MONSTER(0x02),
|
MONSTER(0x02),
|
||||||
@ -12,10 +15,27 @@ public enum EntityIdType {
|
|||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
|
private static final Map<Integer, EntityType> map = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
map.put(EntityIdType.AVATAR.getId(), EntityType.Avatar);
|
||||||
|
map.put(EntityIdType.MONSTER.getId(), EntityType.Monster);
|
||||||
|
map.put(EntityIdType.NPC.getId(), EntityType.NPC);
|
||||||
|
map.put(EntityIdType.GADGET.getId(), EntityType.Gadget);
|
||||||
|
map.put(EntityIdType.REGION.getId(), EntityType.Region);
|
||||||
|
map.put(EntityIdType.WEAPON.getId(), EntityType.Equip);
|
||||||
|
map.put(EntityIdType.TEAM.getId(), EntityType.Team);
|
||||||
|
map.put(EntityIdType.MPLEVEL.getId(), EntityType.MPLevel);
|
||||||
|
}
|
||||||
|
|
||||||
EntityIdType(int id) {
|
EntityIdType(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static EntityType toEntityType(int entityId) {
|
||||||
|
return map.getOrDefault(entityId, EntityType.None);
|
||||||
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ public enum EntityType implements IntValueEnum {
|
|||||||
Screen(64),
|
Screen(64),
|
||||||
EchoShell(65),
|
EchoShell(65),
|
||||||
UIInteractGadget(66),
|
UIInteractGadget(66),
|
||||||
|
Region(98),
|
||||||
PlaceHolder(99);
|
PlaceHolder(99);
|
||||||
|
|
||||||
private static final Int2ObjectMap<EntityType> map = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<EntityType> map = new Int2ObjectOpenHashMap<>();
|
||||||
|
@ -314,7 +314,7 @@ public class GameMainQuest {
|
|||||||
0, new Position(avatarPosPos.get(0), avatarPosPos.get(1), avatarPosPos.get(2))); // position
|
0, new Position(avatarPosPos.get(0), avatarPosPos.get(1), avatarPosPos.get(2))); // position
|
||||||
posAndRot.add(
|
posAndRot.add(
|
||||||
1, new Position(avatarPosRot.get(0), avatarPosRot.get(1), avatarPosRot.get(2))); // rotation
|
1, new Position(avatarPosRot.get(0), avatarPosRot.get(1), avatarPosRot.get(2))); // rotation
|
||||||
Grasscutter.getLogger().info("Succesfully loaded rewind data for subQuest {}", subId);
|
Grasscutter.getLogger().debug("Successfully loaded rewind data for quest {}.", subId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,10 +51,12 @@ public class GameQuest {
|
|||||||
this.state = QuestState.QUEST_STATE_UNSTARTED;
|
this.state = QuestState.QUEST_STATE_UNSTARTED;
|
||||||
this.triggerData = new HashMap<>();
|
this.triggerData = new HashMap<>();
|
||||||
this.triggers = new HashMap<>();
|
this.triggers = new HashMap<>();
|
||||||
|
this.finishProgressList = new int[questData.getFinishCond().size()];
|
||||||
|
this.failProgressList = new int[questData.getFailCond().size()];
|
||||||
|
this.finishTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
this.clearProgress(false);
|
|
||||||
this.acceptTime = Utils.getCurrentSeconds();
|
this.acceptTime = Utils.getCurrentSeconds();
|
||||||
this.startTime = this.acceptTime;
|
this.startTime = this.acceptTime;
|
||||||
this.startGameDay = getOwner().getWorld().getTotalGameTimeDays();
|
this.startGameDay = getOwner().getWorld().getTotalGameTimeDays();
|
||||||
@ -142,7 +144,7 @@ public class GameQuest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setFinishProgress(int index, int value) {
|
public void setFinishProgress(int index, int value) {
|
||||||
finishProgressList[index] = value;
|
this.finishProgressList[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFailProgress(int index, int value) {
|
public void setFailProgress(int index, int value) {
|
||||||
@ -153,17 +155,30 @@ public class GameQuest {
|
|||||||
// TODO improve
|
// TODO improve
|
||||||
var oldState = state;
|
var oldState = state;
|
||||||
if (questData.getFinishCond() != null && questData.getFinishCond().size() != 0) {
|
if (questData.getFinishCond() != null && questData.getFinishCond().size() != 0) {
|
||||||
|
for (var condition : questData.getFinishCond()) {
|
||||||
|
if (condition.getType() == QuestContent.QUEST_CONTENT_LUA_NOTIFY) {
|
||||||
|
this.getOwner().getPlayerProgress().resetCurrentProgress(condition.getParamStr());
|
||||||
|
}
|
||||||
|
}
|
||||||
this.finishProgressList = new int[questData.getFinishCond().size()];
|
this.finishProgressList = new int[questData.getFinishCond().size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (questData.getFailCond() != null && questData.getFailCond().size() != 0) {
|
if (questData.getFailCond() != null && questData.getFailCond().size() != 0) {
|
||||||
|
for (var condition : questData.getFailCond()) {
|
||||||
|
if (condition.getType() == QuestContent.QUEST_CONTENT_LUA_NOTIFY) {
|
||||||
|
this.getOwner().getPlayerProgress().resetCurrentProgress(condition.getParamStr());
|
||||||
|
}
|
||||||
|
}
|
||||||
this.failProgressList = new int[questData.getFailCond().size()];
|
this.failProgressList = new int[questData.getFailCond().size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.getOwner().getPlayerProgress().resetCurrentProgress(String.valueOf(this.subQuestId));
|
||||||
|
|
||||||
setState(QuestState.QUEST_STATE_UNSTARTED);
|
setState(QuestState.QUEST_STATE_UNSTARTED);
|
||||||
finishTime = 0;
|
finishTime = 0;
|
||||||
acceptTime = 0;
|
acceptTime = 0;
|
||||||
startTime = 0;
|
startTime = 0;
|
||||||
this.getOwner().getPlayerProgress().resetCurrentProgress(this.subQuestId);
|
|
||||||
if (oldState == QuestState.QUEST_STATE_UNSTARTED) {
|
if (oldState == QuestState.QUEST_STATE_UNSTARTED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,9 @@ public class QuestManager extends BasePlayerManager {
|
|||||||
30700, // Quest which is responsible for unlocking Crash Course.
|
30700, // Quest which is responsible for unlocking Crash Course.
|
||||||
30800, // Quest which is responsible for unlocking Sparks Amongst the Pages.
|
30800, // Quest which is responsible for unlocking Sparks Amongst the Pages.
|
||||||
|
|
||||||
47001, 47002, 47003, 47004
|
47001, 47002, 47003, 47004,
|
||||||
|
|
||||||
|
2010103, 2010144 // Prologue Act 2: Chasing Shadows
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@ public class ContentAddQuestProgress extends BaseContent {
|
|||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
val progressId = condition.getParam()[0];
|
val progressId = condition.getParam()[0];
|
||||||
val currentCount = quest.getOwner().getPlayerProgress().getCurrentProgress(progressId);
|
val currentCount =
|
||||||
|
quest.getOwner().getPlayerProgress().getCurrentProgress(String.valueOf(progressId));
|
||||||
|
|
||||||
// if the condition count is 0 I think it is safe to assume that the
|
// if the condition count is 0 I think it is safe to assume that the
|
||||||
// condition count from EXEC only needs to be 1
|
// condition count from EXEC only needs to be 1
|
||||||
|
@ -3,8 +3,7 @@ package emu.grasscutter.game.quest.content;
|
|||||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_TALK;
|
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_TALK;
|
||||||
|
|
||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.*;
|
||||||
import emu.grasscutter.game.quest.QuestValueContent;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
|
||||||
@QuestValueContent(QUEST_CONTENT_COMPLETE_TALK)
|
@QuestValueContent(QUEST_CONTENT_COMPLETE_TALK)
|
||||||
|
@ -2,20 +2,16 @@ package emu.grasscutter.game.quest.content;
|
|||||||
|
|
||||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_FINISH_PLOT;
|
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_FINISH_PLOT;
|
||||||
|
|
||||||
import emu.grasscutter.data.binout.MainQuestData;
|
|
||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.*;
|
||||||
import emu.grasscutter.game.quest.QuestValueContent;
|
|
||||||
|
|
||||||
@QuestValueContent(QUEST_CONTENT_FINISH_PLOT)
|
@QuestValueContent(QUEST_CONTENT_FINISH_PLOT)
|
||||||
public class ContentFinishPlot extends BaseContent {
|
public class ContentFinishPlot extends BaseContent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
MainQuestData.TalkData talkData =
|
var talkData = quest.getMainQuest().getTalks().get(params[0]);
|
||||||
quest.getMainQuest().getTalks().get(Integer.valueOf(params[0]));
|
var subQuest = quest.getMainQuest().getChildQuestById(params[0]);
|
||||||
GameQuest subQuest = quest.getMainQuest().getChildQuestById(params[0]);
|
|
||||||
return (talkData != null && subQuest != null || condition.getParamStr().equals(paramStr))
|
return (talkData != null && subQuest != null || condition.getParamStr().equals(paramStr))
|
||||||
&& condition.getParam()[0] == params[0];
|
&& condition.getParam()[0] == params[0];
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ public class ContentLuaNotify extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
return condition.getParamStr().equals(paramStr);
|
return condition.getParamStr().equals(paramStr)
|
||||||
|
&& condition.getCount()
|
||||||
|
<= quest.getOwner().getPlayerProgress().getCurrentProgress(paramStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,22 +3,16 @@ package emu.grasscutter.game.quest.content;
|
|||||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_NOT_FINISH_PLOT;
|
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_NOT_FINISH_PLOT;
|
||||||
|
|
||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.*;
|
||||||
import emu.grasscutter.game.quest.QuestValueContent;
|
|
||||||
import lombok.val;
|
|
||||||
|
|
||||||
@QuestValueContent(QUEST_CONTENT_NOT_FINISH_PLOT)
|
@QuestValueContent(QUEST_CONTENT_NOT_FINISH_PLOT)
|
||||||
public class ContentNotFinishPlot extends BaseContent {
|
public class ContentNotFinishPlot extends BaseContent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
val talkId = condition.getParam()[0];
|
var talkData = quest.getMainQuest().getTalks().get(params[0]);
|
||||||
val checkMainQuest = quest.getOwner().getQuestManager().getMainQuestByTalkId(talkId);
|
var subQuest = quest.getMainQuest().getChildQuestById(params[0]);
|
||||||
if (checkMainQuest == null) {
|
return (talkData == null && subQuest != null || condition.getParamStr().equals(paramStr))
|
||||||
return true;
|
&& condition.getParam()[0] == params[0];
|
||||||
}
|
|
||||||
val talkData = checkMainQuest.getTalks().get(talkId);
|
|
||||||
return talkData == null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package emu.grasscutter.game.quest.exec;
|
package emu.grasscutter.game.quest.exec;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
|
||||||
import emu.grasscutter.data.excels.quest.QuestData;
|
import emu.grasscutter.data.excels.quest.QuestData;
|
||||||
import emu.grasscutter.game.quest.GameQuest;
|
import emu.grasscutter.game.quest.GameQuest;
|
||||||
import emu.grasscutter.game.quest.QuestValueExec;
|
import emu.grasscutter.game.quest.QuestValueExec;
|
||||||
@ -27,33 +26,16 @@ public class ExecNotifyGroupLua extends QuestExecHandler {
|
|||||||
}
|
}
|
||||||
scene.runWhenFinished(
|
scene.runWhenFinished(
|
||||||
() -> {
|
() -> {
|
||||||
val groupInstance = scriptManager.getGroupInstanceById(groupId);
|
|
||||||
|
|
||||||
if (groupInstance != null) {
|
|
||||||
// workaround to make sure the triggers are still there todo find better way of trigger
|
|
||||||
// handling
|
|
||||||
scriptManager.refreshGroup(groupInstance);
|
|
||||||
Grasscutter.getLogger()
|
|
||||||
.trace(
|
|
||||||
"group: {} \ncondition: {} \nparamStr {}",
|
|
||||||
groupInstance.getLuaGroup(),
|
|
||||||
condition,
|
|
||||||
paramStr);
|
|
||||||
} else {
|
|
||||||
Grasscutter.getLogger()
|
|
||||||
.debug(
|
|
||||||
"notify, no group instance for:\n group: {} \ncondition: {} \nparamStr {}",
|
|
||||||
groupId,
|
|
||||||
condition,
|
|
||||||
paramStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
val eventType =
|
val eventType =
|
||||||
quest.getState() == QuestState.QUEST_STATE_FINISHED
|
quest.getState() == QuestState.QUEST_STATE_FINISHED
|
||||||
? EventType.EVENT_QUEST_FINISH
|
? EventType.EVENT_QUEST_FINISH
|
||||||
: EventType.EVENT_QUEST_START;
|
: EventType.EVENT_QUEST_START;
|
||||||
scriptManager.callEvent(
|
scriptManager.callEvent(
|
||||||
new ScriptArgs(groupId, eventType, quest.getSubQuestId())
|
new ScriptArgs(
|
||||||
|
groupId,
|
||||||
|
eventType,
|
||||||
|
quest.getSubQuestId(),
|
||||||
|
quest.getState() == QuestState.QUEST_STATE_FINISHED ? 1 : 0)
|
||||||
.setEventSource(quest.getSubQuestId()));
|
.setEventSource(quest.getSubQuestId()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ public class ExecRefreshGroupSuite extends QuestExecHandler {
|
|||||||
if (!scriptManager.refreshGroupSuite(groupId, suiteId, quest)) {
|
if (!scriptManager.refreshGroupSuite(groupId, suiteId, quest)) {
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
scriptManager.getGroupById(groupId).dontUnload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
package emu.grasscutter.game.talk;
|
package emu.grasscutter.game.talk;
|
||||||
|
|
||||||
import static emu.grasscutter.game.quest.enums.QuestCond.QUEST_COND_COMPLETE_TALK;
|
import static emu.grasscutter.game.quest.enums.QuestCond.QUEST_COND_COMPLETE_TALK;
|
||||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_ANY_TALK;
|
import static emu.grasscutter.game.quest.enums.QuestContent.*;
|
||||||
import static emu.grasscutter.game.quest.enums.QuestContent.QUEST_CONTENT_COMPLETE_TALK;
|
|
||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.binout.MainQuestData.TalkData;
|
import emu.grasscutter.data.binout.MainQuestData.TalkData;
|
||||||
import emu.grasscutter.game.player.BasePlayerManager;
|
import emu.grasscutter.game.player.*;
|
||||||
import emu.grasscutter.game.player.Player;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
||||||
public final class TalkManager extends BasePlayerManager {
|
public final class TalkManager extends BasePlayerManager {
|
||||||
@ -22,30 +20,31 @@ public final class TalkManager extends BasePlayerManager {
|
|||||||
* @param npcEntityId The entity ID of the NPC being talked to.
|
* @param npcEntityId The entity ID of the NPC being talked to.
|
||||||
*/
|
*/
|
||||||
public void triggerTalkAction(int talkId, int npcEntityId) {
|
public void triggerTalkAction(int talkId, int npcEntityId) {
|
||||||
var talkData = GameData.getTalkConfigDataMap().get(talkId);
|
|
||||||
if (talkData == null) return;
|
|
||||||
|
|
||||||
var player = this.getPlayer();
|
var player = this.getPlayer();
|
||||||
// Check if the NPC id is valid.
|
|
||||||
var entity = player.getScene().getEntityById(npcEntityId);
|
|
||||||
if (entity != null) {
|
|
||||||
// The config ID of the entity is the NPC's ID.
|
|
||||||
if (!talkData.getNpcId().contains(entity.getConfigId())) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the talk action on associated handlers.
|
var talkData = GameData.getTalkConfigDataMap().get(talkId);
|
||||||
talkData
|
if (talkData != null) {
|
||||||
.getFinishExec()
|
// Check if the NPC id is valid.
|
||||||
.forEach(e -> player.getServer().getTalkSystem().triggerExec(player, talkData, e));
|
var entity = player.getScene().getEntityById(npcEntityId);
|
||||||
|
if (entity != null) {
|
||||||
|
// The config ID of the entity is the NPC's ID.
|
||||||
|
if (!talkData.getNpcId().contains(entity.getConfigId())) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the talk action on associated handlers.
|
||||||
|
talkData
|
||||||
|
.getFinishExec()
|
||||||
|
.forEach(e -> player.getServer().getTalkSystem().triggerExec(player, talkData, e));
|
||||||
|
|
||||||
|
// Save the talk value to the quest's data.
|
||||||
|
this.saveTalkToQuest(talkId, talkData.getQuestId());
|
||||||
|
}
|
||||||
|
|
||||||
// Invoke the talking events for quests.
|
// Invoke the talking events for quests.
|
||||||
var questManager = player.getQuestManager();
|
var questManager = player.getQuestManager();
|
||||||
questManager.queueEvent(QUEST_CONTENT_COMPLETE_ANY_TALK, talkId);
|
questManager.queueEvent(QUEST_CONTENT_COMPLETE_ANY_TALK, talkId);
|
||||||
questManager.queueEvent(QUEST_CONTENT_COMPLETE_TALK, talkId);
|
questManager.queueEvent(QUEST_CONTENT_COMPLETE_TALK, talkId);
|
||||||
questManager.queueEvent(QUEST_COND_COMPLETE_TALK, talkId);
|
questManager.queueEvent(QUEST_COND_COMPLETE_TALK, talkId);
|
||||||
|
|
||||||
// Save the talk value to the quest's data.
|
|
||||||
this.saveTalkToQuest(talkId, talkData.getQuestId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveTalkToQuest(int talkId, int mainQuestId) {
|
public void saveTalkToQuest(int talkId, int mainQuestId) {
|
||||||
|
@ -1,54 +1,43 @@
|
|||||||
package emu.grasscutter.game.world;
|
package emu.grasscutter.game.world;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.*;
|
||||||
import emu.grasscutter.data.GameDepot;
|
|
||||||
import emu.grasscutter.data.binout.SceneNpcBornEntry;
|
import emu.grasscutter.data.binout.SceneNpcBornEntry;
|
||||||
import emu.grasscutter.data.binout.routes.Route;
|
import emu.grasscutter.data.binout.routes.Route;
|
||||||
import emu.grasscutter.data.excels.ItemData;
|
import emu.grasscutter.data.excels.*;
|
||||||
import emu.grasscutter.data.excels.SceneData;
|
|
||||||
import emu.grasscutter.data.excels.codex.CodexAnimalData;
|
import emu.grasscutter.data.excels.codex.CodexAnimalData;
|
||||||
import emu.grasscutter.data.excels.monster.MonsterData;
|
import emu.grasscutter.data.excels.monster.MonsterData;
|
||||||
import emu.grasscutter.data.excels.world.WorldLevelData;
|
import emu.grasscutter.data.excels.world.WorldLevelData;
|
||||||
import emu.grasscutter.data.server.Grid;
|
import emu.grasscutter.data.server.Grid;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.dungeons.DungeonManager;
|
import emu.grasscutter.game.dungeons.*;
|
||||||
import emu.grasscutter.game.dungeons.DungeonSettleListener;
|
|
||||||
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
import emu.grasscutter.game.dungeons.challenge.WorldChallenge;
|
||||||
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
||||||
import emu.grasscutter.game.entity.*;
|
import emu.grasscutter.game.entity.*;
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
import emu.grasscutter.game.managers.blossom.BlossomManager;
|
import emu.grasscutter.game.managers.blossom.BlossomManager;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.*;
|
||||||
import emu.grasscutter.game.player.TeamInfo;
|
|
||||||
import emu.grasscutter.game.props.*;
|
import emu.grasscutter.game.props.*;
|
||||||
import emu.grasscutter.game.quest.QuestGroupSuite;
|
import emu.grasscutter.game.quest.QuestGroupSuite;
|
||||||
import emu.grasscutter.game.world.data.TeleportProperties;
|
import emu.grasscutter.game.world.data.TeleportProperties;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
|
import emu.grasscutter.net.proto.*;
|
||||||
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult;
|
||||||
import emu.grasscutter.net.proto.EnterTypeOuterClass;
|
|
||||||
import emu.grasscutter.net.proto.SelectWorktopOptionReqOuterClass;
|
|
||||||
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
||||||
import emu.grasscutter.scripts.SceneIndexManager;
|
import emu.grasscutter.scripts.*;
|
||||||
import emu.grasscutter.scripts.SceneScriptManager;
|
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
import emu.grasscutter.scripts.data.SceneBlock;
|
import emu.grasscutter.scripts.data.*;
|
||||||
import emu.grasscutter.scripts.data.SceneGroup;
|
|
||||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
|
||||||
import emu.grasscutter.server.event.entity.EntityCreationEvent;
|
import emu.grasscutter.server.event.entity.EntityCreationEvent;
|
||||||
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
import emu.grasscutter.utils.objects.KahnsSort;
|
import emu.grasscutter.utils.objects.KahnsSort;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import lombok.Getter;
|
import lombok.*;
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.val;
|
|
||||||
|
|
||||||
public final class Scene {
|
public final class Scene {
|
||||||
@Getter private final World world;
|
@Getter private final World world;
|
||||||
@ -551,19 +540,22 @@ public final class Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var sceneTime = getSceneTimeSeconds();
|
var sceneTime = getSceneTimeSeconds();
|
||||||
getEntities().forEach((eid, e) -> e.onTick(sceneTime));
|
|
||||||
|
var entities = Map.copyOf(this.getEntities());
|
||||||
|
entities.forEach(
|
||||||
|
(eid, e) -> {
|
||||||
|
if (!e.isAlive()) {
|
||||||
|
this.getEntities().remove(eid);
|
||||||
|
} else e.onTick(sceneTime);
|
||||||
|
});
|
||||||
|
|
||||||
blossomManager.onTick();
|
blossomManager.onTick();
|
||||||
|
|
||||||
checkNpcGroup();
|
this.checkNpcGroup();
|
||||||
|
|
||||||
this.finishLoading();
|
this.finishLoading();
|
||||||
this.checkPlayerRespawn();
|
this.checkPlayerRespawn();
|
||||||
if (this.tickCount++ % 10 == 0) this.broadcastPacket(new PacketSceneTimeNotify(this));
|
if (this.tickCount++ % 10 == 0) this.broadcastPacket(new PacketSceneTimeNotify(this));
|
||||||
if (this.getPlayerCount() <= 0 && !this.dontDestroyWhenEmpty) {
|
|
||||||
this.getScriptManager().onDestroy();
|
|
||||||
this.getWorld().deregisterScene(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Validates a player's current position. Teleports the player if the player is out of bounds. */
|
/** Validates a player's current position. Teleports the player if the player is out of bounds. */
|
||||||
@ -700,18 +692,6 @@ public final class Scene {
|
|||||||
npcBornEntries.addAll(loadNpcForPlayer(player));
|
npcBornEntries.addAll(loadNpcForPlayer(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the unreachable group for client
|
|
||||||
var toUnload =
|
|
||||||
this.npcBornEntrySet.stream()
|
|
||||||
.filter(i -> !npcBornEntries.contains(i))
|
|
||||||
.map(SceneNpcBornEntry::getGroupId)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
if (toUnload.size() > 0) {
|
|
||||||
broadcastPacket(new PacketGroupUnloadNotify(toUnload));
|
|
||||||
Grasscutter.getLogger().trace("Unload NPC Group {}", toUnload);
|
|
||||||
}
|
|
||||||
// exchange the new npcBornEntry Set
|
|
||||||
this.npcBornEntrySet = npcBornEntries;
|
this.npcBornEntrySet = npcBornEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -858,7 +838,7 @@ public final class Scene {
|
|||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
for (var group : this.loadedGroups) {
|
for (var group : this.loadedGroups) {
|
||||||
if (!visible.contains(group.id) && !group.dynamic_load)
|
if (!visible.contains(group.id) && !group.dynamic_load && !group.dontUnload)
|
||||||
unloadGroup(scriptManager.getBlocks().get(group.block_id), group.id);
|
unloadGroup(scriptManager.getBlocks().get(group.block_id), group.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1164,14 +1144,27 @@ public final class Scene {
|
|||||||
pos.toDoubleArray(),
|
pos.toDoubleArray(),
|
||||||
Grasscutter.getConfig().server.game.loadEntitiesForPlayerRange);
|
Grasscutter.getConfig().server.game.loadEntitiesForPlayerRange);
|
||||||
|
|
||||||
var sceneNpcBornEntries =
|
var sceneNpcBornCanidates =
|
||||||
npcList.stream().filter(i -> !this.npcBornEntrySet.contains(i)).toList();
|
npcList.stream().filter(i -> !this.npcBornEntrySet.contains(i)).toList();
|
||||||
|
|
||||||
|
List<SceneNpcBornEntry> sceneNpcBornEntries = new ArrayList<>();
|
||||||
|
sceneNpcBornCanidates.forEach(
|
||||||
|
i -> {
|
||||||
|
var groupInstance = scriptManager.getGroupInstanceById(i.getGroupId());
|
||||||
|
if (groupInstance == null) return;
|
||||||
|
if (i.getSuiteIdList() != null
|
||||||
|
&& !i.getSuiteIdList().contains(groupInstance.getActiveSuiteId())) return;
|
||||||
|
sceneNpcBornEntries.add(i);
|
||||||
|
});
|
||||||
|
|
||||||
if (sceneNpcBornEntries.size() > 0) {
|
if (sceneNpcBornEntries.size() > 0) {
|
||||||
this.broadcastPacket(new PacketGroupSuiteNotify(sceneNpcBornEntries));
|
this.broadcastPacket(new PacketGroupSuiteNotify(sceneNpcBornEntries));
|
||||||
Grasscutter.getLogger().trace("Loaded Npc Group Suite {}", sceneNpcBornEntries);
|
Grasscutter.getLogger().trace("Loaded Npc Group Suite {}", sceneNpcBornEntries);
|
||||||
}
|
}
|
||||||
return npcList;
|
|
||||||
|
return npcList.stream()
|
||||||
|
.filter(i -> this.npcBornEntrySet.contains(i) || sceneNpcBornEntries.contains(i))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadGroupForQuest(List<QuestGroupSuite> sceneGroupSuite) {
|
public void loadGroupForQuest(List<QuestGroupSuite> sceneGroupSuite) {
|
||||||
|
@ -4,17 +4,14 @@ import static emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportTy
|
|||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.excels.dungeon.DungeonData;
|
import emu.grasscutter.data.excels.dungeon.DungeonData;
|
||||||
import emu.grasscutter.game.entity.EntityTeam;
|
import emu.grasscutter.game.entity.*;
|
||||||
import emu.grasscutter.game.entity.EntityWorld;
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.player.Player.SceneLoadState;
|
import emu.grasscutter.game.player.Player.SceneLoadState;
|
||||||
import emu.grasscutter.game.props.EnterReason;
|
import emu.grasscutter.game.props.*;
|
||||||
import emu.grasscutter.game.props.EntityIdType;
|
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
|
||||||
import emu.grasscutter.game.props.SceneType;
|
|
||||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
import emu.grasscutter.game.quest.enums.QuestContent;
|
||||||
import emu.grasscutter.game.world.data.TeleportProperties;
|
import emu.grasscutter.game.world.data.TeleportProperties;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
|
import emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo.*;
|
||||||
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
|
import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType;
|
||||||
import emu.grasscutter.scripts.data.SceneConfig;
|
import emu.grasscutter.scripts.data.SceneConfig;
|
||||||
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
||||||
@ -22,15 +19,9 @@ import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
|
|||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
import emu.grasscutter.utils.ConversionUtils;
|
import emu.grasscutter.utils.ConversionUtils;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMaps;
|
import java.util.*;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import lombok.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.val;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class World implements Iterable<Player> {
|
public class World implements Iterable<Player> {
|
||||||
@ -44,7 +35,8 @@ public class World implements Iterable<Player> {
|
|||||||
private int nextPeerId = 0;
|
private int nextPeerId = 0;
|
||||||
private int worldLevel;
|
private int worldLevel;
|
||||||
|
|
||||||
@Getter private boolean isMultiplayer, timeLocked = false;
|
@Getter private boolean isMultiplayer = false;
|
||||||
|
@Getter private boolean timeLocked;
|
||||||
|
|
||||||
private long lastUpdateTime;
|
private long lastUpdateTime;
|
||||||
@Getter private int tickCount = 0;
|
@Getter private int tickCount = 0;
|
||||||
@ -65,6 +57,7 @@ public class World implements Iterable<Player> {
|
|||||||
this.entity = new EntityWorld(this);
|
this.entity = new EntityWorld(this);
|
||||||
this.worldLevel = player.getWorldLevel();
|
this.worldLevel = player.getWorldLevel();
|
||||||
this.isMultiplayer = isMultiplayer;
|
this.isMultiplayer = isMultiplayer;
|
||||||
|
this.timeLocked = player.getProperty(PlayerProperty.PROP_IS_GAME_TIME_LOCKED) != 0;
|
||||||
|
|
||||||
this.lastUpdateTime = System.currentTimeMillis();
|
this.lastUpdateTime = System.currentTimeMillis();
|
||||||
this.currentWorldTime = host.getPlayerGameTime();
|
this.currentWorldTime = host.getPlayerGameTime();
|
||||||
@ -164,6 +157,16 @@ public class World implements Iterable<Player> {
|
|||||||
player.getTeamManager().getCurrentSinglePlayerTeamInfo(),
|
player.getTeamManager().getCurrentSinglePlayerTeamInfo(),
|
||||||
player.getTeamManager().getMaxTeamSize());
|
player.getTeamManager().getMaxTeamSize());
|
||||||
player.getTeamManager().setCurrentCharacterIndex(0);
|
player.getTeamManager().setCurrentCharacterIndex(0);
|
||||||
|
|
||||||
|
if (player != this.getHost()) {
|
||||||
|
this.broadcastPacket(
|
||||||
|
new PacketPlayerChatNotify(
|
||||||
|
player,
|
||||||
|
0,
|
||||||
|
SystemHint.newBuilder()
|
||||||
|
.setType(SystemHintType.SYSTEM_HINT_TYPE_CHAT_ENTER_WORLD.getNumber())
|
||||||
|
.build()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to scene
|
// Add to scene
|
||||||
@ -217,6 +220,14 @@ public class World implements Iterable<Player> {
|
|||||||
victim.getSceneId(),
|
victim.getSceneId(),
|
||||||
victim.getPosition()));
|
victim.getPosition()));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.broadcastPacket(
|
||||||
|
new PacketPlayerChatNotify(
|
||||||
|
player,
|
||||||
|
0,
|
||||||
|
SystemHint.newBuilder()
|
||||||
|
.setType(SystemHintType.SYSTEM_HINT_TYPE_CHAT_LEAVE_WORLD.getNumber())
|
||||||
|
.build()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +437,11 @@ public class World implements Iterable<Player> {
|
|||||||
// Check if there are players in this world.
|
// Check if there are players in this world.
|
||||||
if (this.getPlayerCount() == 0) return true;
|
if (this.getPlayerCount() == 0) return true;
|
||||||
// Tick all associated scenes.
|
// Tick all associated scenes.
|
||||||
this.getScenes().forEach((k, scene) -> scene.onTick());
|
this.getScenes()
|
||||||
|
.forEach(
|
||||||
|
(k, scene) -> {
|
||||||
|
if (scene.getPlayerCount() > 0) scene.onTick();
|
||||||
|
});
|
||||||
|
|
||||||
// sync time every 10 seconds
|
// sync time every 10 seconds
|
||||||
if (this.tickCount % 10 == 0) {
|
if (this.tickCount % 10 == 0) {
|
||||||
@ -512,10 +527,6 @@ public class World implements Iterable<Player> {
|
|||||||
*/
|
*/
|
||||||
public void changeTime(long gameTime) {
|
public void changeTime(long gameTime) {
|
||||||
this.currentWorldTime = gameTime;
|
this.currentWorldTime = gameTime;
|
||||||
|
|
||||||
// Trigger script events.
|
|
||||||
this.players.forEach(
|
|
||||||
player -> player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_GAME_TIME_TICK));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,7 +81,7 @@ public final class PluginManager {
|
|||||||
if (pluginConfig.api == null) {
|
if (pluginConfig.api == null) {
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.warn(translate("plugin.invalid_api.not_present", plugin.getName()));
|
.warn(translate("plugin.invalid_api.not_present", plugin.getName()));
|
||||||
return;
|
continue;
|
||||||
} else if (pluginConfig.api != API_VERSION) {
|
} else if (pluginConfig.api != API_VERSION) {
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.warn(
|
.warn(
|
||||||
@ -90,13 +90,13 @@ public final class PluginManager {
|
|||||||
plugin.getName(),
|
plugin.getName(),
|
||||||
pluginConfig.api,
|
pluginConfig.api,
|
||||||
API_VERSION));
|
API_VERSION));
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the plugin config is valid.
|
// Check if the plugin config is valid.
|
||||||
if (!pluginConfig.validate()) {
|
if (!pluginConfig.validate()) {
|
||||||
Grasscutter.getLogger().warn(translate("plugin.invalid_config", plugin.getName()));
|
Grasscutter.getLogger().warn(translate("plugin.invalid_config", plugin.getName()));
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a JAR file instance from the plugin's URL.
|
// Create a JAR file instance from the plugin's URL.
|
||||||
@ -216,9 +216,14 @@ public final class PluginManager {
|
|||||||
Grasscutter.getLogger().info(translate("plugin.enabling_plugin", name));
|
Grasscutter.getLogger().info(translate("plugin.enabling_plugin", name));
|
||||||
try {
|
try {
|
||||||
plugin.onEnable();
|
plugin.onEnable();
|
||||||
|
return;
|
||||||
|
} catch (NoSuchMethodError ignored) {
|
||||||
|
Grasscutter.getLogger().error(translate("plugin.invalid_api.outdated", name));
|
||||||
} catch (Throwable exception) {
|
} catch (Throwable exception) {
|
||||||
Grasscutter.getLogger().error(translate("plugin.enabling_failed", name), exception);
|
Grasscutter.getLogger().error(translate("plugin.enabling_failed", name), exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.disablePlugin(plugin);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,15 +266,15 @@ public class SceneScriptManager {
|
|||||||
suiteId,
|
suiteId,
|
||||||
groupId,
|
groupId,
|
||||||
getScene().getId());
|
getScene().getId());
|
||||||
} else {
|
if (targetGroupInstance == null) return false;
|
||||||
Grasscutter.getLogger().debug("Refreshing group {} suite {}", groupId, suiteId);
|
|
||||||
suiteId =
|
|
||||||
refreshGroup(
|
|
||||||
targetGroupInstance,
|
|
||||||
suiteId,
|
|
||||||
false); // If suiteId is zero, the value of suiteId changes
|
|
||||||
scene.broadcastPacket(new PacketGroupSuiteNotify(groupId, suiteId));
|
|
||||||
}
|
}
|
||||||
|
Grasscutter.getLogger().debug("Refreshing group {} suite {}", groupId, suiteId);
|
||||||
|
suiteId =
|
||||||
|
refreshGroup(
|
||||||
|
targetGroupInstance,
|
||||||
|
suiteId,
|
||||||
|
false); // If suiteId is zero, the value of suiteId changes
|
||||||
|
scene.broadcastPacket(new PacketGroupSuiteNotify(groupId, suiteId));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -629,7 +629,7 @@ public class SceneScriptManager {
|
|||||||
getScene().getEntities().values().stream()
|
getScene().getEntities().values().stream()
|
||||||
.filter(
|
.filter(
|
||||||
e ->
|
e ->
|
||||||
e.getEntityType() == EntityType.Avatar.getValue()
|
e.getEntityType() == EntityType.Avatar
|
||||||
&& region.getMetaRegion().contains(e.getPosition()))
|
&& region.getMetaRegion().contains(e.getPosition()))
|
||||||
.toList();
|
.toList();
|
||||||
entities.forEach(region::addEntity);
|
entities.forEach(region::addEntity);
|
||||||
@ -644,6 +644,7 @@ public class SceneScriptManager {
|
|||||||
.trace("Call EVENT_ENTER_REGION_{}", region.getMetaRegion().config_id);
|
.trace("Call EVENT_ENTER_REGION_{}", region.getMetaRegion().config_id);
|
||||||
this.callEvent(
|
this.callEvent(
|
||||||
new ScriptArgs(region.getGroupId(), EventType.EVENT_ENTER_REGION, region.getConfigId())
|
new ScriptArgs(region.getGroupId(), EventType.EVENT_ENTER_REGION, region.getConfigId())
|
||||||
|
.setEventSource(EntityType.Avatar.getValue())
|
||||||
.setSourceEntityId(region.getId())
|
.setSourceEntityId(region.getId())
|
||||||
.setTargetEntityId(targetId));
|
.setTargetEntityId(targetId));
|
||||||
|
|
||||||
@ -660,6 +661,7 @@ public class SceneScriptManager {
|
|||||||
if (region.entityHasLeft()) {
|
if (region.entityHasLeft()) {
|
||||||
this.callEvent(
|
this.callEvent(
|
||||||
new ScriptArgs(region.getGroupId(), EventType.EVENT_LEAVE_REGION, region.getConfigId())
|
new ScriptArgs(region.getGroupId(), EventType.EVENT_LEAVE_REGION, region.getConfigId())
|
||||||
|
.setEventSource(EntityType.Avatar.getValue())
|
||||||
.setSourceEntityId(region.getId())
|
.setSourceEntityId(region.getId())
|
||||||
.setTargetEntityId(region.getFirstEntityId()));
|
.setTargetEntityId(region.getFirstEntityId()));
|
||||||
|
|
||||||
@ -681,8 +683,8 @@ public class SceneScriptManager {
|
|||||||
|| !groupInstance.getDeadEntities().contains(m.config_id));
|
|| !groupInstance.getDeadEntities().contains(m.config_id));
|
||||||
})
|
})
|
||||||
.map(g -> createGadget(group.id, group.block_id, g, groupInstance.getCachedGadgetState(g)))
|
.map(g -> createGadget(group.id, group.block_id, g, groupInstance.getCachedGadgetState(g)))
|
||||||
.peek(g -> groupInstance.cacheGadgetState(g.getMetaGadget(), g.getState()))
|
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
|
.peek(g -> groupInstance.cacheGadgetState(g.getMetaGadget(), g.getState()))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -801,26 +803,27 @@ public class SceneScriptManager {
|
|||||||
private void realCallEvent(@Nonnull ScriptArgs params) {
|
private void realCallEvent(@Nonnull ScriptArgs params) {
|
||||||
try {
|
try {
|
||||||
ScriptLoader.getScriptLib().setSceneScriptManager(this);
|
ScriptLoader.getScriptLib().setSceneScriptManager(this);
|
||||||
int eventType = params.type;
|
|
||||||
Set<SceneTrigger> relevantTriggers = new HashSet<>();
|
var eventType = params.type;
|
||||||
if (eventType == EventType.EVENT_ENTER_REGION || eventType == EventType.EVENT_LEAVE_REGION) {
|
var relevantTriggers =
|
||||||
relevantTriggers =
|
switch (eventType) {
|
||||||
this.getTriggersByEvent(eventType).stream()
|
case EventType.EVENT_ENTER_REGION, EventType.EVENT_LEAVE_REGION -> this
|
||||||
|
.getTriggersByEvent(eventType)
|
||||||
|
.stream()
|
||||||
.filter(
|
.filter(
|
||||||
t ->
|
t ->
|
||||||
t.getCondition().contains(String.valueOf(params.param1))
|
t.getName().substring(13).equals(String.valueOf(params.param1))
|
||||||
&& (t.getSource().isEmpty()
|
&& (t.getSource().isEmpty()
|
||||||
|| t.getSource().equals(params.getEventSource())))
|
|| t.getSource().equals(params.getEventSource())))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
} else {
|
default -> this.getTriggersByEvent(eventType).stream()
|
||||||
relevantTriggers =
|
|
||||||
this.getTriggersByEvent(eventType).stream()
|
|
||||||
.filter(
|
.filter(
|
||||||
t -> params.getGroupId() == 0 || t.getCurrentGroup().id == params.getGroupId())
|
t -> params.getGroupId() == 0 || t.getCurrentGroup().id == params.getGroupId())
|
||||||
.filter(
|
.filter(
|
||||||
t -> (t.getSource().isEmpty() || t.getSource().equals(params.getEventSource())))
|
t -> (t.getSource().isEmpty() || t.getSource().equals(params.getEventSource())))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
};
|
||||||
|
|
||||||
for (SceneTrigger trigger : relevantTriggers) {
|
for (SceneTrigger trigger : relevantTriggers) {
|
||||||
handleEventForTrigger(params, trigger);
|
handleEventForTrigger(params, trigger);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import emu.grasscutter.game.quest.enums.QuestContent;
|
|||||||
import emu.grasscutter.game.quest.enums.QuestState;
|
import emu.grasscutter.game.quest.enums.QuestState;
|
||||||
import emu.grasscutter.game.world.SceneGroupInstance;
|
import emu.grasscutter.game.world.SceneGroupInstance;
|
||||||
import emu.grasscutter.net.proto.EnterTypeOuterClass;
|
import emu.grasscutter.net.proto.EnterTypeOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
import emu.grasscutter.scripts.constants.GroupKillPolicy;
|
import emu.grasscutter.scripts.constants.GroupKillPolicy;
|
||||||
import emu.grasscutter.scripts.data.SceneGroup;
|
import emu.grasscutter.scripts.data.SceneGroup;
|
||||||
@ -129,7 +130,7 @@ public class ScriptLib {
|
|||||||
|
|
||||||
public int SetWorktopOptionsByGroupId(int groupId, int configId, int[] options) {
|
public int SetWorktopOptionsByGroupId(int groupId, int configId, int[] options) {
|
||||||
logger.debug("[LUA] Call SetWorktopOptionsByGroupId with {},{},{}",
|
logger.debug("[LUA] Call SetWorktopOptionsByGroupId with {},{},{}",
|
||||||
groupId,configId,options);
|
groupId, configId, options);
|
||||||
|
|
||||||
val entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
|
val entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
|
||||||
|
|
||||||
@ -152,18 +153,17 @@ public class ScriptLib {
|
|||||||
logger.debug("[LUA] Call SetWorktopOptions with {}", printTable(table));
|
logger.debug("[LUA] Call SetWorktopOptions with {}", printTable(table));
|
||||||
var callParams = this.callParams.getIfExists();
|
var callParams = this.callParams.getIfExists();
|
||||||
var group = this.currentGroup.getIfExists();
|
var group = this.currentGroup.getIfExists();
|
||||||
if(callParams == null || group == null){
|
if (callParams == null || group == null) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
var configId = callParams.param1;
|
var configId = callParams.param1;
|
||||||
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
|
var entity = getSceneScriptManager().getScene().getEntityByConfigId(configId);
|
||||||
|
|
||||||
|
var worktopOptions = new int[table.length()];
|
||||||
int[] worktopOptions = new int[table.length()];
|
for (int i = 1; i<=table.length(); i++) {
|
||||||
for(int i = 1 ;i<=table.length() ;i++){
|
|
||||||
worktopOptions[i-1] = table.get(i).optint(-1);
|
worktopOptions[i-1] = table.get(i).optint(-1);
|
||||||
}
|
}
|
||||||
if(!(entity instanceof EntityGadget gadget)|| worktopOptions.length == 0){
|
if (!(entity instanceof EntityGadget gadget) || worktopOptions.length == 0) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,9 +172,11 @@ public class ScriptLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
worktop.addWorktopOptions(worktopOptions);
|
worktop.addWorktopOptions(worktopOptions);
|
||||||
|
var scene = this.getSceneScriptManager().getScene();
|
||||||
var scene = getSceneScriptManager().getScene();
|
// Done in order to synchronize with addEntities in Scene.class.
|
||||||
scene.broadcastPacket(new PacketWorktopOptionNotify(gadget));
|
synchronized (this.getSceneScriptManager().getScene()) {
|
||||||
|
scene.broadcastPacket(new PacketWorktopOptionNotify(gadget));
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +403,7 @@ public class ScriptLib {
|
|||||||
|
|
||||||
val old = variables.getOrDefault(var, value);
|
val old = variables.getOrDefault(var, value);
|
||||||
variables.put(var, value);
|
variables.put(var, value);
|
||||||
getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, value, old));
|
getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, value, old).setEventSource(var));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,7 +418,7 @@ public class ScriptLib {
|
|||||||
variables.put(var, old + value);
|
variables.put(var, old + value);
|
||||||
logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}",
|
logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}",
|
||||||
old, old+value);
|
old, old+value);
|
||||||
getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, old+value, old));
|
getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, old+value, old).setEventSource(var));
|
||||||
return LuaValue.ZERO;
|
return LuaValue.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,6 +611,11 @@ public class ScriptLib {
|
|||||||
logger.debug("[LUA] Call CreateGadget with {}",
|
logger.debug("[LUA] Call CreateGadget with {}",
|
||||||
printTable(table));
|
printTable(table));
|
||||||
var configId = table.get("config_id").toint();
|
var configId = table.get("config_id").toint();
|
||||||
|
//TODO: figure out what creating gadget configId 0 does
|
||||||
|
if (configId == 0){
|
||||||
|
Grasscutter.getLogger().warn("Tried to CreateGadget with config_id 0: {}", printTable(table));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
var group = getCurrentGroup();
|
var group = getCurrentGroup();
|
||||||
|
|
||||||
@ -667,6 +674,7 @@ public class ScriptLib {
|
|||||||
var1);
|
var1);
|
||||||
|
|
||||||
for(var player : getSceneScriptManager().getScene().getPlayers()){
|
for(var player : getSceneScriptManager().getScene().getPlayers()){
|
||||||
|
player.getPlayerProgress().addToCurrentProgress(var1, 1);
|
||||||
player.getQuestManager().queueEvent(QuestCond.QUEST_COND_LUA_NOTIFY, var1);
|
player.getQuestManager().queueEvent(QuestCond.QUEST_COND_LUA_NOTIFY, var1);
|
||||||
player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_LUA_NOTIFY, var1);
|
player.getQuestManager().queueEvent(QuestContent.QUEST_CONTENT_LUA_NOTIFY, var1);
|
||||||
}
|
}
|
||||||
@ -702,7 +710,7 @@ public class ScriptLib {
|
|||||||
return EntityType.None.getValue();
|
return EntityType.None.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
return entity.getEntityType();
|
return entity.getEntityType().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetQuestState(int entityId, int questId){
|
public int GetQuestState(int entityId, int questId){
|
||||||
@ -737,11 +745,11 @@ public class ScriptLib {
|
|||||||
|
|
||||||
val entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
|
val entity = getSceneScriptManager().getScene().getEntityByConfigId(configId, groupId);
|
||||||
|
|
||||||
if(entity == null || entity.getEntityType() != entityType){
|
if(entity == null || entity.getEntityType().getValue() != entityType){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSceneScriptManager().getScene().removeEntity(entity);
|
getSceneScriptManager().getScene().removeEntity(entity, VisionType.VISION_TYPE_REMOVE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -815,17 +823,17 @@ public class ScriptLib {
|
|||||||
//TODO implement
|
//TODO implement
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
public int IsPlayerAllAvatarDie(int sceneUid){
|
public boolean IsPlayerAllAvatarDie(int sceneUid){
|
||||||
logger.warn("[LUA] Call unimplemented IsPlayerAllAvatarDie {}", sceneUid);
|
logger.warn("[LUA] Call unimplemented IsPlayerAllAvatarDie {}", sceneUid);
|
||||||
var playerEntities = getSceneScriptManager().getScene().getEntities().values().stream().filter(e -> e.getEntityType() == EntityIdType.AVATAR.getId()).toList();
|
var playerEntities = getSceneScriptManager().getScene().getEntities().values().stream().filter(e -> e.getEntityType() == EntityType.Avatar).toList();
|
||||||
for (GameEntity p : playerEntities){
|
for (GameEntity p : playerEntities){
|
||||||
var player = (EntityAvatar)p;
|
var player = (EntityAvatar)p;
|
||||||
if(player.isAlive()){
|
if(player.isAlive()){
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO check
|
//TODO check
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int sendShowCommonTipsToClient(String title, String content, int closeTime) {
|
public int sendShowCommonTipsToClient(String title, String content, int closeTime) {
|
||||||
@ -861,6 +869,11 @@ public class ScriptLib {
|
|||||||
//TODO implement var6 object has int success, int fail, bool fail_on_wipe
|
//TODO implement var6 object has int success, int fail, bool fail_on_wipe
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
public int StopChallenge(int var1, int var2){
|
||||||
|
logger.warn("[LUA] Call unimplemented StopChallenge with {} {}", var1, var2);
|
||||||
|
//TODO implement
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
public int CreateEffigyChallengeMonster(int var1, int[] var2){
|
public int CreateEffigyChallengeMonster(int var1, int[] var2){
|
||||||
logger.warn("[LUA] Call unimplemented CreateEffigyChallengeMonster with {} {}", var1, var2);
|
logger.warn("[LUA] Call unimplemented CreateEffigyChallengeMonster with {} {}", var1, var2);
|
||||||
//TODO implement
|
//TODO implement
|
||||||
@ -1598,6 +1611,16 @@ public class ScriptLib {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int DropSubfield(LuaTable table) {
|
||||||
|
String subfield_name = table.get("subfield_name").toString();
|
||||||
|
var entity = getCurrentEntity();
|
||||||
|
if(!entity.isPresent()) return -1;
|
||||||
|
|
||||||
|
entity.get().dropSubfield(subfield_name);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
public int[] GetGatherConfigIdList() {
|
public int[] GetGatherConfigIdList() {
|
||||||
EntityGadget gadget = getCurrentEntityGadget();
|
EntityGadget gadget = getCurrentEntityGadget();
|
||||||
|
|
||||||
|
@ -3,5 +3,8 @@ package emu.grasscutter.scripts.constants;
|
|||||||
public enum VisionLevelType {
|
public enum VisionLevelType {
|
||||||
VISION_LEVEL_NORMAL,
|
VISION_LEVEL_NORMAL,
|
||||||
VISION_LEVEL_LITTLE_REMOTE,
|
VISION_LEVEL_LITTLE_REMOTE,
|
||||||
VISION_LEVEL_REMOTE
|
VISION_LEVEL_REMOTE,
|
||||||
|
VISION_LEVEL_SUPER,
|
||||||
|
VISION_LEVEL_NEARBY,
|
||||||
|
VISION_LEVEL_SUPER_NEARBY
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ public final class SceneGroup {
|
|||||||
public SceneGarbage garbages;
|
public SceneGarbage garbages;
|
||||||
public SceneInitConfig init_config;
|
public SceneInitConfig init_config;
|
||||||
@Getter public boolean dynamic_load = false;
|
@Getter public boolean dynamic_load = false;
|
||||||
|
public boolean dontUnload = false;
|
||||||
|
|
||||||
public SceneReplaceable is_replaceable;
|
public SceneReplaceable is_replaceable;
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ public class SceneRegion {
|
|||||||
public boolean contains(Position position) {
|
public boolean contains(Position position) {
|
||||||
switch (shape) {
|
switch (shape) {
|
||||||
case ScriptRegionShape.CUBIC:
|
case ScriptRegionShape.CUBIC:
|
||||||
return (Math.abs(pos.getX() - position.getX()) <= size.getX())
|
return (Math.abs(pos.getX() - position.getX()) <= size.getX() / 2f)
|
||||||
&& (Math.abs(pos.getY() - position.getY()) <= size.getY())
|
&& (Math.abs(pos.getY() - position.getY()) <= size.getY() / 2f)
|
||||||
&& (Math.abs(pos.getZ() - position.getZ()) <= size.getZ());
|
&& (Math.abs(pos.getZ() - position.getZ()) <= size.getZ() / 2f);
|
||||||
case ScriptRegionShape.SPHERE:
|
case ScriptRegionShape.SPHERE:
|
||||||
var x = Math.pow(pos.getX() - position.getX(), 2);
|
var x = Math.pow(pos.getX() - position.getX(), 2);
|
||||||
var y = Math.pow(pos.getY() - position.getY(), 2);
|
var y = Math.pow(pos.getY() - position.getY(), 2);
|
||||||
|
@ -27,7 +27,7 @@ public final class SceneTrigger {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return name.hashCode();
|
return (currentGroup.id + name).hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,10 +32,11 @@ import emu.grasscutter.server.event.internal.*;
|
|||||||
import emu.grasscutter.server.event.types.ServerEvent;
|
import emu.grasscutter.server.event.types.ServerEvent;
|
||||||
import emu.grasscutter.server.scheduler.ServerTaskScheduler;
|
import emu.grasscutter.server.scheduler.ServerTaskScheduler;
|
||||||
import emu.grasscutter.task.TaskMap;
|
import emu.grasscutter.task.TaskMap;
|
||||||
|
import emu.grasscutter.utils.Utils;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.time.*;
|
import java.time.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.*;
|
||||||
import kcp.highway.*;
|
import kcp.highway.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -163,9 +164,6 @@ public final class GameServer extends KcpServer implements Iterable<Player> {
|
|||||||
|
|
||||||
// Chata manager
|
// Chata manager
|
||||||
this.chatManager = new ChatSystem(this);
|
this.chatManager = new ChatSystem(this);
|
||||||
|
|
||||||
// Hook into shutdown event.
|
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InetSocketAddress getAdapterInetSocketAddress() {
|
private static InetSocketAddress getAdapterInetSocketAddress() {
|
||||||
@ -326,16 +324,27 @@ public final class GameServer extends KcpServer implements Iterable<Player> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onServerShutdown() {
|
public void onServerShutdown() {
|
||||||
ServerStopEvent event = new ServerStopEvent(ServerEvent.Type.GAME, OffsetDateTime.now());
|
var event = new ServerStopEvent(ServerEvent.Type.GAME, OffsetDateTime.now());
|
||||||
event.call();
|
event.call();
|
||||||
|
|
||||||
this.getPlayers()
|
// Save players & the world.
|
||||||
.forEach(
|
this.getPlayers().forEach((uid, player) -> player.getSession().close());
|
||||||
(uid, player) -> {
|
|
||||||
player.getSession().close();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.getWorlds().forEach(World::save);
|
this.getWorlds().forEach(World::save);
|
||||||
|
|
||||||
|
Utils.sleep(1000L); // Wait 1 second for operations to finish.
|
||||||
|
this.stop(); // Stop the server.
|
||||||
|
|
||||||
|
try {
|
||||||
|
var threadPool = GameSessionManager.getLogicThread();
|
||||||
|
|
||||||
|
// Shutdown network thread.
|
||||||
|
threadPool.shutdownGracefully();
|
||||||
|
// Wait for the network thread to finish.
|
||||||
|
if (!threadPool.awaitTermination(5, TimeUnit.SECONDS)) {
|
||||||
|
Grasscutter.getLogger().error("Logic thread did not terminate!");
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull @Override
|
@NotNull @Override
|
||||||
|
@ -1,27 +1,20 @@
|
|||||||
package emu.grasscutter.server.game;
|
package emu.grasscutter.server.game;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.GAME_INFO;
|
import static emu.grasscutter.config.Configuration.*;
|
||||||
import static emu.grasscutter.config.Configuration.SERVER;
|
|
||||||
import static emu.grasscutter.utils.lang.Language.translate;
|
import static emu.grasscutter.utils.lang.Language.translate;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.*;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
|
||||||
import emu.grasscutter.net.packet.PacketOpcodesUtils;
|
|
||||||
import emu.grasscutter.server.event.game.SendPacketEvent;
|
import emu.grasscutter.server.event.game.SendPacketEvent;
|
||||||
import emu.grasscutter.utils.Crypto;
|
import emu.grasscutter.utils.*;
|
||||||
import emu.grasscutter.utils.FileUtils;
|
import io.netty.buffer.*;
|
||||||
import emu.grasscutter.utils.Utils;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import lombok.Getter;
|
import lombok.*;
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
public class GameSession implements GameSessionManager.KcpChannel {
|
public class GameSession implements GameSessionManager.KcpChannel {
|
||||||
private final GameServer server;
|
private final GameServer server;
|
||||||
@ -139,7 +132,11 @@ public class GameSession implements GameSessionManager.KcpChannel {
|
|||||||
SendPacketEvent event = new SendPacketEvent(this, packet);
|
SendPacketEvent event = new SendPacketEvent(this, packet);
|
||||||
event.call();
|
event.call();
|
||||||
if (!event.isCanceled()) { // If event is not cancelled, continue.
|
if (!event.isCanceled()) { // If event is not cancelled, continue.
|
||||||
tunnel.writeData(event.getPacket().build());
|
try {
|
||||||
|
tunnel.writeData(event.getPacket().build());
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
Grasscutter.getLogger().debug("Unable to send packet to client.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,8 +149,7 @@ public class GameSession implements GameSessionManager.KcpChannel {
|
|||||||
@Override
|
@Override
|
||||||
public void handleReceive(byte[] bytes) {
|
public void handleReceive(byte[] bytes) {
|
||||||
// Decrypt and turn back into a packet
|
// Decrypt and turn back into a packet
|
||||||
if (this.getState() != SessionState.WAITING_FOR_TOKEN)
|
Crypto.xor(bytes, useSecretKey() ? Crypto.ENCRYPT_KEY : Crypto.DISPATCH_KEY);
|
||||||
Crypto.xor(bytes, useSecretKey() ? Crypto.ENCRYPT_KEY : Crypto.DISPATCH_KEY);
|
|
||||||
ByteBuf packet = Unpooled.wrappedBuffer(bytes);
|
ByteBuf packet = Unpooled.wrappedBuffer(bytes);
|
||||||
|
|
||||||
// Log
|
// Log
|
||||||
|
@ -2,16 +2,15 @@ package emu.grasscutter.server.game;
|
|||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.*;
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import io.netty.channel.DefaultEventLoop;
|
import io.netty.channel.DefaultEventLoop;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import kcp.highway.KcpListener;
|
import kcp.highway.*;
|
||||||
import kcp.highway.Ukcp;
|
import lombok.Getter;
|
||||||
|
|
||||||
public class GameSessionManager {
|
public class GameSessionManager {
|
||||||
private static final DefaultEventLoop logicThread = new DefaultEventLoop();
|
@Getter private static final DefaultEventLoop logicThread = new DefaultEventLoop();
|
||||||
private static final ConcurrentHashMap<Ukcp, GameSession> sessions = new ConcurrentHashMap<>();
|
private static final ConcurrentHashMap<Ukcp, GameSession> sessions = new ConcurrentHashMap<>();
|
||||||
private static final KcpListener listener =
|
private static final KcpListener listener =
|
||||||
new KcpListener() {
|
new KcpListener() {
|
||||||
|
@ -95,10 +95,13 @@ public final class RegionHandler implements Router {
|
|||||||
RegionInfo.newBuilder()
|
RegionInfo.newBuilder()
|
||||||
.setGateserverIp(region.Ip)
|
.setGateserverIp(region.Ip)
|
||||||
.setGateserverPort(region.Port)
|
.setGateserverPort(region.Port)
|
||||||
.setSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
|
||||||
.build();
|
.build();
|
||||||
// Create an updated region query.
|
// Create an updated region query.
|
||||||
var updatedQuery = QueryCurrRegionHttpRsp.newBuilder().setRegionInfo(regionInfo).build();
|
var updatedQuery =
|
||||||
|
QueryCurrRegionHttpRsp.newBuilder()
|
||||||
|
.setRegionInfo(regionInfo)
|
||||||
|
.setClientSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
||||||
|
.build();
|
||||||
regions.put(
|
regions.put(
|
||||||
region.Name,
|
region.Name,
|
||||||
new RegionData(
|
new RegionData(
|
||||||
|
@ -7,18 +7,13 @@ import emu.grasscutter.Grasscutter;
|
|||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.server.http.Router;
|
import emu.grasscutter.server.http.Router;
|
||||||
import emu.grasscutter.utils.DispatchUtils;
|
import emu.grasscutter.utils.*;
|
||||||
import emu.grasscutter.utils.FileUtils;
|
|
||||||
import emu.grasscutter.utils.Utils;
|
|
||||||
import io.javalin.Javalin;
|
import io.javalin.Javalin;
|
||||||
import io.javalin.http.ContentType;
|
import io.javalin.http.*;
|
||||||
import io.javalin.http.Context;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.*;
|
||||||
import java.nio.file.Path;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
/** Handles all gacha-related HTTP requests. */
|
/** Handles all gacha-related HTTP requests. */
|
||||||
@ -48,14 +43,14 @@ public final class GachaHandler implements Router {
|
|||||||
|
|
||||||
// Make request to dispatch server.
|
// Make request to dispatch server.
|
||||||
var data = DispatchUtils.fetchGachaRecords(account.getId(), page, gachaType);
|
var data = DispatchUtils.fetchGachaRecords(account.getId(), page, gachaType);
|
||||||
var records = data.get("records").getAsJsonArray();
|
var records = data.get("records").getAsString();
|
||||||
var maxPage = data.get("maxPage").getAsLong();
|
var maxPage = data.get("maxPage").getAsLong();
|
||||||
|
|
||||||
var locale = account.getLocale();
|
var locale = account.getLocale();
|
||||||
var template =
|
var template =
|
||||||
new String(
|
new String(
|
||||||
FileUtils.read(FileUtils.getDataPath("gacha/records.html")), StandardCharsets.UTF_8)
|
FileUtils.read(FileUtils.getDataPath("gacha/records.html")), StandardCharsets.UTF_8)
|
||||||
.replace("'{{REPLACE_RECORDS}}'", records.toString())
|
.replace("'{{REPLACE_RECORDS}}'", Utils.unescapeJson(records))
|
||||||
.replace("'{{REPLACE_MAXPAGE}}'", String.valueOf(maxPage))
|
.replace("'{{REPLACE_MAXPAGE}}'", String.valueOf(maxPage))
|
||||||
.replace("{{TITLE}}", translate(locale, "gacha.records.title"))
|
.replace("{{TITLE}}", translate(locale, "gacha.records.title"))
|
||||||
.replace("{{DATE}}", translate(locale, "gacha.records.date"))
|
.replace("{{DATE}}", translate(locale, "gacha.records.date"))
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
import emu.grasscutter.net.packet.PacketHandler;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
@ -11,6 +12,11 @@ public final class HandlerClientLockGameTimeNotify extends PacketHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
var packet = ClientLockGameTimeNotify.parseFrom(payload);
|
var packet = ClientLockGameTimeNotify.parseFrom(payload);
|
||||||
session.getPlayer().getWorld().lockTime(packet.getIsLock());
|
// session.getPlayer().getWorld().lockTime(packet.getIsLock());
|
||||||
|
// TODO: figure out what to implement here
|
||||||
|
if (packet.getIsLock())
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.warn(
|
||||||
|
"Invalid 'ClientLockGameTimeNotify' received; value is true. (please report to development channel)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
import emu.grasscutter.data.GameData;
|
import emu.grasscutter.data.GameData;
|
||||||
import emu.grasscutter.data.excels.GadgetData;
|
|
||||||
import emu.grasscutter.data.excels.ItemData;
|
import emu.grasscutter.data.excels.ItemData;
|
||||||
import emu.grasscutter.data.excels.monster.MonsterData;
|
import emu.grasscutter.data.excels.monster.MonsterData;
|
||||||
import emu.grasscutter.game.entity.*;
|
import emu.grasscutter.game.entity.*;
|
||||||
import emu.grasscutter.game.world.Position;
|
import emu.grasscutter.game.world.Position;
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.*;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
|
||||||
import emu.grasscutter.net.proto.QuestCreateEntityReqOuterClass.QuestCreateEntityReq;
|
import emu.grasscutter.net.proto.QuestCreateEntityReqOuterClass.QuestCreateEntityReq;
|
||||||
|
import emu.grasscutter.scripts.data.SceneGadget;
|
||||||
import emu.grasscutter.server.game.GameSession;
|
import emu.grasscutter.server.game.GameSession;
|
||||||
import emu.grasscutter.server.packet.send.PacketQuestCreateEntityRsp;
|
import emu.grasscutter.server.packet.send.PacketQuestCreateEntityRsp;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
@ -30,12 +28,29 @@ public class HandlerQuestCreateEntityReq extends PacketHandler {
|
|||||||
case GADGET_ID -> {
|
case GADGET_ID -> {
|
||||||
val gadgetId = entity.getGadgetId();
|
val gadgetId = entity.getGadgetId();
|
||||||
val gadgetInfo = entity.getGadget();
|
val gadgetInfo = entity.getGadget();
|
||||||
GadgetData gadgetData = GameData.getGadgetDataMap().get(gadgetId);
|
var gadgetData = GameData.getGadgetDataMap().get(gadgetId);
|
||||||
gameEntity =
|
gameEntity =
|
||||||
switch (gadgetData.getType()) {
|
switch (gadgetData.getType()) {
|
||||||
case Vehicle -> new EntityVehicle(scene, session.getPlayer(), gadgetId, 0, pos, rot);
|
case Vehicle -> new EntityVehicle(scene, session.getPlayer(), gadgetId, 0, pos, rot);
|
||||||
|
case Chest -> {
|
||||||
|
var chest = gadgetInfo.getChest();
|
||||||
|
var gadget = new EntityGadget(scene, gadgetId, pos, rot);
|
||||||
|
// Create the gadget data for the chest.
|
||||||
|
var metaGadget = new SceneGadget();
|
||||||
|
metaGadget.drop_count = 1; // TODO: Check if more items should be dropped.
|
||||||
|
metaGadget.chest_drop_id = chest.getChestDropId();
|
||||||
|
metaGadget.setShowcutscene(chest.getIsShowCutscene());
|
||||||
|
// Apply the gadget data to the chest.
|
||||||
|
gadget.setMetaGadget(metaGadget);
|
||||||
|
|
||||||
|
yield gadget;
|
||||||
|
}
|
||||||
default -> new EntityGadget(scene, gadgetId, pos, rot);
|
default -> new EntityGadget(scene, gadgetId, pos, rot);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (gameEntity instanceof EntityGadget gadget) {
|
||||||
|
gadget.buildContent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case ITEM_ID -> {
|
case ITEM_ID -> {
|
||||||
val itemId = entity.getItemId();
|
val itemId = entity.getItemId();
|
||||||
|
@ -13,7 +13,6 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
|
|||||||
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
||||||
|
|
||||||
this.setUseDispatchKey(true);
|
this.setUseDispatchKey(true);
|
||||||
this.shouldEncrypt = false;
|
|
||||||
|
|
||||||
GetPlayerTokenRsp p =
|
GetPlayerTokenRsp p =
|
||||||
GetPlayerTokenRsp.newBuilder()
|
GetPlayerTokenRsp.newBuilder()
|
||||||
@ -39,7 +38,6 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
|
|||||||
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
||||||
|
|
||||||
this.setUseDispatchKey(true);
|
this.setUseDispatchKey(true);
|
||||||
this.shouldEncrypt = false;
|
|
||||||
|
|
||||||
GetPlayerTokenRsp p =
|
GetPlayerTokenRsp p =
|
||||||
GetPlayerTokenRsp.newBuilder()
|
GetPlayerTokenRsp.newBuilder()
|
||||||
@ -61,7 +59,6 @@ public class PacketGetPlayerTokenRsp extends BasePacket {
|
|||||||
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
||||||
|
|
||||||
this.setUseDispatchKey(true);
|
this.setUseDispatchKey(true);
|
||||||
this.shouldEncrypt = false;
|
|
||||||
|
|
||||||
GetPlayerTokenRsp p =
|
GetPlayerTokenRsp p =
|
||||||
GetPlayerTokenRsp.newBuilder()
|
GetPlayerTokenRsp.newBuilder()
|
||||||
|
@ -35,12 +35,12 @@ public class PacketPlayerLoginRsp extends BasePacket {
|
|||||||
RegionInfo.newBuilder()
|
RegionInfo.newBuilder()
|
||||||
.setGateserverIp(lr(GAME_INFO.accessAddress, GAME_INFO.bindAddress))
|
.setGateserverIp(lr(GAME_INFO.accessAddress, GAME_INFO.bindAddress))
|
||||||
.setGateserverPort(lr(GAME_INFO.accessPort, GAME_INFO.bindPort))
|
.setGateserverPort(lr(GAME_INFO.accessPort, GAME_INFO.bindPort))
|
||||||
.setSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
regionCache =
|
var regionCache =
|
||||||
QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp.newBuilder()
|
QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp.newBuilder()
|
||||||
.setRegionInfo(serverRegion)
|
.setRegionInfo(serverRegion)
|
||||||
|
.setClientSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
||||||
.build();
|
.build();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Grasscutter.getLogger().error("Error while initializing region cache!", e);
|
Grasscutter.getLogger().error("Error while initializing region cache!", e);
|
||||||
|
@ -1,23 +1,15 @@
|
|||||||
package emu.grasscutter.utils;
|
package emu.grasscutter.utils;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.*;
|
||||||
import com.google.gson.TypeAdapter;
|
|
||||||
import com.google.gson.TypeAdapterFactory;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.*;
|
||||||
import com.google.gson.stream.JsonToken;
|
|
||||||
import com.google.gson.stream.JsonWriter;
|
|
||||||
import emu.grasscutter.data.common.DynamicFloat;
|
import emu.grasscutter.data.common.DynamicFloat;
|
||||||
import emu.grasscutter.game.world.GridPosition;
|
import emu.grasscutter.game.world.*;
|
||||||
import emu.grasscutter.game.world.Position;
|
|
||||||
import it.unimi.dsi.fastutil.floats.FloatArrayList;
|
import it.unimi.dsi.fastutil.floats.FloatArrayList;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Objects;
|
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
|
||||||
public interface JsonAdapters {
|
public interface JsonAdapters {
|
||||||
|
@ -12,6 +12,7 @@ import io.javalin.http.Context;
|
|||||||
import io.netty.buffer.*;
|
import io.netty.buffer.*;
|
||||||
import it.unimi.dsi.fastutil.ints.*;
|
import it.unimi.dsi.fastutil.ints.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.time.*;
|
import java.time.*;
|
||||||
@ -484,6 +485,7 @@ public final class Utils {
|
|||||||
*
|
*
|
||||||
* @param runnable The task to run.
|
* @param runnable The task to run.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("BusyWait")
|
||||||
public static void waitFor(Returnable<Boolean> runnable) {
|
public static void waitFor(Returnable<Boolean> runnable) {
|
||||||
while (!runnable.invoke()) {
|
while (!runnable.invoke()) {
|
||||||
try {
|
try {
|
||||||
@ -493,4 +495,43 @@ public final class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively finds all fields in a class.
|
||||||
|
*
|
||||||
|
* @param type The class to find fields in.
|
||||||
|
* @return A list of all fields in the class.
|
||||||
|
*/
|
||||||
|
public static List<Field> getAllFields(Class<?> type) {
|
||||||
|
var fields = new LinkedList<>(Arrays.asList(type.getDeclaredFields()));
|
||||||
|
|
||||||
|
// Check for superclasses.
|
||||||
|
if (type.getSuperclass() != null) {
|
||||||
|
fields.addAll(getAllFields(type.getSuperclass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sleeps the current thread without an exception.
|
||||||
|
*
|
||||||
|
* @param millis The amount of milliseconds to sleep.
|
||||||
|
*/
|
||||||
|
public static void sleep(long millis) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(millis);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unescapes a JSON string.
|
||||||
|
*
|
||||||
|
* @param json The JSON string to unescape.
|
||||||
|
* @return The unescaped JSON string.
|
||||||
|
*/
|
||||||
|
public static String unescapeJson(String json) {
|
||||||
|
return json.replaceAll("\"", "\"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package emu.grasscutter.utils.objects;
|
package emu.grasscutter.utils.objects;
|
||||||
|
|
||||||
import com.google.gson.JsonNull;
|
import com.google.gson.*;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import emu.grasscutter.server.dispatch.IDispatcher;
|
import emu.grasscutter.server.dispatch.IDispatcher;
|
||||||
|
import emu.grasscutter.utils.Utils;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
public interface FieldFetch {
|
public interface FieldFetch {
|
||||||
/**
|
/**
|
||||||
@ -18,8 +17,7 @@ public interface FieldFetch {
|
|||||||
// Prepare field properties.
|
// Prepare field properties.
|
||||||
var fieldValues = new JsonObject();
|
var fieldValues = new JsonObject();
|
||||||
var fieldMap = new HashMap<String, Field>();
|
var fieldMap = new HashMap<String, Field>();
|
||||||
Arrays.stream(this.getClass().getDeclaredFields())
|
Utils.getAllFields(this.getClass()).forEach(field -> fieldMap.put(field.getName(), field));
|
||||||
.forEach(field -> fieldMap.put(field.getName(), field));
|
|
||||||
|
|
||||||
// Find the values of all requested fields.
|
// Find the values of all requested fields.
|
||||||
for (var fieldName : fields) {
|
for (var fieldName : fields) {
|
||||||
|
@ -463,7 +463,8 @@
|
|||||||
"disabling_failed": "Failed to disable plugin: %s",
|
"disabling_failed": "Failed to disable plugin: %s",
|
||||||
"invalid_api": {
|
"invalid_api": {
|
||||||
"not_present": "Plugin %s does not specify an API version.",
|
"not_present": "Plugin %s does not specify an API version.",
|
||||||
"lower": "Plugin %s is using API version %s, while the server is using API version %s."
|
"lower": "Plugin %s is using API version %s, while the server is using API version %s.",
|
||||||
|
"outdated": "Plugin %s is using an outdated API method."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,8 @@
|
|||||||
"disabling_failed": "Error al desactivar el plugin: %s",
|
"disabling_failed": "Error al desactivar el plugin: %s",
|
||||||
"invalid_api": {
|
"invalid_api": {
|
||||||
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
||||||
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s."
|
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s.",
|
||||||
|
"outdated": "🇺🇸Plugin %s is using an outdated API method."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,8 @@
|
|||||||
"disabling_failed": "Impossible de désactiver le plugin %s",
|
"disabling_failed": "Impossible de désactiver le plugin %s",
|
||||||
"invalid_api": {
|
"invalid_api": {
|
||||||
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
||||||
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s."
|
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s.",
|
||||||
|
"outdated": "🇺🇸Plugin %s is using an outdated API method."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +463,8 @@
|
|||||||
"disabling_failed": "Impossibile disabilitare il plug-in: %s",
|
"disabling_failed": "Impossibile disabilitare il plug-in: %s",
|
||||||
"invalid_api": {
|
"invalid_api": {
|
||||||
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
||||||
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s."
|
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s.",
|
||||||
|
"outdated": "🇺🇸Plugin %s is using an outdated API method."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user