Merge branch 'development' into plugin-system

This commit is contained in:
Magix 2022-04-25 17:08:18 -04:00 committed by GitHub
commit b857601b78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 3976 additions and 653 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

10
.github/ISSUE_TEMPLATE/custom.md vendored Normal file
View File

@ -0,0 +1,10 @@
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''
---

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -3,9 +3,14 @@ on:
push: push:
branches: branches:
- "stable" - "stable"
pull_request:
types:
- opened
- synchronize
- reopened
jobs: jobs:
Build-Server-Jar: Build-Server-Jar:
runs-on: windows-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -13,12 +18,11 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
distribution: temurin distribution: temurin
java-version: '8' java-version: '16'
- name: Run Gradle - name: Run Gradle
run: .\gradlew.bat && .\gradlew jar run: ./gradlew && ./gradlew jar
- name: Upload build - name: Upload build
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: Grasscutter name: Grasscutter
path: grasscutter.jar path: grasscutter.jar

6
.gitignore vendored
View File

@ -45,13 +45,15 @@ tmp/
.loadpath .loadpath
.recommenders .recommenders
# VSCode
.vscode
# Grasscutter # Grasscutter
resources/* resources/*
logs/* logs/*
data/AbilityEmbryos.json data/AbilityEmbryos.json
data/OpenConfig.json data/OpenConfig.json
proto/auto/ proto/*
proto/protoc.exe
GM Handbook.txt GM Handbook.txt
config.json config.json
mitmdump.exe mitmdump.exe

127
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,127 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[the Discord server](https://discord.gg/T5vZU6UyeG).
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

14
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,14 @@
# Contributing
Please note we have a code of conduct, please follow it in all your interactions with the project. If you have any further questions please create an issue or ask in the Discord server.
- Only fix/add the functionality in question OR address wide-spread whitespace/style issues, not both.
- Address a single concern in the least number of changed lines as possible.
**Do not make a pull request to merge into stable unless it is a hotfix. Use the development branch instead.**
## Pull Request Process
1. Ensure any install or build dependencies are removed before the end of the layer when doing a build.
2. Update the README.md and wiki with details of changes to the interface, this includes new environment variables, exposed ports, useful file locations and container parameters.
3. Write with detail on your pull request description what you have committed, to make it easier for the collaborators to make a changelog.

161
README.md
View File

@ -1,79 +1,148 @@
# Grasscutter ![Grasscutter](https://socialify.git.ci/Grasscutters/Grasscutter/image?description=1&forks=1&issues=1&language=1&logo=https%3A%2F%2Fs2.loli.net%2F2022%2F04%2F25%2FxOiJn7lCdcT5Mw1.png&name=1&owner=1&pulls=1&stargazers=1&theme=Light)
A WIP server reimplementation for *some anime game* 2.3-2.6 <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"><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_zh-CN.md)
**Attention:** We always welcome contributors to the project. Before adding your contribution, please carefully read our [Code of Conduct](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
## Current features
**Documentation**: [Grasscutter Wiki](https://github.com/Melledy/Grasscutter/wiki/)
**Note**: For support please join the [Discord server](https://discord.gg/T5vZU6UyeG).
# Current features
* Logging in * Logging in
* Combat * Combat
* Friends list
* Teleportation
* Gacha system
* Co-op *partially* work
* Spawning monsters via console * Spawning monsters via console
* Inventory features (recieving items/characters, upgrading items/characters, etc) * Inventory features (recieving items/characters, upgrading items/characters, etc)
* Gacha system
* Friends list
* Co-op *partially* work
# Quick setup guide
### Note
* If you update from an older version, delete `config.json` for regeneration
### Prerequisites ## Quick setup guide
* Java 16
* Mongodb (recommended 4.0+) **Note:** for support please join our [Discord](https://discord.gg/T5vZU6UyeG)
### Requirements
* Java SE - 16 ([mirror link](https://github.com/adoptium/temurin16-binaries/releases/tag/jdk-16.0.2+7) since Oracle required an account to download old builds)
**Note:** If you just want to **run it**, then **jre** is fine
* MongoDB (recommended 4.0+)
* Proxy daemon: mitmproxy (mitmdump, recommended), Fiddler Classic, etc. * Proxy daemon: mitmproxy (mitmdump, recommended), Fiddler Classic, etc.
### Starting up Grasscutter server (Assuming you are on Windows) ### Running
1. Setup compile environment `gradlew.bat`
2. Compile Grasscutter with `gradlew jar` **Note:** If you update from an older version, delete `config.json` for regeneration
3. Create a folder named `resources` in your Grasscutter directory, bring your `BinOutput` and `ExcelBinOutput` folders into it *(Check the wiki for more details how to get those.)*
4. Run Grasscutter with `java -jar grasscutter.jar`. Make sure mongodb service is running as well. 1. Get `grasscutter.jar`
- Download from [actions](https://nightly.link/Grasscutters/Grasscutter/workflows/build/stable/Grasscutter.zip)
- [Build by yourself](#Building)
2. Create a `resources` folder in the directory where grasscutter.jar is located and bring your `BinOutput` and `ExcelBinOutput` folders into it *(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 ### Connecting with the client
½. Create an account using *server console command* below
1. Run a proxy daemon: (choose either one) ½. Create an account using [server console command](#Commands).
1. Redirect traffic: (choose one)
- mitmdump: `mitmdump -s proxy.py -k` - mitmdump: `mitmdump -s proxy.py -k`
Trust CA certificate:
**Note:**The CA certificate is usually stored in `% USERPROFILE%\ .mitmproxy`, or you can download it from `http://mitm.it`
Double click for [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
```shell
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
```
- Fiddler Classic: Run Fiddler Classic, turn on `Decrypt https traffic` in setting and change the default port there (Tools -> Options -> Connections) to anything other than `8888`, and load [this script](https://github.lunatic.moe/fiddlerscript). - Fiddler Classic: Run Fiddler Classic, turn on `Decrypt https traffic` in setting and change the default port there (Tools -> Options -> Connections) to anything other than `8888`, and load [this script](https://github.lunatic.moe/fiddlerscript).
- [Hosts file](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [Hosts file](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map)
2. Trust CA certificate:
- mitmdump: `certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer`
2. Set network proxy to `127.0.0.1:8080` or the proxy port you specified. 2. Set network proxy to `127.0.0.1:8080` or the proxy port you specified.
4. *yoink*
* or you can use `run.cmd` to start Server & Proxy daemon with one click **you can also use `start.cmd` to start servers and proxy daemons automatically**
# Grasscutter commands ### Building
There is a dummy user named "Server" in every player's friends list that you can message to use commands. Commands also work in other chat rooms, such as private/team chats.
`account create [username] {playerid}` - Creates an account with the specified username and the in-game uid for that account. The playerid parameter is optional and will be auto generated if not set. Grasscutter uses Gradle to handle dependencies & building.
`spawn [monster id] [level] [amount]` **Requirements:**
`give [item id] [amount]` - Java SE Development Kits - 16
- Git
`givechar [avatar id] [level]` ##### Windows
`drop [item id] [amount]` ```shell
git clone https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
.\gradlew.bat # Setting up environments
.\gradlew jar # Compile
```
`killall` ##### Linux
`setworldlevel [level]` - Relog to see effects properly ```bash
git clone https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
chmod +x gradlew
./gradlew jar # Compile
```
`godmode` - Prevents you from taking damage You can find the output jar in the root of the project folder
`resetconst` - Resets the constellation level on your current active character, will need to relog after using the command to see any changes. ## Commands
`setstats [stats] [amount]` - Changes the current character's specified stat. You might want to use this command (`java -jar grasscutter.jar -handbook`) in a cmd that is in the grasscutter folder. It will create a handbook file (GM Handbook.txt) where you can find the item IDs for stuff you want
`clearartifacts` - Deletes all unequipped and unlocked level 0 artifacts, **including yellow rarity ones** from your inventory There is a dummy user named "Server" in every player's friends list that you can message to use commands. Commands also work in other chat rooms, such as private/team chats. to run commands ingame, you need to add prefix `/` or `!` such as `/pos`
`pos` - Gets your current coordinate. | Commands | Usage | Permission node | Availability | description | Alias |
| -------------- | ------------------------------------------------- | ------------------------- | ------------ | ------------------------------------------------------------ | ----------------------------------------------- |
`weather [weather id] [climate id]` - Changes the current weather. | account | account <create\|delete> <username> [uid] | | Server only | Creates an account with the specified username and the in-game uid for that account. The uid will be auto generated if not set. | |
| broadcast | broadcast <message> | server.broadcast | Both side | Sends a message to all the players. | b |
*More commands will be updated in the [wiki](https://github.com/Melledy/Grasscutter/wiki/).* | changescene | changescene <scene id> | player.changescene | Client only | Switch scenes by scene ID. | scene |
| clearartifacts | clearartifacts | player.clearartifacts | Client only | Deletes all unequipped and unlocked level 0 artifacts, including yellow rarity ones from your inventory. | clearart |
| clearweapons | clearweapons | player.clearweapons | Client only | Deletes all unequipped and unlocked weapons, including yellow rarity ones from your inventory. | clearwpns |
| drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` |
| give | give [player] <itemId\|itemName> [amount] [level] | player.give | Both side | Gives item(s) to you or the specified player. | `g` `item` `giveitem` |
| givechar | givechar <uid> <avatarId> [level] | player.givechar | Both side | Gives the player a specified character. | givec |
| godmode | godmode [uid] | player.godmode | Client only | Prevents you from taking damage. | |
| heal | heal | player.heal | Client only | Heal all characters in your current team. | h |
| help | help [command] | | Both side | Sends the help message or shows information about a specified command. | |
| kick | kick <player> | server.kick | Both side | Kicks the specified player from the server. (WIP) | k |
| killall | killall [playerUid] [sceneId] | server.killall | Both side | Kill all entities in the current scene or specified scene of the corresponding player. | |
| list | list | | Both side | List online players. | |
| permission | permission <add\|remove> <username> <permission> | * | Both side | Grants or removes a permission for a user. | |
| position | position | | Client only | Get coordinates. | pos |
| reload | reload | server.reload | Both side | Reload server config | |
| resetconst | resetconst [all] | player.resetconstellation | Client only | Resets the constellation level on your current active character, will need to relog after using the command to see any changes. | resetconstellation |
| restart | | | Both side | Restarts the current session | |
| say | say <player> <message> | server.sendmessage | Both side | Sends a message to a player as the server | `sendservmsg` `sendservermessage` `sendmessage` |
| setfetterlevel | setfetterlevel <level> | player.setfetterlevel | Client only | Sets your fetter level for your current active character | setfetterlvl |
| setstats | setstats <stat> <value> | player.setstats | Client only | Set fight property for your current active character | stats |
| setworldlevel | setworldlevel <level> | player.setworldlevel | Client only | Sets your world level (Relog to see proper effects) | setworldlvl |
| spawn | spanw <entityID\|entityName> [level] [amount] | server.spawn | Client only | Spawns an entity near you | |
| stop | stop | server.stop | Both side | Stops the server | |
| talent | talent <talentID> <value> | player.settalent | Client only | Set talent level for your current active character | |
| teleport | teleport <x> <y> <z> | player.teleport | Client only | Change the player's position. | tp |
| weather | weather <weatherID> <climateID> | player.weather | Client only | Changes the weather | w |
### Bonus ### Bonus
When you want to teleport to somewhere, use the ingame marking function on Map, click Confirm. You will see your character falling from a very high destination, exact location that you marked.
When you want to teleport to somewhere, use the ingame marking function on Map, click Confirm. You will see your
character falling from a very high destination, exact location that you marked.
# Quick Troubleshooting # Quick Troubleshooting
* If compiling wasn't successful, please check your JDK installation (must be JDK 8 and validated JDK's bin PATH variable)
* My client doesn't connect, doesn't login, 4206, etc... - Mostly your proxy daemon setup is *the issue*, if using Fiddler make sure it running on another port except 8888 * If compiling wasn't successful, please check your JDK installation (JDK 16 and validated JDK's bin PATH variable)
* My client doesn't connect, doesn't login, 4206, etc... - Mostly your proxy daemon setup is *the issue*, if using
Fiddler make sure it running on another port except 8888
* Startup sequence: Mongodb > Grasscutter > Proxy daemon (mitmdump, fiddler, etc.) > Client * Startup sequence: Mongodb > Grasscutter > Proxy daemon (mitmdump, fiddler, etc.) > Client

147
README_zh-CN.md Normal file
View File

@ -0,0 +1,147 @@
![Grasscutter](https://socialify.git.ci/Grasscutters/Grasscutter/image?description=1&forks=1&issues=1&language=1&logo=https%3A%2F%2Fs2.loli.net%2F2022%2F04%2F25%2FxOiJn7lCdcT5Mw1.png&name=1&owner=1&pulls=1&stargazers=1&theme=Light)
<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"><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) | 中文
**注意:** 我们一直欢迎您成为该项目的贡献者。在添加您的代码之前,请仔细阅读我们的 [代码规范](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
## 当前特性
* 登录
* 战斗
* 好友列表
* 传送系统
* 祈愿系统
* 从控制台生成魔物
* 多人游戏 *部分* 可用
* 物品栏相关 (接收物品/角色, 升级角色/武器等)
## 快速设置指南
**附:** 加入我们的 [Discord](https://discord.gg/T5vZU6UyeG) 获取更多帮助!
### 环境需求
* Java SE - 16 (当您没有Oracle账户可以使用[镜像](https://github.com/adoptium/temurin16-binaries/releases/tag/jdk-16.0.2+7))
**注:** 如果您仅仅想要简单地**运行服务端**, 那么使用 **jre** 便足够了
* MongoDB (推荐 4.0+)
* Proxy daemon: mitmproxy (推荐使用mitmdump), Fiddler Classic, 等
### 运行
**注:** 如果您从旧版本升级到新版本,最好删除 `config.json` 并启动服务端jar来重新生成它
1. 获取 `grasscutter.jar`
- 从 [actions](https://nightly.link/Grasscutters/Grasscutter/workflows/build/stable/Grasscutter.zip) 中下载
- [自行构建](#构建)
2. 在**grasscutter.jar** 所在目录中创建 `resources` 文件夹并将 `BinOutput``ExcelBinOutput` 放入其中 *(查看 [wiki](https://github.com/Grasscutters/Grasscutter/wiki) 了解更多)*
3. 通过命令 `java -jar grasscutter.jar` 来运行Grasscutter. **在此之前请确认MongoDB服务运行正常**
### 连接
½. 在服务器控制台中 [创建账户](#命令列表).
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` 来全自动启动服务端并设置代理**
### 构建
Grasscutter 使用 Gradle 来处理依赖及构建.
**依赖:**
- Java SE Development Kits - 16
- Git
##### Windows
```shell
git clone https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
.\gradlew.bat # Setting up environments
.\gradlew jar # Compile
```
##### Linux
```bash
git clone https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
chmod +x gradlew
./gradlew jar # Compile
```
你可以在项目根目录中找到`grasscutter.jar`
## 命令列表
你可能需要在终端中运行 `java -jar grasscutter.jar -handbook` 它将会创建一个 `GM Handbook.txt` 以方便您查阅物品ID等
在每个玩家的朋友列表中都有一个名为“服务器”的虚拟用户,你可以通过发送消息来使用命令。命令也适用于其他聊天室,例如私人/团队聊天。
要在游戏中使用命令,需要添加 `/``!` 前缀,如 `/pos`
| 命令 | 用法 | 权限节点 | 可用性 | 注释 | 别名 |
| -------------- | -------------------------------------------- | ------------------------- | -------- | ------------------------------------------ | ----------------------------------------------- |
| account | account <create\|delete> <用户名> [uid] | | 仅服务端 | 通过指定用户名和uid增删账户 | |
| broadcast | broadcast <消息内容> | server.broadcast | 均可使用 | 给所有玩家发送公告 | b |
| changescene | changescene <场景ID> | player.changescene | 仅客户端 | 切换到指定场景 | scene |
| clearartifacts | clearartifacts | player.clearartifacts | 仅客户端 | 删除所有未装备及未解锁的圣遗物,包括五星 | clearart |
| clearweapons | clearweapons | player.clearweapons | 仅客户端 | 删除所有未装备及未解锁的武器,包括五星 | clearwp |
| drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` |
| give | give [uid] <物品ID\|物品名称> [数量] [等级] | | | 给予指定玩家一定数量及等级的物品 | `g` `item` `giveitem` |
| givechar | givechar <uid> <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec |
| godmode | godmode [uid] | player.godmode | 仅客户端 | 保护你不受到任何伤害(依然会被击退) | |
| heal | heal | player.heal | 仅客户端 | 治疗队伍中所有角色 | h |
| help | help [命令] | | 均可使用 | 显示帮助或展示指定命令的帮助 | |
| kick | kick <uid> | server.kick | 均可使用 | 从服务器中踢出指定玩家 (WIP) | k |
| killall | killall [uid] [场景ID] | server.killall | 均可使用 | 杀死指定玩家世界中所在或指定场景的全部生物 | |
| list | list | | 均可使用 | 列出在线玩家 | |
| permission | permission <add\|remove> <用户名> <权限节点> | * | 均可使用 | 添加或移除玩家的权限 | |
| position | position | | 仅客户端 | 获取当前坐标 | pos |
| reload | reload | server.reload | 均可使用 | 重载服务器配置 | |
| resetconst | resetconst [all] | player.resetconstellation | 仅客户端 | 重置当前角色的命座,重新登录即可生效 | resetconstellation |
| restart | restart | | 均可使用 | 重启服务端 | |
| say | say <uid> <消息> | server.sendmessage | 均可使用 | 作为服务器发送消息给玩家 | `sendservmsg` `sendservermessage` `sendmessage` |
| setfetterlevel | setfetterlevel <好感等级> | player.setfetterlevel | 仅客户端 | 设置当前角色的好感等级 | `setfetterlvl` `setfriendship` |
| setstats | setstats <属性> <数值> | player.setstats | 仅客户端 | 直接修改当前角色的面板 | stats |
| setworldlevel | setworldlevel <世界等级> | player.setworldlevel | 仅客户端 | 设置世界等级(重新登陆即可生效) | setworldlvl |
| spawn | spanw <实体ID\|实体名称> [等级] [数量] | server.spawn | 仅客户端 | 在你周围生成实体 | |
| stop | stop | server.stop | 均可使用 | 停止服务器 | |
| talent | talent <天赋ID> <等级> | player.settalent | 仅客户端 | 设置当前角色的天赋等级 | |
| teleport | teleport <x> <y> <z> | player.teleport | 仅客户端 | 传送玩家到指定坐标 | tp |
| weather | weather <天气ID> <气候ID> | player.weather | 仅客户端 | 改变天气 | w |
### 额外功能
当你想传送到某个地点, 只需要在地图中创建标记, 关闭地图后即可到达目标地点上空
# 快速排除问题
* 如果编译未能成功,请检查您的jdk安装 (JDK 16并确认jdk处于环境变量`PATH`中
* 我的客户端无法登录/连接, 4206, 其它... - 大部分情况下这是因为您的代理存在问题.如果使用Fiddler请确认Fiddler监听端口不是`8888`
* 启动顺序: MongoDB > Grasscutter > 代理程序 (mitmdump, fiddler等.) > 客户端

View File

@ -25,12 +25,12 @@ dependencies {
implementation fileTree(dir: 'lib', include: ['*.jar']) implementation fileTree(dir: 'lib', include: ['*.jar'])
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.32' implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.32'
implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.2.6' implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.2.9'
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.6' implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.9'
implementation group: 'io.netty', name: 'netty-all', version: '4.1.69.Final' implementation group: 'io.netty', name: 'netty-all', version: '4.1.71.Final'
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.8' implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.8'
implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.18.1' implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.18.2'
implementation group: 'org.reflections', name: 'reflections', version: '0.10.2' implementation group: 'org.reflections', name: 'reflections', version: '0.10.2'

0
gradlew vendored Normal file → Executable file
View File

View File

@ -129,6 +129,7 @@ public final class Grasscutter {
public static void startConsole() { public static void startConsole() {
String input; String input;
getLogger().info("Done! For help, type \"help\"");
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) { try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
while ((input = br.readLine()) != null) { while ((input = br.readLine()) != null) {
try { try {

View File

@ -1,30 +0,0 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.inventory.Inventory;
import emu.grasscutter.game.inventory.ItemType;
import java.util.List;
@Command(label = "clearartifacts", usage = "clearartifacts",
description = "Deletes all unequipped and unlocked level 0 artifacts, including yellow rarity ones from your inventory",
aliases = {"clearart"}, permission = "player.clearartifacts")
public final class ClearArtifactsCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game.");
return; // TODO: clear player's artifacts from console or other players
}
Inventory playerInventory = sender.getInventory();
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
}
}

View File

@ -0,0 +1,106 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.inventory.Inventory;
import emu.grasscutter.game.inventory.ItemType;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@Command(label = "clear", usage = "clear <all|wp|art|mat>", //Merged /clearartifacts and /clearweapons to /clear <args> [uid]
description = "Deletes unequipped unlocked items, including yellow rarity ones from your inventory",
aliases = {"clear"}, permission = "player.clearinv")
public final class ClearCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
int target;
if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game.");
return;
}
String cmdSwitch = args.get(1);
Inventory playerInventory = sender.getInventory();
try {
target = Integer.parseInt(args.get(0));
GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
if (targetPlayer == null && sender != null) {
target = sender.getUid();
} else {
switch (cmdSwitch){
case "wp":
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_WEAPON)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " .");
break;
case "art":
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
break;
case "mat":
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_MATERIAL)
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
break;
case "all":
playerInventory.getItems().values().stream()
.filter(item1 -> item1.getItemType() == ItemType.ITEM_RELIQUARY)
.filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0)
.filter(item1 -> !item1.isLocked() && !item1.isEquipped())
.forEach(item1 -> playerInventory.removeItem(item1, item1.getCount()));
playerInventory.getItems().values().stream()
.filter(item2 -> item2.getItemType() == ItemType.ITEM_MATERIAL)
.filter(item2 -> !item2.isLocked() && !item2.isEquipped())
.forEach(item2 -> playerInventory.removeItem(item2, item2.getCount()));
playerInventory.getItems().values().stream()
.filter(item3 -> item3.getItemType() == ItemType.ITEM_WEAPON)
.filter(item3 -> item3.getLevel() == 1 && item3.getExp() == 0)
.filter(item3 -> !item3.isLocked() && !item3.isEquipped())
.forEach(item3 -> playerInventory.removeItem(item3, item3.getCount()));
playerInventory.getItems().values().stream()
.filter(item4 -> item4.getItemType() == ItemType.ITEM_FURNITURE)
.filter(item4 -> !item4.isLocked() && !item4.isEquipped())
.forEach(item4 -> playerInventory.removeItem(item4, item4.getCount()));
playerInventory.getItems().values().stream()
.filter(item5 -> item5.getItemType() == ItemType.ITEM_DISPLAY)
.filter(item5 -> !item5.isLocked() && !item5.isEquipped())
.forEach(item5 -> playerInventory.removeItem(item5, item5.getCount()));
playerInventory.getItems().values().stream()
.filter(item6 -> item6.getItemType() == ItemType.ITEM_VIRTUAL)
.filter(item6 -> !item6.isLocked() && !item6.isEquipped())
.forEach(item6 -> playerInventory.removeItem(item6, item6.getCount()));
sender.dropMessage("Cleared everything for " + targetPlayer.getNickname() + " .");
break;
}
}
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid playerId.");
return;
}
GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, "Player not found.");
return;
}
}
}

View File

@ -1,29 +0,0 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.inventory.Inventory;
import emu.grasscutter.game.inventory.ItemType;
import java.util.List;
@Command(label = "clearweapons", usage = "clearweapons",
description = "Deletes all unequipped and unlocked weapons, including yellow rarity ones from your inventory",
aliases = {"clearwpns"}, permission = "player.clearweapons")
public final class ClearWeaponsCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game.");
return; // TODO: clear player's weapons from console or other players
}
Inventory playerInventory = sender.getInventory();
playerInventory.getItems().values().stream()
.filter(item -> item.getItemType() == ItemType.ITEM_WEAPON)
.filter(item -> !item.isLocked() && !item.isEquipped())
.forEach(item -> playerInventory.removeItem(item, item.getCount()));
}
}

View File

@ -13,16 +13,15 @@ import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@Command(label = "give", usage = "give [player] <itemId|itemName> [amount]", @Command(label = "give", usage = "give [player] <itemId|itemName> [amount] [level]", description = "Gives an item to you or the specified player", aliases = {
description = "Gives an item to you or the specified player", aliases = {"g", "item", "giveitem"}, permission = "player.give") "g", "item", "giveitem" }, permission = "player.give")
public final class GiveCommand implements CommandHandler { public final class GiveCommand implements CommandHandler {
@Override @Override
public void execute(GenshinPlayer sender, List<String> args) { public void execute(GenshinPlayer sender, List<String> args) {
int target, item, amount = 1; int target, item, lvl, amount = 1;
if (sender == null && args.size() < 2) { if (sender == null && args.size() < 2) {
CommandHandler.sendMessage(null, "Usage: give <player> <itemId|itemName> [amount]"); CommandHandler.sendMessage(null, "Usage: give <player> <itemId|itemName> [amount] [level]");
return; return;
} }
@ -34,6 +33,7 @@ public final class GiveCommand implements CommandHandler {
try { try {
item = Integer.parseInt(args.get(0)); item = Integer.parseInt(args.get(0));
target = sender.getUid(); target = sender.getUid();
lvl = 1;
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook. // TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid item id."); CommandHandler.sendMessage(sender, "Invalid item id.");
@ -43,6 +43,7 @@ public final class GiveCommand implements CommandHandler {
case 2: // <itemId|itemName> [amount] | [player] <itemId|itemName> case 2: // <itemId|itemName> [amount] | [player] <itemId|itemName>
try { try {
target = Integer.parseInt(args.get(0)); target = Integer.parseInt(args.get(0));
lvl = 1;
if (Grasscutter.getGameServer().getPlayerByUid(target) == null && sender != null) { if (Grasscutter.getGameServer().getPlayerByUid(target) == null && sender != null) {
target = sender.getUid(); target = sender.getUid();
@ -57,17 +58,39 @@ public final class GiveCommand implements CommandHandler {
return; return;
} }
break; break;
case 3: // [player] <itemId|itemName> [amount] case 3: // [player] <itemId|itemName> [amount] | <itemId|itemName> [amount] [level]
try {
target = Integer.parseInt(args.get(0));
if (Grasscutter.getGameServer().getPlayerByUid(target) == null && sender != null) {
target = sender.getUid();
item = Integer.parseInt(args.get(0));
amount = Integer.parseInt(args.get(1));
lvl = Integer.parseInt(args.get(2));
} else {
item = Integer.parseInt(args.get(1));
amount = Integer.parseInt(args.get(2));
lvl = 1;
}
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid item or player ID.");
return;
}
break;
case 4: // [player] <itemId|itemName> [amount] [level]
try { try {
target = Integer.parseInt(args.get(0)); target = Integer.parseInt(args.get(0));
if (Grasscutter.getGameServer().getPlayerByUid(target) == null) { if (Grasscutter.getGameServer().getPlayerByUid(target) == null) {
CommandHandler.sendMessage(sender, "Invalid player ID."); CommandHandler.sendMessage(sender, "Invalid player ID.");
return; return;
} } else {
item = Integer.parseInt(args.get(1)); item = Integer.parseInt(args.get(1));
amount = Integer.parseInt(args.get(2)); amount = Integer.parseInt(args.get(2));
lvl = Integer.parseInt(args.get(3));
}
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook. // TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid item or player ID."); CommandHandler.sendMessage(sender, "Invalid item or player ID.");
@ -89,16 +112,37 @@ public final class GiveCommand implements CommandHandler {
return; return;
} }
this.item(targetPlayer, itemData, amount); this.item(targetPlayer, itemData, amount, lvl);
if (!itemData.isEquip())
CommandHandler.sendMessage(sender, String.format("Given %s of %s to %s.", amount, item, target)); CommandHandler.sendMessage(sender, String.format("Given %s of %s to %s.", amount, item, target));
else
CommandHandler.sendMessage(sender,
String.format("Given %s with level %s %s times to %s", item, lvl, amount, target));
} }
private void item(GenshinPlayer player, ItemData itemData, int amount) { private void item(GenshinPlayer player, ItemData itemData, int amount, int lvl) {
if (itemData.isEquip()) { if (itemData.isEquip()) {
List<GenshinItem> items = new LinkedList<>(); List<GenshinItem> items = new LinkedList<>();
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
items.add(new GenshinItem(itemData)); GenshinItem item = new GenshinItem(itemData);
item.setCount(amount);
item.setLevel(lvl);
item.setPromoteLevel(0);
if (lvl > 20) { // 20/40
item.setPromoteLevel(1);
} else if (lvl > 40) { // 40/50
item.setPromoteLevel(2);
} else if (lvl > 50) { // 50/60
item.setPromoteLevel(3);
} else if (lvl > 60) { // 60/70
item.setPromoteLevel(4);
} else if (lvl > 70) { // 70/80
item.setPromoteLevel(5);
} else if (lvl > 80) { // 80/90
item.setPromoteLevel(6);
}
items.add(item);
} }
player.getInventory().addItems(items); player.getInventory().addItems(items);
player.sendPacket(new PacketItemAddHintNotify(items, ActionReason.SubfieldDrop)); player.sendPacket(new PacketItemAddHintNotify(items, ActionReason.SubfieldDrop));
@ -110,4 +154,3 @@ public final class GiveCommand implements CommandHandler {
} }
} }
} }

View File

@ -1,5 +1,6 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
@ -16,7 +17,29 @@ public final class GodModeCommand implements CommandHandler {
CommandHandler.sendMessage(null, "Run this command in-game."); CommandHandler.sendMessage(null, "Run this command in-game.");
return; // TODO: toggle player's godmode statue from console or other players return; // TODO: toggle player's godmode statue from console or other players
} }
sender.setGodmode(!sender.inGodmode());
sender.dropMessage("Godmode is now " + (sender.inGodmode() ? "enabled" : "disabled") + "."); int target;
if (args.size() == 1) {
try {
target = Integer.parseInt(args.get(0));
if (Grasscutter.getGameServer().getPlayerByUid(target) == null) {
target = sender.getUid();
}
} catch (NumberFormatException e) {
CommandHandler.sendMessage(sender, "Invalid player id.");
return;
}
} else {
target = sender.getUid();
}
GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, "Player not found.");
return;
}
targetPlayer.setGodmode(!targetPlayer.inGodmode());
sender.dropMessage("Godmode is now " + (targetPlayer.inGodmode() ? "enabled" : "disabled") +
"for " + targetPlayer.getNickname() + " .");
} }
} }

View File

@ -0,0 +1,68 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.LifeState;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
import java.util.List;
@Command(label = "killcharacter", usage = "killcharacter [playerId]", aliases = {"suicide", "kill"},
description = "Kills the players current character", permission = "player.killcharacter")
public final class KillCharacterCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
int target;
if (sender == null) {
// from console
if (args.size() == 1) {
try {
target = Integer.parseInt(args.get(0));
} catch (NumberFormatException e) {
CommandHandler.sendMessage(null, "Invalid player id.");
return;
}
} else {
CommandHandler.sendMessage(null, "Usage: /killcharacter [playerId]");
return;
}
} else {
if (args.size() == 1) {
try {
target = Integer.parseInt(args.get(0));
if (Grasscutter.getGameServer().getPlayerByUid(target) == null) {
target = sender.getUid();
}
} catch (NumberFormatException e) {
CommandHandler.sendMessage(sender, "Invalid player id.");
return;
}
} else {
target = sender.getUid();
}
}
GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, "Player not found or offline.");
return;
}
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
// Packets
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
entity.getWorld().broadcastPacket(new PacketLifeStateChangeNotify(0, entity, LifeState.LIFE_DEAD));
// remove
targetPlayer.getScene().removeEntity(entity);
entity.onDeath(0);
CommandHandler.sendMessage(sender, "Killed " + targetPlayer.getNickname() + " current character.");
}
}

View File

@ -17,6 +17,7 @@ public final class PositionCommand implements CommandHandler {
return; return;
} }
sender.dropMessage(String.format("Coord: %.3f, %.3f, %.3f", sender.getPos().getX(), sender.getPos().getY(), sender.getPos().getZ())); sender.dropMessage(String.format("Coord: %.3f, %.3f, %.3f\nScene id: %d",
sender.getPos().getX(), sender.getPos().getY(), sender.getPos().getZ(), sender.getSceneId()));
} }
} }

View File

@ -0,0 +1,50 @@
package emu.grasscutter.command.commands;
import java.util.List;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
@Command(label = "setfetterlevel", usage = "setfetterlevel <level>",
description = "Sets your fetter level for your current active character",
aliases = {"setfetterlvl", "setfriendship"}, permission = "player.setfetterlevel")
public final class SetFetterLevelCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game.");
return;
}
if (args.size() < 1) {
CommandHandler.sendMessage(sender, "Usage: setfetterlevel <level>");
return;
}
try {
int fetterLevel = Integer.parseInt(args.get(0));
if (fetterLevel < 0 || fetterLevel > 10) {
CommandHandler.sendMessage(sender, "Fetter level must be between 0 and 10.");
return;
}
GenshinAvatar avatar = sender.getTeamManager().getCurrentAvatarEntity().getAvatar();
avatar.setFetterLevel(fetterLevel);
if (fetterLevel != 10) {
avatar.setFetterExp(GenshinData.getAvatarFetterLevelDataMap().get(fetterLevel).getExp());
}
avatar.save();
sender.sendPacket(new PacketAvatarFetterDataNotify(avatar));
CommandHandler.sendMessage(sender, "Fetter level set to " + fetterLevel);
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(null, "Invalid fetter level.");
}
}
}

View File

@ -197,8 +197,8 @@ public final class SetStatsCommand implements CommandHandler {
float eelec = Integer.parseInt(args.get(1)); float eelec = Integer.parseInt(args.get(1));
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity(); EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();
float elec = eelec / 10000; float elec = eelec / 10000;
entity.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL_HURT, elec); entity.setFightProperty(FightProperty.FIGHT_PROP_ELEC_ADD_HURT, elec);
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CRITICAL_HURT)); entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_ELEC_ADD_HURT));
float igelec = elec * 100; float igelec = elec * 100;
CommandHandler.sendMessage(sender, "Electro DMG Bonus set to " + igelec + "%"); CommandHandler.sendMessage(sender, "Electro DMG Bonus set to " + igelec + "%");
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {

View File

@ -2,6 +2,7 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.def.AvatarSkillDepotData;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.avatar.GenshinAvatar; import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.entity.EntityAvatar;
@ -21,8 +22,9 @@ public class TalentCommand implements CommandHandler {
return; return;
} }
if (args.size() < 0 || args.size() < 1){ if (args.size() < 1){
CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>"); CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>");
CommandHandler.sendMessage(sender, "Another way to set talent level: /talent <n or e or q> <value>");
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid"); CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
return; return;
} }
@ -31,6 +33,7 @@ public class TalentCommand implements CommandHandler {
switch (cmdSwitch) { switch (cmdSwitch) {
default: default:
CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>"); CommandHandler.sendMessage(sender, "To set talent level: /talent set <talentID> <value>");
CommandHandler.sendMessage(sender, "Another way to set talent level: /talent <n or e or q> <value>");
CommandHandler.sendMessage(sender, "To get talent ID: /talent getid"); CommandHandler.sendMessage(sender, "To get talent ID: /talent getid");
return; return;
case "set": case "set":
@ -90,6 +93,45 @@ public class TalentCommand implements CommandHandler {
return; return;
} }
break;
case "n": case "e": case "q":
try {
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();
GenshinAvatar avatar = entity.getAvatar();
AvatarSkillDepotData SkillDepot = avatar.getData().getSkillDepot();
int skillId;
switch (cmdSwitch) {
default:
skillId = SkillDepot.getSkills().get(0);
break;
case "e":
skillId = SkillDepot.getSkills().get(1);
break;
case "q":
skillId = SkillDepot.getEnergySkill();
break;
}
int nextLevel = Integer.parseInt(args.get(1));
int currentLevel = avatar.getSkillLevelMap().get(skillId);
if (args.size() < 1){
CommandHandler.sendMessage(sender, "To set talent level: /talent <n or e or q> <value>");
return;
}
if (nextLevel > 16){
CommandHandler.sendMessage(sender, "Invalid talent level. Level should be lower than 16");
return;
}
// Upgrade skill
avatar.getSkillLevelMap().put(skillId, nextLevel);
avatar.save();
// Packet
sender.sendPacket(new PacketAvatarSkillChangeNotify(avatar, skillId, currentLevel, nextLevel));
sender.sendPacket(new PacketAvatarSkillUpgradeRsp(avatar, skillId, currentLevel, nextLevel));
CommandHandler.sendMessage(sender, "Set this talent to " + nextLevel + ".");
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, "Invalid talent level.");
return;
}
break; break;
case "getid": case "getid":
EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity(); EntityAvatar entity = sender.getTeamManager().getCurrentAvatarEntity();

View File

@ -0,0 +1,70 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.utils.Position;
import java.util.List;
@Command(label = "teleport", usage = "teleport <x> <y> <z>", aliases = {"tp"},
description = "Change the player's position.", permission = "player.teleport")
public class TelePortCommand implements CommandHandler {
@Override
public void execute(GenshinPlayer sender, List<String> args) {
if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game.");
return;
}
if (args.size() < 3){
CommandHandler.sendMessage(sender, "Usage: /tp <x> <y> <z> [scene id]");
return;
}
try {
float x = 0f;
float y = 0f;
float z = 0f;
if (args.get(0).contains("~")) {
if (args.get(0).equals("~")) {
x = sender.getPos().getX();
} else {
x = Float.parseFloat(args.get(0).replace("~", "")) + sender.getPos().getX();
}
} else {
x = Float.parseFloat(args.get(0));
}
if (args.get(1).contains("~")) {
if (args.get(1).equals("~")) {
y = sender.getPos().getY();
} else {
y = Float.parseFloat(args.get(1).replace("~", "")) + sender.getPos().getY();
}
} else {
y = Float.parseFloat(args.get(1));
}
if (args.get(2).contains("~")) {
if (args.get(2).equals("~")) {
z = sender.getPos().getZ();
} else {
z = Float.parseFloat(args.get(2).replace("~", "")) + sender.getPos().getZ();
}
} else {
z = Float.parseFloat(args.get(2));
}
int sceneId = sender.getSceneId();
if (args.size() == 4){
sceneId = Integer.parseInt(args.get(3));
}
Position target = new Position(x, y, z);
boolean result = sender.getWorld().transferPlayerToScene(sender, sceneId, target);
if (!result) {
CommandHandler.sendMessage(sender, "Invalid position.");
}
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, "Invalid position.");
}
}
}

View File

@ -31,6 +31,7 @@ public class GenshinData {
private static final Int2ObjectMap<AvatarSkillDepotData> avatarSkillDepotDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<AvatarSkillDepotData> avatarSkillDepotDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<AvatarSkillData> avatarSkillDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<AvatarSkillData> avatarSkillDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap = new Int2ObjectLinkedOpenHashMap<>(); private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap = new Int2ObjectLinkedOpenHashMap<>();
private static final Int2ObjectMap<AvatarFetterLevelData> avatarFetterLevelDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<ProudSkillData> proudSkillDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<ProudSkillData> proudSkillDataMap = new Int2ObjectOpenHashMap<>();
@ -57,6 +58,8 @@ public class GenshinData {
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>(); private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
// Cache // Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>(); private static Map<Integer, List<Integer>> fetters = new HashMap<>();
@ -114,6 +117,14 @@ public class GenshinData {
return playerLevelDataMap; return playerLevelDataMap;
} }
public static Int2ObjectMap<AvatarFetterLevelData> getAvatarFetterLevelDataMap() {
return avatarFetterLevelDataMap;
}
public static Int2ObjectMap<FetterCharacterCardData> getFetterCharacterCardDataMap() {
return fetterCharacterCardDataMap;
}
public static Int2ObjectMap<AvatarLevelData> getAvatarLevelDataMap() { public static Int2ObjectMap<AvatarLevelData> getAvatarLevelDataMap() {
return avatarLevelDataMap; return avatarLevelDataMap;
} }
@ -176,6 +187,11 @@ public class GenshinData {
return levelData != null ? levelData.getExp() : 0; return levelData != null ? levelData.getExp() : 0;
} }
public static int getAvatarFetterLevelExpRequired(int level) {
AvatarFetterLevelData levelData = avatarFetterLevelDataMap.get(level);
return levelData != null ? levelData.getExp() : 0;
}
public static Int2ObjectMap<ProudSkillData> getProudSkillDataMap() { public static Int2ObjectMap<ProudSkillData> getProudSkillDataMap() {
return proudSkillDataMap; return proudSkillDataMap;
} }
@ -228,6 +244,10 @@ public class GenshinData {
return sceneDataMap; return sceneDataMap;
} }
public static Int2ObjectMap<RewardData> getRewardDataMap() {
return rewardDataMap;
}
public static Map<Integer, List<Integer>> getFetterDataEntries() { public static Map<Integer, List<Integer>> getFetterDataEntries() {
if (fetters.isEmpty()) { if (fetters.isEmpty()) {
fetterDataMap.forEach((k, v) -> { fetterDataMap.forEach((k, v) -> {

View File

@ -0,0 +1,24 @@
package emu.grasscutter.data.common;
import java.util.List;
public class OpenCondData {
private String CondType;
private List<Integer> ParamList;
public String getCondType() {
return CondType;
}
public void setCondType(String condType) {
CondType = condType;
}
public List<Integer> getParamList() {
return ParamList;
}
public void setParamList(List<Integer> paramList) {
ParamList = paramList;
}
}

View File

@ -0,0 +1,22 @@
package emu.grasscutter.data.common;
public class RewardItemData {
private int ItemId;
private int ItemCount;
public int getItemId() {
return ItemId;
}
public void setItemId(int itemId) {
ItemId = itemId;
}
public int getItemCount() {
return ItemCount;
}
public void setItemCount(int itemCount) {
ItemCount = itemCount;
}
}

View File

@ -57,6 +57,8 @@ public class AvatarData extends GenshinResource {
private IntList abilities; private IntList abilities;
private List<Integer> fetters; private List<Integer> fetters;
private int nameCardRewardId;
private int nameCardId;
@Override @Override
public int getId(){ public int getId(){
@ -199,6 +201,14 @@ public class AvatarData extends GenshinResource {
return fetters; return fetters;
} }
public int getNameCardRewardId() {
return nameCardRewardId;
}
public int getNameCardId() {
return nameCardId;
}
@Override @Override
public void onLoad() { public void onLoad() {
this.skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(this.SkillDepotId); this.skillDepot = GenshinData.getAvatarSkillDepotDataMap().get(this.SkillDepotId);
@ -206,6 +216,14 @@ public class AvatarData extends GenshinResource {
// Get fetters from GenshinData // Get fetters from GenshinData
this.fetters = GenshinData.getFetterDataEntries().get(this.Id); this.fetters = GenshinData.getFetterDataEntries().get(this.Id);
if (GenshinData.getFetterCharacterCardDataMap().get(this.Id) != null) {
this.nameCardRewardId = GenshinData.getFetterCharacterCardDataMap().get(this.Id).getRewardId();
}
if (GenshinData.getRewardDataMap().get(this.nameCardRewardId) != null) {
this.nameCardId = GenshinData.getRewardDataMap().get(this.nameCardRewardId).getRewardItemList().get(0).getItemId();
}
int size = GenshinData.getAvatarCurveDataMap().size(); int size = GenshinData.getAvatarCurveDataMap().size();
this.hpGrowthCurve = new float[size]; this.hpGrowthCurve = new float[size];
this.attackGrowthCurve = new float[size]; this.attackGrowthCurve = new float[size];

View File

@ -0,0 +1,23 @@
package emu.grasscutter.data.def;
import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType;
@ResourceType(name = "AvatarFettersLevelExcelConfigData.json")
public class AvatarFetterLevelData extends GenshinResource {
private int FetterLevel;
private int NeedExp;
@Override
public int getId() {
return this.FetterLevel;
}
public int getLevel() {
return FetterLevel;
}
public int getExp() {
return NeedExp;
}
}

View File

@ -0,0 +1,24 @@
package emu.grasscutter.data.def;
import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority;
@ResourceType(name = "FetterCharacterCardExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
public class FetterCharacterCardData extends GenshinResource {
private int AvatarId;
private int RewardId;
@Override
public int getId() {
return AvatarId;
}
public int getRewardId() {
return RewardId;
}
@Override
public void onLoad() {
}
}

View File

@ -1,13 +1,17 @@
package emu.grasscutter.data.def; package emu.grasscutter.data.def;
import java.util.List;
import emu.grasscutter.data.GenshinResource; import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority; import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.common.OpenCondData;
@ResourceType(name = {"FetterInfoExcelConfigData.json", "FettersExcelConfigData.json", "FetterStoryExcelConfigData.json"}, loadPriority = LoadPriority.HIGHEST) @ResourceType(name = {"FetterInfoExcelConfigData.json", "FettersExcelConfigData.json", "FetterStoryExcelConfigData.json"}, loadPriority = LoadPriority.HIGHEST)
public class FetterData extends GenshinResource { public class FetterData extends GenshinResource {
private int AvatarId; private int AvatarId;
private int FetterId; private int FetterId;
private List<OpenCondData> OpenCond;
@Override @Override
public int getId() { public int getId() {
@ -18,6 +22,10 @@ public class FetterData extends GenshinResource {
return AvatarId; return AvatarId;
} }
public List<OpenCondData> getOpenConds() {
return OpenCond;
}
@Override @Override
public void onLoad() { public void onLoad() {
} }

View File

@ -0,0 +1,27 @@
package emu.grasscutter.data.def;
import java.util.List;
import emu.grasscutter.data.GenshinResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.common.RewardItemData;
@ResourceType(name = "RewardExcelConfigData.json")
public class RewardData extends GenshinResource {
public int RewardId;
public List<RewardItemData> RewardItemList;
@Override
public int getId() {
return RewardId;
}
public List<RewardItemData> getRewardItemList() {
return RewardItemList;
}
@Override
public void onLoad() {
}
}

View File

@ -101,7 +101,7 @@ public final class DatabaseManager {
} }
public static synchronized int getNextId(Class<?> c) { public static synchronized int getNextId(Class<?> c) {
DatabaseCounter counter = getDatastore().find(DatabaseCounter.class).filter(Filters.eq("_id", c.getName())).first(); DatabaseCounter counter = getDatastore().find(DatabaseCounter.class).filter(Filters.eq("_id", c.getSimpleName())).first();
if (counter == null) { if (counter == null) {
counter = new DatabaseCounter(c.getSimpleName()); counter = new DatabaseCounter(c.getSimpleName());
} }

View File

@ -1,7 +1,5 @@
package emu.grasscutter.game; package emu.grasscutter.game;
import java.util.*;
import dev.morphia.annotations.*; import dev.morphia.annotations.*;
import emu.grasscutter.GenshinConstants; import emu.grasscutter.GenshinConstants;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
@ -23,7 +21,6 @@ import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry; import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
import emu.grasscutter.net.proto.BirthdayOuterClass.Birthday;
import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry; import emu.grasscutter.net.proto.CombatInvokeEntryOuterClass.CombatInvokeEntry;
import emu.grasscutter.net.proto.HeadImageOuterClass.HeadImage; import emu.grasscutter.net.proto.HeadImageOuterClass.HeadImage;
import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType; import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
@ -35,33 +32,13 @@ import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo; import emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAbilityInvocationsNotify; import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.server.packet.send.PacketAvatarAddNotify;
import emu.grasscutter.server.packet.send.PacketAvatarDataNotify;
import emu.grasscutter.server.packet.send.PacketAvatarGainCostumeNotify;
import emu.grasscutter.server.packet.send.PacketAvatarGainFlycloakNotify;
import emu.grasscutter.server.packet.send.PacketClientAbilityInitFinishNotify;
import emu.grasscutter.server.packet.send.PacketCombatInvocationsNotify;
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import emu.grasscutter.server.packet.send.PacketOpenStateUpdateNotify;
import emu.grasscutter.server.packet.send.PacketPlayerApplyEnterMpResultNotify;
import emu.grasscutter.server.packet.send.PacketPlayerDataNotify;
import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
import emu.grasscutter.server.packet.send.PacketPlayerPropNotify;
import emu.grasscutter.server.packet.send.PacketPlayerStoreNotify;
import emu.grasscutter.server.packet.send.PacketPrivateChatNotify;
import emu.grasscutter.server.packet.send.PacketScenePlayerLocationNotify;
import emu.grasscutter.server.packet.send.PacketSetNameCardRsp;
import emu.grasscutter.server.packet.send.PacketStoreWeightLimitNotify;
import emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerLocationNotify;
import emu.grasscutter.server.packet.send.PacketWorldPlayerRTTNotify;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.*;
@Entity(value = "players", useDiscriminator = false) @Entity(value = "players", useDiscriminator = false)
public class GenshinPlayer { public class GenshinPlayer {
@Id private int id; @Id private int id;
@ -96,6 +73,7 @@ public class GenshinPlayer {
private MpSettingType mpSetting = MpSettingType.MpSettingEnterAfterApply; private MpSettingType mpSetting = MpSettingType.MpSettingEnterAfterApply;
private boolean showAvatar; private boolean showAvatar;
private ArrayList<AvatarProfileData> shownAvatars; private ArrayList<AvatarProfileData> shownAvatars;
private Set<Integer> rewardedLevels;
private int sceneId; private int sceneId;
private int regionId; private int regionId;
@ -113,7 +91,8 @@ public class GenshinPlayer {
@Transient private final InvokeHandler<AbilityInvokeEntry> abilityInvokeHandler; @Transient private final InvokeHandler<AbilityInvokeEntry> abilityInvokeHandler;
@Transient private final InvokeHandler<AbilityInvokeEntry> clientAbilityInitFinishHandler; @Transient private final InvokeHandler<AbilityInvokeEntry> clientAbilityInitFinishHandler;
@Deprecated @SuppressWarnings({ "rawtypes", "unchecked" }) // Morphia only! @Deprecated
@SuppressWarnings({"rawtypes", "unchecked"}) // Morphia only!
public GenshinPlayer() { public GenshinPlayer() {
this.inventory = new Inventory(this); this.inventory = new Inventory(this);
this.avatars = new AvatarStorage(this); this.avatars = new AvatarStorage(this);
@ -143,6 +122,7 @@ public class GenshinPlayer {
this.clientAbilityInitFinishHandler = new InvokeHandler(PacketClientAbilityInitFinishNotify.class); this.clientAbilityInitFinishHandler = new InvokeHandler(PacketClientAbilityInitFinishNotify.class);
this.birthday = new PlayerBirthday(); this.birthday = new PlayerBirthday();
this.rewardedLevels = new HashSet<>();
} }
// On player creation // On player creation
@ -581,6 +561,7 @@ public class GenshinPlayer {
/** /**
* Sends a message to another player. * Sends a message to another player.
*
* @param sender The sender of the message. * @param sender The sender of the message.
* @param message The message to send. * @param message The message to send.
*/ */
@ -656,6 +637,18 @@ public class GenshinPlayer {
this.updateProfile(); this.updateProfile();
} }
public boolean hasBirthday() {
return this.birthday.getDay() > 0;
}
public Set<Integer> getRewardedLevels() {
return rewardedLevels;
}
public void setRewardedLevels(Set<Integer> rewardedLevels) {
this.rewardedLevels = rewardedLevels;
}
public SocialDetail.Builder getSocialDetail() { public SocialDetail.Builder getSocialDetail() {
SocialDetail.Builder social = SocialDetail.newBuilder() SocialDetail.Builder social = SocialDetail.newBuilder()
.setUid(this.getUid()) .setUid(this.getUid())
@ -734,7 +727,8 @@ public class GenshinPlayer {
// Make sure these exist // Make sure these exist
if (this.getTeamManager() == null) { if (this.getTeamManager() == null) {
this.teamManager = new TeamManager(this); this.teamManager = new TeamManager(this);
} if (this.getProfile().getUid() == 0) { }
if (this.getProfile().getUid() == 0) {
this.getProfile().syncWithCharacter(this); this.getProfile().syncWithCharacter(this);
} }
@ -773,6 +767,7 @@ public class GenshinPlayer {
session.send(new PacketAvatarDataNotify(this)); session.send(new PacketAvatarDataNotify(this));
session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world session.send(new PacketPlayerEnterSceneNotify(this)); // Enter game world
session.send(new PacketPlayerLevelRewardUpdateNotify(rewardedLevels));
session.send(new PacketOpenStateUpdateNotify()); session.send(new PacketOpenStateUpdateNotify());
// First notify packets sent // First notify packets sent

View File

@ -90,6 +90,12 @@ public class GenshinAvatar {
private int costume; private int costume;
private int bornTime; private int bornTime;
private int fetterLevel = 1;
private int fetterExp;
private int nameCardRewardId;
private int nameCardId;
public GenshinAvatar() { public GenshinAvatar() {
// Morhpia only! // Morhpia only!
this.equips = new Int2ObjectOpenHashMap<>(); this.equips = new Int2ObjectOpenHashMap<>();
@ -107,6 +113,8 @@ public class GenshinAvatar {
public GenshinAvatar(AvatarData data) { public GenshinAvatar(AvatarData data) {
this(); this();
this.avatarId = data.getId(); this.avatarId = data.getId();
this.nameCardRewardId = data.getNameCardRewardId();
this.nameCardId = data.getNameCardId();
this.data = data; this.data = data;
this.bornTime = (int) (System.currentTimeMillis() / 1000); this.bornTime = (int) (System.currentTimeMillis() / 1000);
this.flyCloak = 140001; this.flyCloak = 140001;
@ -169,6 +177,14 @@ public class GenshinAvatar {
this.satiation = satiation; this.satiation = satiation;
} }
public int getNameCardRewardId() {
return nameCardRewardId;
}
public void setNameCardRewardId(int nameCardRewardId) {
this.nameCardRewardId = nameCardRewardId;
}
public int getSatiationPenalty() { public int getSatiationPenalty() {
return satiationPenalty; return satiationPenalty;
} }
@ -281,6 +297,30 @@ public class GenshinAvatar {
return fetters; return fetters;
} }
public int getFetterLevel() {
return fetterLevel;
}
public void setFetterLevel(int fetterLevel) {
this.fetterLevel = fetterLevel;
}
public int getFetterExp() {
return fetterExp;
}
public void setFetterExp(int fetterExp) {
this.fetterExp = fetterExp;
}
public int getNameCardId() {
return nameCardId;
}
public void setNameCardId(int nameCardId) {
this.nameCardId = nameCardId;
}
public float getCurrentHp() { public float getCurrentHp() {
return currentHp; return currentHp;
} }
@ -403,6 +443,8 @@ public class GenshinAvatar {
// Fetters // Fetters
this.setFetterList(data.getFetters()); this.setFetterList(data.getFetters());
this.setNameCardRewardId(data.getNameCardRewardId());
this.setNameCardId(data.getNameCardId());
// Get hp percent, set to 100% if none // Get hp percent, set to 100% if none
float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP); float hpPercent = this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP) <= 0 ? 1f : this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP) / this.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
@ -701,9 +743,14 @@ public class GenshinAvatar {
} }
public AvatarInfo toProto() { public AvatarInfo toProto() {
int fetterLevel = this.getFetterLevel();
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder() AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
.setExpLevel(10) .setExpLevel(fetterLevel);
.setExpNumber(6325); // Highest Level
if (fetterLevel != 10) {
avatarFetter.setExpNumber(this.getFetterExp());
}
if (this.getFetterList() != null) { if (this.getFetterList() != null) {
for (int i = 0; i < this.getFetterList().size(); i++) { for (int i = 0; i < this.getFetterList().size(); i++) {
@ -715,6 +762,12 @@ public class GenshinAvatar {
} }
} }
int cardId = this.getNameCardId();
if (this.getPlayer().getNameCardList().contains(cardId)) {
avatarFetter.addRewardedFetterLevelList(10);
}
AvatarInfo.Builder avatarInfo = AvatarInfo.newBuilder() AvatarInfo.Builder avatarInfo = AvatarInfo.newBuilder()
.setAvatarId(this.getAvatarId()) .setAvatarId(this.getAvatarId())
.setGuid(this.getGuid()) .setGuid(this.getGuid())

View File

@ -90,7 +90,7 @@ public class GenshinItem {
// Equip data // Equip data
if (getItemType() == ItemType.ITEM_WEAPON) { if (getItemType() == ItemType.ITEM_WEAPON) {
this.level = 1; this.level = this.count > 1 ? this.count : 1;
this.affixes = new ArrayList<>(2); this.affixes = new ArrayList<>(2);
if (getItemData().getSkillAffix() != null) { if (getItemData().getSkillAffix() != null) {
for (int skillAffix : getItemData().getSkillAffix()) { for (int skillAffix : getItemData().getSkillAffix()) {

View File

@ -711,6 +711,31 @@ public class InventoryManager {
player.sendPacket(new PacketAvatarUpgradeRsp(avatar, oldLevel, oldPropMap)); player.sendPacket(new PacketAvatarUpgradeRsp(avatar, oldLevel, oldPropMap));
} }
public void upgradeAvatarFetterLevel(GenshinPlayer player, GenshinAvatar avatar, int expGain) {
// May work. Not test.
int maxLevel = 10; // Keep it until I think of a more "elegant" way
int level = avatar.getFetterLevel();
int exp = avatar.getFetterExp();
int reqExp = GenshinData.getAvatarFetterLevelExpRequired(level);
while (expGain > 0 && reqExp > 0 && level < maxLevel) {
int toGain = Math.min(expGain, reqExp - exp);
exp += toGain;
expGain -= toGain;
if (exp >= reqExp) {
exp = 0;
level += 1;
reqExp = GenshinData.getAvatarFetterLevelExpRequired(level);
}
}
avatar.setFetterLevel(level);
avatar.setFetterExp(exp);
avatar.save();
player.sendPacket(new PacketAvatarPropNotify(avatar));
}
public void upgradeAvatarSkill(GenshinPlayer player, long guid, int skillId) { public void upgradeAvatarSkill(GenshinPlayer player, long guid, int skillId) {
// Sanity checks // Sanity checks
GenshinAvatar avatar = player.getAvatars().getAvatarByGuid(guid); GenshinAvatar avatar = player.getAvatars().getAvatarByGuid(guid);

View File

@ -1,7 +1,9 @@
package emu.grasscutter.game.player; package emu.grasscutter.game.player;
import dev.morphia.annotations.Entity;
import emu.grasscutter.net.proto.BirthdayOuterClass.Birthday; import emu.grasscutter.net.proto.BirthdayOuterClass.Birthday;
@Entity
public class PlayerBirthday { public class PlayerBirthday {
private int day; private int day;
private int month; private int month;

View File

@ -0,0 +1,666 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: PlayerLevelRewardUpdateNotify.proto
package emu.grasscutter.net.proto;
public final class PlayerLevelRewardUpdateNotifyOuterClass {
private PlayerLevelRewardUpdateNotifyOuterClass() {}
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 PlayerLevelRewardUpdateNotifyOrBuilder extends
// @@protoc_insertion_point(interface_extends:PlayerLevelRewardUpdateNotify)
com.google.protobuf.MessageOrBuilder {
/**
* <code>repeated uint32 levelList = 1;</code>
* @return A list containing the levelList.
*/
java.util.List<java.lang.Integer> getLevelListList();
/**
* <code>repeated uint32 levelList = 1;</code>
* @return The count of levelList.
*/
int getLevelListCount();
/**
* <code>repeated uint32 levelList = 1;</code>
* @param index The index of the element to return.
* @return The levelList at the given index.
*/
int getLevelList(int index);
}
/**
* Protobuf type {@code PlayerLevelRewardUpdateNotify}
*/
public static final class PlayerLevelRewardUpdateNotify extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:PlayerLevelRewardUpdateNotify)
PlayerLevelRewardUpdateNotifyOrBuilder {
private static final long serialVersionUID = 0L;
// Use PlayerLevelRewardUpdateNotify.newBuilder() to construct.
private PlayerLevelRewardUpdateNotify(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private PlayerLevelRewardUpdateNotify() {
levelList_ = emptyIntList();
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new PlayerLevelRewardUpdateNotify();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private PlayerLevelRewardUpdateNotify(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
this();
if (extensionRegistry == null) {
throw new java.lang.NullPointerException();
}
int mutable_bitField0_ = 0;
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 8: {
if (!((mutable_bitField0_ & 0x00000001) != 0)) {
levelList_ = newIntList();
mutable_bitField0_ |= 0x00000001;
}
levelList_.addInt(input.readUInt32());
break;
}
case 10: {
int length = input.readRawVarint32();
int limit = input.pushLimit(length);
if (!((mutable_bitField0_ & 0x00000001) != 0) && input.getBytesUntilLimit() > 0) {
levelList_ = newIntList();
mutable_bitField0_ |= 0x00000001;
}
while (input.getBytesUntilLimit() > 0) {
levelList_.addInt(input.readUInt32());
}
input.popLimit(limit);
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (com.google.protobuf.UninitializedMessageException e) {
throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this);
} catch (java.io.IOException e) {
throw new com.google.protobuf.InvalidProtocolBufferException(
e).setUnfinishedMessage(this);
} finally {
if (((mutable_bitField0_ & 0x00000001) != 0)) {
levelList_.makeImmutable(); // C
}
this.unknownFields = unknownFields.build();
makeExtensionsImmutable();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.internal_static_PlayerLevelRewardUpdateNotify_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.internal_static_PlayerLevelRewardUpdateNotify_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify.class, emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify.Builder.class);
}
public static final int LEVELLIST_FIELD_NUMBER = 1;
private com.google.protobuf.Internal.IntList levelList_;
/**
* <code>repeated uint32 levelList = 1;</code>
* @return A list containing the levelList.
*/
@java.lang.Override
public java.util.List<java.lang.Integer>
getLevelListList() {
return levelList_;
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @return The count of levelList.
*/
public int getLevelListCount() {
return levelList_.size();
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @param index The index of the element to return.
* @return The levelList at the given index.
*/
public int getLevelList(int index) {
return levelList_.getInt(index);
}
private int levelListMemoizedSerializedSize = -1;
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 {
getSerializedSize();
if (getLevelListList().size() > 0) {
output.writeUInt32NoTag(10);
output.writeUInt32NoTag(levelListMemoizedSerializedSize);
}
for (int i = 0; i < levelList_.size(); i++) {
output.writeUInt32NoTag(levelList_.getInt(i));
}
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
{
int dataSize = 0;
for (int i = 0; i < levelList_.size(); i++) {
dataSize += com.google.protobuf.CodedOutputStream
.computeUInt32SizeNoTag(levelList_.getInt(i));
}
size += dataSize;
if (!getLevelListList().isEmpty()) {
size += 1;
size += com.google.protobuf.CodedOutputStream
.computeInt32SizeNoTag(dataSize);
}
levelListMemoizedSerializedSize = dataSize;
}
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.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify)) {
return super.equals(obj);
}
emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify other = (emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify) obj;
if (!getLevelListList()
.equals(other.getLevelListList())) 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();
if (getLevelListCount() > 0) {
hash = (37 * hash) + LEVELLIST_FIELD_NUMBER;
hash = (53 * hash) + getLevelListList().hashCode();
}
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify 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.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify 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.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify 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.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify 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.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify 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.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify 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 PlayerLevelRewardUpdateNotify}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:PlayerLevelRewardUpdateNotify)
emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotifyOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.internal_static_PlayerLevelRewardUpdateNotify_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.internal_static_PlayerLevelRewardUpdateNotify_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify.class, emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify.Builder.class);
}
// Construct using emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify.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();
levelList_ = emptyIntList();
bitField0_ = (bitField0_ & ~0x00000001);
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.internal_static_PlayerLevelRewardUpdateNotify_descriptor;
}
@java.lang.Override
public emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify getDefaultInstanceForType() {
return emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify.getDefaultInstance();
}
@java.lang.Override
public emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify build() {
emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify buildPartial() {
emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify result = new emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify(this);
int from_bitField0_ = bitField0_;
if (((bitField0_ & 0x00000001) != 0)) {
levelList_.makeImmutable();
bitField0_ = (bitField0_ & ~0x00000001);
}
result.levelList_ = levelList_;
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.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify) {
return mergeFrom((emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify other) {
if (other == emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify.getDefaultInstance()) return this;
if (!other.levelList_.isEmpty()) {
if (levelList_.isEmpty()) {
levelList_ = other.levelList_;
bitField0_ = (bitField0_ & ~0x00000001);
} else {
ensureLevelListIsMutable();
levelList_.addAll(other.levelList_);
}
onChanged();
}
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.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int bitField0_;
private com.google.protobuf.Internal.IntList levelList_ = emptyIntList();
private void ensureLevelListIsMutable() {
if (!((bitField0_ & 0x00000001) != 0)) {
levelList_ = mutableCopy(levelList_);
bitField0_ |= 0x00000001;
}
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @return A list containing the levelList.
*/
public java.util.List<java.lang.Integer>
getLevelListList() {
return ((bitField0_ & 0x00000001) != 0) ?
java.util.Collections.unmodifiableList(levelList_) : levelList_;
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @return The count of levelList.
*/
public int getLevelListCount() {
return levelList_.size();
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @param index The index of the element to return.
* @return The levelList at the given index.
*/
public int getLevelList(int index) {
return levelList_.getInt(index);
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @param index The index to set the value at.
* @param value The levelList to set.
* @return This builder for chaining.
*/
public Builder setLevelList(
int index, int value) {
ensureLevelListIsMutable();
levelList_.setInt(index, value);
onChanged();
return this;
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @param value The levelList to add.
* @return This builder for chaining.
*/
public Builder addLevelList(int value) {
ensureLevelListIsMutable();
levelList_.addInt(value);
onChanged();
return this;
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @param values The levelList to add.
* @return This builder for chaining.
*/
public Builder addAllLevelList(
java.lang.Iterable<? extends java.lang.Integer> values) {
ensureLevelListIsMutable();
com.google.protobuf.AbstractMessageLite.Builder.addAll(
values, levelList_);
onChanged();
return this;
}
/**
* <code>repeated uint32 levelList = 1;</code>
* @return This builder for chaining.
*/
public Builder clearLevelList() {
levelList_ = emptyIntList();
bitField0_ = (bitField0_ & ~0x00000001);
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:PlayerLevelRewardUpdateNotify)
}
// @@protoc_insertion_point(class_scope:PlayerLevelRewardUpdateNotify)
private static final emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify();
}
public static emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<PlayerLevelRewardUpdateNotify>
PARSER = new com.google.protobuf.AbstractParser<PlayerLevelRewardUpdateNotify>() {
@java.lang.Override
public PlayerLevelRewardUpdateNotify parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new PlayerLevelRewardUpdateNotify(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<PlayerLevelRewardUpdateNotify> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<PlayerLevelRewardUpdateNotify> getParserForType() {
return PARSER;
}
@java.lang.Override
public emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_PlayerLevelRewardUpdateNotify_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_PlayerLevelRewardUpdateNotify_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#PlayerLevelRewardUpdateNotify.proto\"2\n" +
"\035PlayerLevelRewardUpdateNotify\022\021\n\tlevelL" +
"ist\030\001 \003(\rB\033\n\031emu.grasscutter.net.protob\006" +
"proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
});
internal_static_PlayerLevelRewardUpdateNotify_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_PlayerLevelRewardUpdateNotify_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_PlayerLevelRewardUpdateNotify_descriptor,
new java.lang.String[] { "LevelList", });
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@ -1,5 +1,5 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! // Generated by the protocol buffer compiler. DO NOT EDIT!
// source: proto/SetPlayerBirthdayReq.proto // source: SetPlayerBirthdayReq.proto
package emu.grasscutter.net.proto; package emu.grasscutter.net.proto;
@ -19,19 +19,19 @@ public final class SetPlayerBirthdayReqOuterClass {
com.google.protobuf.MessageOrBuilder { com.google.protobuf.MessageOrBuilder {
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
* @return Whether the birth field is set. * @return Whether the birthday field is set.
*/ */
boolean hasBirth(); boolean hasBirthday();
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
* @return The birth. * @return The birthday.
*/ */
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirth(); emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirthday();
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthOrBuilder(); emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthdayOrBuilder();
} }
/** /**
* Protobuf type {@code SetPlayerBirthdayReq} * Protobuf type {@code SetPlayerBirthdayReq}
@ -80,13 +80,13 @@ public final class SetPlayerBirthdayReqOuterClass {
break; break;
case 10: { case 10: {
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder subBuilder = null; emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder subBuilder = null;
if (birth_ != null) { if (birthday_ != null) {
subBuilder = birth_.toBuilder(); subBuilder = birthday_.toBuilder();
} }
birth_ = input.readMessage(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.parser(), extensionRegistry); birthday_ = input.readMessage(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.parser(), extensionRegistry);
if (subBuilder != null) { if (subBuilder != null) {
subBuilder.mergeFrom(birth_); subBuilder.mergeFrom(birthday_);
birth_ = subBuilder.buildPartial(); birthday_ = subBuilder.buildPartial();
} }
break; break;
@ -125,30 +125,30 @@ public final class SetPlayerBirthdayReqOuterClass {
emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq.class, emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq.Builder.class); emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq.class, emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq.Builder.class);
} }
public static final int BIRTH_FIELD_NUMBER = 1; public static final int BIRTHDAY_FIELD_NUMBER = 1;
private emu.grasscutter.net.proto.BirthdayOuterClass.Birthday birth_; private emu.grasscutter.net.proto.BirthdayOuterClass.Birthday birthday_;
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
* @return Whether the birth field is set. * @return Whether the birthday field is set.
*/ */
@java.lang.Override @java.lang.Override
public boolean hasBirth() { public boolean hasBirthday() {
return birth_ != null; return birthday_ != null;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
* @return The birth. * @return The birthday.
*/ */
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirth() { public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirthday() {
return birth_ == null ? emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birth_; return birthday_ == null ? emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birthday_;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthOrBuilder() { public emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthdayOrBuilder() {
return getBirth(); return getBirthday();
} }
private byte memoizedIsInitialized = -1; private byte memoizedIsInitialized = -1;
@ -165,8 +165,8 @@ public final class SetPlayerBirthdayReqOuterClass {
@java.lang.Override @java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output) public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException { throws java.io.IOException {
if (birth_ != null) { if (birthday_ != null) {
output.writeMessage(1, getBirth()); output.writeMessage(1, getBirthday());
} }
unknownFields.writeTo(output); unknownFields.writeTo(output);
} }
@ -177,9 +177,9 @@ public final class SetPlayerBirthdayReqOuterClass {
if (size != -1) return size; if (size != -1) return size;
size = 0; size = 0;
if (birth_ != null) { if (birthday_ != null) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeMessageSize(1, getBirth()); .computeMessageSize(1, getBirthday());
} }
size += unknownFields.getSerializedSize(); size += unknownFields.getSerializedSize();
memoizedSize = size; memoizedSize = size;
@ -196,10 +196,10 @@ public final class SetPlayerBirthdayReqOuterClass {
} }
emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq other = (emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq) obj; emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq other = (emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq) obj;
if (hasBirth() != other.hasBirth()) return false; if (hasBirthday() != other.hasBirthday()) return false;
if (hasBirth()) { if (hasBirthday()) {
if (!getBirth() if (!getBirthday()
.equals(other.getBirth())) return false; .equals(other.getBirthday())) return false;
} }
if (!unknownFields.equals(other.unknownFields)) return false; if (!unknownFields.equals(other.unknownFields)) return false;
return true; return true;
@ -212,9 +212,9 @@ public final class SetPlayerBirthdayReqOuterClass {
} }
int hash = 41; int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode(); hash = (19 * hash) + getDescriptor().hashCode();
if (hasBirth()) { if (hasBirthday()) {
hash = (37 * hash) + BIRTH_FIELD_NUMBER; hash = (37 * hash) + BIRTHDAY_FIELD_NUMBER;
hash = (53 * hash) + getBirth().hashCode(); hash = (53 * hash) + getBirthday().hashCode();
} }
hash = (29 * hash) + unknownFields.hashCode(); hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash; memoizedHashCode = hash;
@ -349,11 +349,11 @@ public final class SetPlayerBirthdayReqOuterClass {
@java.lang.Override @java.lang.Override
public Builder clear() { public Builder clear() {
super.clear(); super.clear();
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
birth_ = null; birthday_ = null;
} else { } else {
birth_ = null; birthday_ = null;
birthBuilder_ = null; birthdayBuilder_ = null;
} }
return this; return this;
} }
@ -381,10 +381,10 @@ public final class SetPlayerBirthdayReqOuterClass {
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq buildPartial() { public emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq buildPartial() {
emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq result = new emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq(this); emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq result = new emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq(this);
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
result.birth_ = birth_; result.birthday_ = birthday_;
} else { } else {
result.birth_ = birthBuilder_.build(); result.birthday_ = birthdayBuilder_.build();
} }
onBuilt(); onBuilt();
return result; return result;
@ -434,8 +434,8 @@ public final class SetPlayerBirthdayReqOuterClass {
public Builder mergeFrom(emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq other) { public Builder mergeFrom(emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq other) {
if (other == emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq.getDefaultInstance()) return this; if (other == emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq.getDefaultInstance()) return this;
if (other.hasBirth()) { if (other.hasBirthday()) {
mergeBirth(other.getBirth()); mergeBirthday(other.getBirthday());
} }
this.mergeUnknownFields(other.unknownFields); this.mergeUnknownFields(other.unknownFields);
onChanged(); onChanged();
@ -466,123 +466,123 @@ public final class SetPlayerBirthdayReqOuterClass {
return this; return this;
} }
private emu.grasscutter.net.proto.BirthdayOuterClass.Birthday birth_; private emu.grasscutter.net.proto.BirthdayOuterClass.Birthday birthday_;
private com.google.protobuf.SingleFieldBuilderV3< private com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder> birthBuilder_; emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder> birthdayBuilder_;
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
* @return Whether the birth field is set. * @return Whether the birthday field is set.
*/ */
public boolean hasBirth() { public boolean hasBirthday() {
return birthBuilder_ != null || birth_ != null; return birthdayBuilder_ != null || birthday_ != null;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
* @return The birth. * @return The birthday.
*/ */
public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirth() { public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirthday() {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
return birth_ == null ? emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birth_; return birthday_ == null ? emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birthday_;
} else { } else {
return birthBuilder_.getMessage(); return birthdayBuilder_.getMessage();
} }
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
public Builder setBirth(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday value) { public Builder setBirthday(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday value) {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
if (value == null) { if (value == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
birth_ = value; birthday_ = value;
onChanged(); onChanged();
} else { } else {
birthBuilder_.setMessage(value); birthdayBuilder_.setMessage(value);
} }
return this; return this;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
public Builder setBirth( public Builder setBirthday(
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder builderForValue) { emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder builderForValue) {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
birth_ = builderForValue.build(); birthday_ = builderForValue.build();
onChanged(); onChanged();
} else { } else {
birthBuilder_.setMessage(builderForValue.build()); birthdayBuilder_.setMessage(builderForValue.build());
} }
return this; return this;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
public Builder mergeBirth(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday value) { public Builder mergeBirthday(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday value) {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
if (birth_ != null) { if (birthday_ != null) {
birth_ = birthday_ =
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.newBuilder(birth_).mergeFrom(value).buildPartial(); emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.newBuilder(birthday_).mergeFrom(value).buildPartial();
} else { } else {
birth_ = value; birthday_ = value;
} }
onChanged(); onChanged();
} else { } else {
birthBuilder_.mergeFrom(value); birthdayBuilder_.mergeFrom(value);
} }
return this; return this;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
public Builder clearBirth() { public Builder clearBirthday() {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
birth_ = null; birthday_ = null;
onChanged(); onChanged();
} else { } else {
birth_ = null; birthday_ = null;
birthBuilder_ = null; birthdayBuilder_ = null;
} }
return this; return this;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder getBirthBuilder() { public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder getBirthdayBuilder() {
onChanged(); onChanged();
return getBirthFieldBuilder().getBuilder(); return getBirthdayFieldBuilder().getBuilder();
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
public emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthOrBuilder() { public emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthdayOrBuilder() {
if (birthBuilder_ != null) { if (birthdayBuilder_ != null) {
return birthBuilder_.getMessageOrBuilder(); return birthdayBuilder_.getMessageOrBuilder();
} else { } else {
return birth_ == null ? return birthday_ == null ?
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birth_; emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birthday_;
} }
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 1;</code>
*/ */
private com.google.protobuf.SingleFieldBuilderV3< private com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder> emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder>
getBirthFieldBuilder() { getBirthdayFieldBuilder() {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
birthBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< birthdayBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder>( emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder>(
getBirth(), getBirthday(),
getParentForChildren(), getParentForChildren(),
isClean()); isClean());
birth_ = null; birthday_ = null;
} }
return birthBuilder_; return birthdayBuilder_;
} }
@java.lang.Override @java.lang.Override
public final Builder setUnknownFields( public final Builder setUnknownFields(
@ -651,10 +651,10 @@ public final class SetPlayerBirthdayReqOuterClass {
descriptor; descriptor;
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n proto/SetPlayerBirthdayReq.proto\032\024prot" + "\n\032SetPlayerBirthdayReq.proto\032\016Birthday.p" +
"o/Birthday.proto\"0\n\024SetPlayerBirthdayReq" + "roto\"3\n\024SetPlayerBirthdayReq\022\033\n\010birthday" +
"\022\030\n\005birth\030\001 \001(\0132\t.BirthdayB\033\n\031emu.grassc" + "\030\001 \001(\0132\t.BirthdayB\033\n\031emu.grasscutter.net" +
"utter.net.protob\006proto3" ".protob\006proto3"
}; };
descriptor = com.google.protobuf.Descriptors.FileDescriptor descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData, .internalBuildGeneratedFileFrom(descriptorData,
@ -666,7 +666,7 @@ public final class SetPlayerBirthdayReqOuterClass {
internal_static_SetPlayerBirthdayReq_fieldAccessorTable = new internal_static_SetPlayerBirthdayReq_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_SetPlayerBirthdayReq_descriptor, internal_static_SetPlayerBirthdayReq_descriptor,
new java.lang.String[] { "Birth", }); new java.lang.String[] { "Birthday", });
emu.grasscutter.net.proto.BirthdayOuterClass.getDescriptor(); emu.grasscutter.net.proto.BirthdayOuterClass.getDescriptor();
} }

View File

@ -1,5 +1,5 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! // Generated by the protocol buffer compiler. DO NOT EDIT!
// source: proto/SetPlayerBirthdayRsp.proto // source: SetPlayerBirthdayRsp.proto
package emu.grasscutter.net.proto; package emu.grasscutter.net.proto;
@ -19,19 +19,25 @@ public final class SetPlayerBirthdayRspOuterClass {
com.google.protobuf.MessageOrBuilder { com.google.protobuf.MessageOrBuilder {
/** /**
* <code>.Birthday birth = 1;</code> * <code>int32 retcode = 1;</code>
* @return Whether the birth field is set. * @return The retcode.
*/ */
boolean hasBirth(); int getRetcode();
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
* @return The birth. * @return Whether the birthday field is set.
*/ */
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirth(); boolean hasBirthday();
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
* @return The birthday.
*/ */
emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthOrBuilder(); emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirthday();
/**
* <code>.Birthday birthday = 2;</code>
*/
emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthdayOrBuilder();
} }
/** /**
* Protobuf type {@code SetPlayerBirthdayRsp} * Protobuf type {@code SetPlayerBirthdayRsp}
@ -78,15 +84,20 @@ public final class SetPlayerBirthdayRspOuterClass {
case 0: case 0:
done = true; done = true;
break; break;
case 10: { case 8: {
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder subBuilder = null;
if (birth_ != null) { retcode_ = input.readInt32();
subBuilder = birth_.toBuilder(); break;
} }
birth_ = input.readMessage(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.parser(), extensionRegistry); case 18: {
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder subBuilder = null;
if (birthday_ != null) {
subBuilder = birthday_.toBuilder();
}
birthday_ = input.readMessage(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.parser(), extensionRegistry);
if (subBuilder != null) { if (subBuilder != null) {
subBuilder.mergeFrom(birth_); subBuilder.mergeFrom(birthday_);
birth_ = subBuilder.buildPartial(); birthday_ = subBuilder.buildPartial();
} }
break; break;
@ -125,30 +136,41 @@ public final class SetPlayerBirthdayRspOuterClass {
emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp.class, emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp.Builder.class); emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp.class, emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp.Builder.class);
} }
public static final int BIRTH_FIELD_NUMBER = 1; public static final int RETCODE_FIELD_NUMBER = 1;
private emu.grasscutter.net.proto.BirthdayOuterClass.Birthday birth_; private int retcode_;
/** /**
* <code>.Birthday birth = 1;</code> * <code>int32 retcode = 1;</code>
* @return Whether the birth field is set. * @return The retcode.
*/ */
@java.lang.Override @java.lang.Override
public boolean hasBirth() { public int getRetcode() {
return birth_ != null; return retcode_;
}
public static final int BIRTHDAY_FIELD_NUMBER = 2;
private emu.grasscutter.net.proto.BirthdayOuterClass.Birthday birthday_;
/**
* <code>.Birthday birthday = 2;</code>
* @return Whether the birthday field is set.
*/
@java.lang.Override
public boolean hasBirthday() {
return birthday_ != null;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
* @return The birth. * @return The birthday.
*/ */
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirth() { public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirthday() {
return birth_ == null ? emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birth_; return birthday_ == null ? emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birthday_;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
*/ */
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthOrBuilder() { public emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthdayOrBuilder() {
return getBirth(); return getBirthday();
} }
private byte memoizedIsInitialized = -1; private byte memoizedIsInitialized = -1;
@ -165,8 +187,11 @@ public final class SetPlayerBirthdayRspOuterClass {
@java.lang.Override @java.lang.Override
public void writeTo(com.google.protobuf.CodedOutputStream output) public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException { throws java.io.IOException {
if (birth_ != null) { if (retcode_ != 0) {
output.writeMessage(1, getBirth()); output.writeInt32(1, retcode_);
}
if (birthday_ != null) {
output.writeMessage(2, getBirthday());
} }
unknownFields.writeTo(output); unknownFields.writeTo(output);
} }
@ -177,9 +202,13 @@ public final class SetPlayerBirthdayRspOuterClass {
if (size != -1) return size; if (size != -1) return size;
size = 0; size = 0;
if (birth_ != null) { if (retcode_ != 0) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeMessageSize(1, getBirth()); .computeInt32Size(1, retcode_);
}
if (birthday_ != null) {
size += com.google.protobuf.CodedOutputStream
.computeMessageSize(2, getBirthday());
} }
size += unknownFields.getSerializedSize(); size += unknownFields.getSerializedSize();
memoizedSize = size; memoizedSize = size;
@ -196,10 +225,12 @@ public final class SetPlayerBirthdayRspOuterClass {
} }
emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp other = (emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp) obj; emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp other = (emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp) obj;
if (hasBirth() != other.hasBirth()) return false; if (getRetcode()
if (hasBirth()) { != other.getRetcode()) return false;
if (!getBirth() if (hasBirthday() != other.hasBirthday()) return false;
.equals(other.getBirth())) return false; if (hasBirthday()) {
if (!getBirthday()
.equals(other.getBirthday())) return false;
} }
if (!unknownFields.equals(other.unknownFields)) return false; if (!unknownFields.equals(other.unknownFields)) return false;
return true; return true;
@ -212,9 +243,11 @@ public final class SetPlayerBirthdayRspOuterClass {
} }
int hash = 41; int hash = 41;
hash = (19 * hash) + getDescriptor().hashCode(); hash = (19 * hash) + getDescriptor().hashCode();
if (hasBirth()) { hash = (37 * hash) + RETCODE_FIELD_NUMBER;
hash = (37 * hash) + BIRTH_FIELD_NUMBER; hash = (53 * hash) + getRetcode();
hash = (53 * hash) + getBirth().hashCode(); if (hasBirthday()) {
hash = (37 * hash) + BIRTHDAY_FIELD_NUMBER;
hash = (53 * hash) + getBirthday().hashCode();
} }
hash = (29 * hash) + unknownFields.hashCode(); hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash; memoizedHashCode = hash;
@ -349,11 +382,13 @@ public final class SetPlayerBirthdayRspOuterClass {
@java.lang.Override @java.lang.Override
public Builder clear() { public Builder clear() {
super.clear(); super.clear();
if (birthBuilder_ == null) { retcode_ = 0;
birth_ = null;
if (birthdayBuilder_ == null) {
birthday_ = null;
} else { } else {
birth_ = null; birthday_ = null;
birthBuilder_ = null; birthdayBuilder_ = null;
} }
return this; return this;
} }
@ -381,10 +416,11 @@ public final class SetPlayerBirthdayRspOuterClass {
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp buildPartial() { public emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp buildPartial() {
emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp result = new emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp(this); emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp result = new emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp(this);
if (birthBuilder_ == null) { result.retcode_ = retcode_;
result.birth_ = birth_; if (birthdayBuilder_ == null) {
result.birthday_ = birthday_;
} else { } else {
result.birth_ = birthBuilder_.build(); result.birthday_ = birthdayBuilder_.build();
} }
onBuilt(); onBuilt();
return result; return result;
@ -434,8 +470,11 @@ public final class SetPlayerBirthdayRspOuterClass {
public Builder mergeFrom(emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp other) { public Builder mergeFrom(emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp other) {
if (other == emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp.getDefaultInstance()) return this; if (other == emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp.getDefaultInstance()) return this;
if (other.hasBirth()) { if (other.getRetcode() != 0) {
mergeBirth(other.getBirth()); setRetcode(other.getRetcode());
}
if (other.hasBirthday()) {
mergeBirthday(other.getBirthday());
} }
this.mergeUnknownFields(other.unknownFields); this.mergeUnknownFields(other.unknownFields);
onChanged(); onChanged();
@ -466,123 +505,154 @@ public final class SetPlayerBirthdayRspOuterClass {
return this; return this;
} }
private emu.grasscutter.net.proto.BirthdayOuterClass.Birthday birth_; private int retcode_ ;
/**
* <code>int32 retcode = 1;</code>
* @return The retcode.
*/
@java.lang.Override
public int getRetcode() {
return retcode_;
}
/**
* <code>int32 retcode = 1;</code>
* @param value The retcode to set.
* @return This builder for chaining.
*/
public Builder setRetcode(int value) {
retcode_ = value;
onChanged();
return this;
}
/**
* <code>int32 retcode = 1;</code>
* @return This builder for chaining.
*/
public Builder clearRetcode() {
retcode_ = 0;
onChanged();
return this;
}
private emu.grasscutter.net.proto.BirthdayOuterClass.Birthday birthday_;
private com.google.protobuf.SingleFieldBuilderV3< private com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder> birthBuilder_; emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder> birthdayBuilder_;
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
* @return Whether the birth field is set. * @return Whether the birthday field is set.
*/ */
public boolean hasBirth() { public boolean hasBirthday() {
return birthBuilder_ != null || birth_ != null; return birthdayBuilder_ != null || birthday_ != null;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
* @return The birth. * @return The birthday.
*/ */
public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirth() { public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday getBirthday() {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
return birth_ == null ? emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birth_; return birthday_ == null ? emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birthday_;
} else { } else {
return birthBuilder_.getMessage(); return birthdayBuilder_.getMessage();
} }
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
*/ */
public Builder setBirth(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday value) { public Builder setBirthday(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday value) {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
if (value == null) { if (value == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
birth_ = value; birthday_ = value;
onChanged(); onChanged();
} else { } else {
birthBuilder_.setMessage(value); birthdayBuilder_.setMessage(value);
} }
return this; return this;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
*/ */
public Builder setBirth( public Builder setBirthday(
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder builderForValue) { emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder builderForValue) {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
birth_ = builderForValue.build(); birthday_ = builderForValue.build();
onChanged(); onChanged();
} else { } else {
birthBuilder_.setMessage(builderForValue.build()); birthdayBuilder_.setMessage(builderForValue.build());
} }
return this; return this;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
*/ */
public Builder mergeBirth(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday value) { public Builder mergeBirthday(emu.grasscutter.net.proto.BirthdayOuterClass.Birthday value) {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
if (birth_ != null) { if (birthday_ != null) {
birth_ = birthday_ =
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.newBuilder(birth_).mergeFrom(value).buildPartial(); emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.newBuilder(birthday_).mergeFrom(value).buildPartial();
} else { } else {
birth_ = value; birthday_ = value;
} }
onChanged(); onChanged();
} else { } else {
birthBuilder_.mergeFrom(value); birthdayBuilder_.mergeFrom(value);
} }
return this; return this;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
*/ */
public Builder clearBirth() { public Builder clearBirthday() {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
birth_ = null; birthday_ = null;
onChanged(); onChanged();
} else { } else {
birth_ = null; birthday_ = null;
birthBuilder_ = null; birthdayBuilder_ = null;
} }
return this; return this;
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
*/ */
public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder getBirthBuilder() { public emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder getBirthdayBuilder() {
onChanged(); onChanged();
return getBirthFieldBuilder().getBuilder(); return getBirthdayFieldBuilder().getBuilder();
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
*/ */
public emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthOrBuilder() { public emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder getBirthdayOrBuilder() {
if (birthBuilder_ != null) { if (birthdayBuilder_ != null) {
return birthBuilder_.getMessageOrBuilder(); return birthdayBuilder_.getMessageOrBuilder();
} else { } else {
return birth_ == null ? return birthday_ == null ?
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birth_; emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.getDefaultInstance() : birthday_;
} }
} }
/** /**
* <code>.Birthday birth = 1;</code> * <code>.Birthday birthday = 2;</code>
*/ */
private com.google.protobuf.SingleFieldBuilderV3< private com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder> emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder>
getBirthFieldBuilder() { getBirthdayFieldBuilder() {
if (birthBuilder_ == null) { if (birthdayBuilder_ == null) {
birthBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< birthdayBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder>( emu.grasscutter.net.proto.BirthdayOuterClass.Birthday, emu.grasscutter.net.proto.BirthdayOuterClass.Birthday.Builder, emu.grasscutter.net.proto.BirthdayOuterClass.BirthdayOrBuilder>(
getBirth(), getBirthday(),
getParentForChildren(), getParentForChildren(),
isClean()); isClean());
birth_ = null; birthday_ = null;
} }
return birthBuilder_; return birthdayBuilder_;
} }
@java.lang.Override @java.lang.Override
public final Builder setUnknownFields( public final Builder setUnknownFields(
@ -651,10 +721,10 @@ public final class SetPlayerBirthdayRspOuterClass {
descriptor; descriptor;
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n proto/SetPlayerBirthdayRsp.proto\032\024prot" + "\n\032SetPlayerBirthdayRsp.proto\032\016Birthday.p" +
"o/Birthday.proto\"0\n\024SetPlayerBirthdayRsp" + "roto\"D\n\024SetPlayerBirthdayRsp\022\017\n\007retcode\030" +
"\022\030\n\005birth\030\001 \001(\0132\t.BirthdayB\033\n\031emu.grassc" + "\001 \001(\005\022\033\n\010birthday\030\002 \001(\0132\t.BirthdayB\033\n\031em" +
"utter.net.protob\006proto3" "u.grasscutter.net.protob\006proto3"
}; };
descriptor = com.google.protobuf.Descriptors.FileDescriptor descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData, .internalBuildGeneratedFileFrom(descriptorData,
@ -666,7 +736,7 @@ public final class SetPlayerBirthdayRspOuterClass {
internal_static_SetPlayerBirthdayRsp_fieldAccessorTable = new internal_static_SetPlayerBirthdayRsp_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_SetPlayerBirthdayRsp_descriptor, internal_static_SetPlayerBirthdayRsp_descriptor,
new java.lang.String[] { "Birth", }); new java.lang.String[] { "Retcode", "Birthday", });
emu.grasscutter.net.proto.BirthdayOuterClass.getDescriptor(); emu.grasscutter.net.proto.BirthdayOuterClass.getDescriptor();
} }

View File

@ -0,0 +1,538 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: TakePlayerLevelRewardReq.proto
package emu.grasscutter.net.proto;
public final class TakePlayerLevelRewardReqOuterClass {
private TakePlayerLevelRewardReqOuterClass() {}
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 TakePlayerLevelRewardReqOrBuilder extends
// @@protoc_insertion_point(interface_extends:TakePlayerLevelRewardReq)
com.google.protobuf.MessageOrBuilder {
/**
* <code>uint32 level = 1;</code>
* @return The level.
*/
int getLevel();
}
/**
* Protobuf type {@code TakePlayerLevelRewardReq}
*/
public static final class TakePlayerLevelRewardReq extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:TakePlayerLevelRewardReq)
TakePlayerLevelRewardReqOrBuilder {
private static final long serialVersionUID = 0L;
// Use TakePlayerLevelRewardReq.newBuilder() to construct.
private TakePlayerLevelRewardReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private TakePlayerLevelRewardReq() {
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new TakePlayerLevelRewardReq();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private TakePlayerLevelRewardReq(
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 8: {
level_ = input.readUInt32();
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (com.google.protobuf.UninitializedMessageException e) {
throw e.asInvalidProtocolBufferException().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.TakePlayerLevelRewardReqOuterClass.internal_static_TakePlayerLevelRewardReq_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.internal_static_TakePlayerLevelRewardReq_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq.class, emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq.Builder.class);
}
public static final int LEVEL_FIELD_NUMBER = 1;
private int level_;
/**
* <code>uint32 level = 1;</code>
* @return The level.
*/
@java.lang.Override
public int getLevel() {
return level_;
}
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 (level_ != 0) {
output.writeUInt32(1, level_);
}
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
if (level_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(1, level_);
}
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.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq)) {
return super.equals(obj);
}
emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq other = (emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq) obj;
if (getLevel()
!= other.getLevel()) 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) + LEVEL_FIELD_NUMBER;
hash = (53 * hash) + getLevel();
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq 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.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq 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.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq 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.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq 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.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq 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.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq 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 TakePlayerLevelRewardReq}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:TakePlayerLevelRewardReq)
emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReqOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.internal_static_TakePlayerLevelRewardReq_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.internal_static_TakePlayerLevelRewardReq_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq.class, emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq.Builder.class);
}
// Construct using emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq.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();
level_ = 0;
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.internal_static_TakePlayerLevelRewardReq_descriptor;
}
@java.lang.Override
public emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq getDefaultInstanceForType() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq.getDefaultInstance();
}
@java.lang.Override
public emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq build() {
emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq buildPartial() {
emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq result = new emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq(this);
result.level_ = level_;
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.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq) {
return mergeFrom((emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq other) {
if (other == emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq.getDefaultInstance()) return this;
if (other.getLevel() != 0) {
setLevel(other.getLevel());
}
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.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int level_ ;
/**
* <code>uint32 level = 1;</code>
* @return The level.
*/
@java.lang.Override
public int getLevel() {
return level_;
}
/**
* <code>uint32 level = 1;</code>
* @param value The level to set.
* @return This builder for chaining.
*/
public Builder setLevel(int value) {
level_ = value;
onChanged();
return this;
}
/**
* <code>uint32 level = 1;</code>
* @return This builder for chaining.
*/
public Builder clearLevel() {
level_ = 0;
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:TakePlayerLevelRewardReq)
}
// @@protoc_insertion_point(class_scope:TakePlayerLevelRewardReq)
private static final emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq();
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<TakePlayerLevelRewardReq>
PARSER = new com.google.protobuf.AbstractParser<TakePlayerLevelRewardReq>() {
@java.lang.Override
public TakePlayerLevelRewardReq parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new TakePlayerLevelRewardReq(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<TakePlayerLevelRewardReq> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<TakePlayerLevelRewardReq> getParserForType() {
return PARSER;
}
@java.lang.Override
public emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_TakePlayerLevelRewardReq_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_TakePlayerLevelRewardReq_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\036TakePlayerLevelRewardReq.proto\")\n\030Take" +
"PlayerLevelRewardReq\022\r\n\005level\030\001 \001(\rB\033\n\031e" +
"mu.grasscutter.net.protob\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
});
internal_static_TakePlayerLevelRewardReq_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_TakePlayerLevelRewardReq_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_TakePlayerLevelRewardReq_descriptor,
new java.lang.String[] { "Level", });
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@ -0,0 +1,679 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: TakePlayerLevelRewardRsp.proto
package emu.grasscutter.net.proto;
public final class TakePlayerLevelRewardRspOuterClass {
private TakePlayerLevelRewardRspOuterClass() {}
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 TakePlayerLevelRewardRspOrBuilder extends
// @@protoc_insertion_point(interface_extends:TakePlayerLevelRewardRsp)
com.google.protobuf.MessageOrBuilder {
/**
* <code>int32 retcode = 1;</code>
* @return The retcode.
*/
int getRetcode();
/**
* <code>uint32 level = 2;</code>
* @return The level.
*/
int getLevel();
/**
* <code>uint32 rewardId = 3;</code>
* @return The rewardId.
*/
int getRewardId();
}
/**
* Protobuf type {@code TakePlayerLevelRewardRsp}
*/
public static final class TakePlayerLevelRewardRsp extends
com.google.protobuf.GeneratedMessageV3 implements
// @@protoc_insertion_point(message_implements:TakePlayerLevelRewardRsp)
TakePlayerLevelRewardRspOrBuilder {
private static final long serialVersionUID = 0L;
// Use TakePlayerLevelRewardRsp.newBuilder() to construct.
private TakePlayerLevelRewardRsp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
super(builder);
}
private TakePlayerLevelRewardRsp() {
}
@java.lang.Override
@SuppressWarnings({"unused"})
protected java.lang.Object newInstance(
UnusedPrivateParameter unused) {
return new TakePlayerLevelRewardRsp();
}
@java.lang.Override
public final com.google.protobuf.UnknownFieldSet
getUnknownFields() {
return this.unknownFields;
}
private TakePlayerLevelRewardRsp(
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 8: {
retcode_ = input.readInt32();
break;
}
case 16: {
level_ = input.readUInt32();
break;
}
case 24: {
rewardId_ = input.readUInt32();
break;
}
default: {
if (!parseUnknownField(
input, unknownFields, extensionRegistry, tag)) {
done = true;
}
break;
}
}
}
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (com.google.protobuf.UninitializedMessageException e) {
throw e.asInvalidProtocolBufferException().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.TakePlayerLevelRewardRspOuterClass.internal_static_TakePlayerLevelRewardRsp_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.internal_static_TakePlayerLevelRewardRsp_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp.class, emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp.Builder.class);
}
public static final int RETCODE_FIELD_NUMBER = 1;
private int retcode_;
/**
* <code>int32 retcode = 1;</code>
* @return The retcode.
*/
@java.lang.Override
public int getRetcode() {
return retcode_;
}
public static final int LEVEL_FIELD_NUMBER = 2;
private int level_;
/**
* <code>uint32 level = 2;</code>
* @return The level.
*/
@java.lang.Override
public int getLevel() {
return level_;
}
public static final int REWARDID_FIELD_NUMBER = 3;
private int rewardId_;
/**
* <code>uint32 rewardId = 3;</code>
* @return The rewardId.
*/
@java.lang.Override
public int getRewardId() {
return rewardId_;
}
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 (retcode_ != 0) {
output.writeInt32(1, retcode_);
}
if (level_ != 0) {
output.writeUInt32(2, level_);
}
if (rewardId_ != 0) {
output.writeUInt32(3, rewardId_);
}
unknownFields.writeTo(output);
}
@java.lang.Override
public int getSerializedSize() {
int size = memoizedSize;
if (size != -1) return size;
size = 0;
if (retcode_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(1, retcode_);
}
if (level_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(2, level_);
}
if (rewardId_ != 0) {
size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(3, rewardId_);
}
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.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp)) {
return super.equals(obj);
}
emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp other = (emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp) obj;
if (getRetcode()
!= other.getRetcode()) return false;
if (getLevel()
!= other.getLevel()) return false;
if (getRewardId()
!= other.getRewardId()) 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) + RETCODE_FIELD_NUMBER;
hash = (53 * hash) + getRetcode();
hash = (37 * hash) + LEVEL_FIELD_NUMBER;
hash = (53 * hash) + getLevel();
hash = (37 * hash) + REWARDID_FIELD_NUMBER;
hash = (53 * hash) + getRewardId();
hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash;
return hash;
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp parseFrom(
java.nio.ByteBuffer data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp 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.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp parseFrom(
com.google.protobuf.ByteString data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp 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.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp parseFrom(byte[] data)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp parseFrom(
byte[] data,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return PARSER.parseFrom(data, extensionRegistry);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp parseFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp 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.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp parseDelimitedFrom(java.io.InputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseDelimitedWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp 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.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp parseFrom(
com.google.protobuf.CodedInputStream input)
throws java.io.IOException {
return com.google.protobuf.GeneratedMessageV3
.parseWithIOException(PARSER, input);
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp 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.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp 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 TakePlayerLevelRewardRsp}
*/
public static final class Builder extends
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
// @@protoc_insertion_point(builder_implements:TakePlayerLevelRewardRsp)
emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRspOrBuilder {
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.internal_static_TakePlayerLevelRewardRsp_descriptor;
}
@java.lang.Override
protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internalGetFieldAccessorTable() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.internal_static_TakePlayerLevelRewardRsp_fieldAccessorTable
.ensureFieldAccessorsInitialized(
emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp.class, emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp.Builder.class);
}
// Construct using emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp.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();
retcode_ = 0;
level_ = 0;
rewardId_ = 0;
return this;
}
@java.lang.Override
public com.google.protobuf.Descriptors.Descriptor
getDescriptorForType() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.internal_static_TakePlayerLevelRewardRsp_descriptor;
}
@java.lang.Override
public emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp getDefaultInstanceForType() {
return emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp.getDefaultInstance();
}
@java.lang.Override
public emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp build() {
emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp result = buildPartial();
if (!result.isInitialized()) {
throw newUninitializedMessageException(result);
}
return result;
}
@java.lang.Override
public emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp buildPartial() {
emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp result = new emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp(this);
result.retcode_ = retcode_;
result.level_ = level_;
result.rewardId_ = rewardId_;
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.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp) {
return mergeFrom((emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp)other);
} else {
super.mergeFrom(other);
return this;
}
}
public Builder mergeFrom(emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp other) {
if (other == emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp.getDefaultInstance()) return this;
if (other.getRetcode() != 0) {
setRetcode(other.getRetcode());
}
if (other.getLevel() != 0) {
setLevel(other.getLevel());
}
if (other.getRewardId() != 0) {
setRewardId(other.getRewardId());
}
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.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp parsedMessage = null;
try {
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
parsedMessage = (emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp) e.getUnfinishedMessage();
throw e.unwrapIOException();
} finally {
if (parsedMessage != null) {
mergeFrom(parsedMessage);
}
}
return this;
}
private int retcode_ ;
/**
* <code>int32 retcode = 1;</code>
* @return The retcode.
*/
@java.lang.Override
public int getRetcode() {
return retcode_;
}
/**
* <code>int32 retcode = 1;</code>
* @param value The retcode to set.
* @return This builder for chaining.
*/
public Builder setRetcode(int value) {
retcode_ = value;
onChanged();
return this;
}
/**
* <code>int32 retcode = 1;</code>
* @return This builder for chaining.
*/
public Builder clearRetcode() {
retcode_ = 0;
onChanged();
return this;
}
private int level_ ;
/**
* <code>uint32 level = 2;</code>
* @return The level.
*/
@java.lang.Override
public int getLevel() {
return level_;
}
/**
* <code>uint32 level = 2;</code>
* @param value The level to set.
* @return This builder for chaining.
*/
public Builder setLevel(int value) {
level_ = value;
onChanged();
return this;
}
/**
* <code>uint32 level = 2;</code>
* @return This builder for chaining.
*/
public Builder clearLevel() {
level_ = 0;
onChanged();
return this;
}
private int rewardId_ ;
/**
* <code>uint32 rewardId = 3;</code>
* @return The rewardId.
*/
@java.lang.Override
public int getRewardId() {
return rewardId_;
}
/**
* <code>uint32 rewardId = 3;</code>
* @param value The rewardId to set.
* @return This builder for chaining.
*/
public Builder setRewardId(int value) {
rewardId_ = value;
onChanged();
return this;
}
/**
* <code>uint32 rewardId = 3;</code>
* @return This builder for chaining.
*/
public Builder clearRewardId() {
rewardId_ = 0;
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:TakePlayerLevelRewardRsp)
}
// @@protoc_insertion_point(class_scope:TakePlayerLevelRewardRsp)
private static final emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp DEFAULT_INSTANCE;
static {
DEFAULT_INSTANCE = new emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp();
}
public static emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp getDefaultInstance() {
return DEFAULT_INSTANCE;
}
private static final com.google.protobuf.Parser<TakePlayerLevelRewardRsp>
PARSER = new com.google.protobuf.AbstractParser<TakePlayerLevelRewardRsp>() {
@java.lang.Override
public TakePlayerLevelRewardRsp parsePartialFrom(
com.google.protobuf.CodedInputStream input,
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
throws com.google.protobuf.InvalidProtocolBufferException {
return new TakePlayerLevelRewardRsp(input, extensionRegistry);
}
};
public static com.google.protobuf.Parser<TakePlayerLevelRewardRsp> parser() {
return PARSER;
}
@java.lang.Override
public com.google.protobuf.Parser<TakePlayerLevelRewardRsp> getParserForType() {
return PARSER;
}
@java.lang.Override
public emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp getDefaultInstanceForType() {
return DEFAULT_INSTANCE;
}
}
private static final com.google.protobuf.Descriptors.Descriptor
internal_static_TakePlayerLevelRewardRsp_descriptor;
private static final
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
internal_static_TakePlayerLevelRewardRsp_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\036TakePlayerLevelRewardRsp.proto\"L\n\030Take" +
"PlayerLevelRewardRsp\022\017\n\007retcode\030\001 \001(\005\022\r\n" +
"\005level\030\002 \001(\r\022\020\n\010rewardId\030\003 \001(\rB\033\n\031emu.gr" +
"asscutter.net.protob\006proto3"
};
descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
});
internal_static_TakePlayerLevelRewardRsp_descriptor =
getDescriptor().getMessageTypes().get(0);
internal_static_TakePlayerLevelRewardRsp_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_TakePlayerLevelRewardRsp_descriptor,
new java.lang.String[] { "Retcode", "Level", "RewardId", });
}
// @@protoc_insertion_point(outer_class_scope)
}

View File

@ -64,9 +64,8 @@ public class MihoyoKcpServer extends Thread {
// Wait until the server socket is closed. // Wait until the server socket is closed.
f.channel().closeFuture().sync(); f.channel().closeFuture().sync();
} catch (Exception e) { } catch (Exception exception) {
// TODO Auto-generated catch block Grasscutter.getLogger().error("Unable to start game server.", exception);
e.printStackTrace();
} finally { } finally {
// Close // Close
finish(); finish();

View File

@ -26,6 +26,7 @@ import emu.grasscutter.utils.Utils;
import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import java.io.*; import java.io.*;
import java.net.BindException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.URI; import java.net.URI;
import java.net.URLDecoder; import java.net.URLDecoder;
@ -45,7 +46,8 @@ public final class DispatchServer {
public DispatchServer() { public DispatchServer() {
this.regions = new HashMap<String, RegionData>(); this.regions = new HashMap<String, RegionData>();
this.address = new InetSocketAddress(Grasscutter.getConfig().getDispatchOptions().Ip, Grasscutter.getConfig().getDispatchOptions().Port); this.address = new InetSocketAddress(Grasscutter.getConfig().getDispatchOptions().Ip,
Grasscutter.getConfig().getDispatchOptions().Port);
this.gson = new GsonBuilder().create(); this.gson = new GsonBuilder().create();
this.loadQueries(); this.loadQueries();
@ -98,33 +100,51 @@ public final class DispatchServer {
List<RegionSimpleInfo> servers = new ArrayList<RegionSimpleInfo>(); List<RegionSimpleInfo> servers = new ArrayList<RegionSimpleInfo>();
List<String> usedNames = new ArrayList<String>(); // List to check for potential naming conflicts List<String> usedNames = new ArrayList<String>(); // List to check for potential naming conflicts
if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("HYBRID")) { // Automatically add the game server if in hybrid mode if (Grasscutter.getConfig().RunMode.equalsIgnoreCase("HYBRID")) { // Automatically add the game server if in
// hybrid mode
RegionSimpleInfo server = RegionSimpleInfo.newBuilder() RegionSimpleInfo server = RegionSimpleInfo.newBuilder()
.setName("os_usa") .setName("os_usa")
.setTitle(Grasscutter.getConfig().getGameServerOptions().Name) .setTitle(Grasscutter.getConfig().getGameServerOptions().Name)
.setType("DEV_PUBLIC") .setType("DEV_PUBLIC")
.setDispatchUrl("http" + (Grasscutter.getConfig().getDispatchOptions().FrontHTTPS ? "s" : "") + "://" + (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getDispatchOptions().Ip : Grasscutter.getConfig().getDispatchOptions().PublicIp) + ":" + (Grasscutter.getConfig().getDispatchOptions().PublicPort != 0 ? Grasscutter.getConfig().getDispatchOptions().PublicPort : Grasscutter.getConfig().getDispatchOptions().Port) + "/query_cur_region_" + defaultServerName) .setDispatchUrl(
"http" + (Grasscutter.getConfig().getDispatchOptions().FrontHTTPS ? "s" : "") + "://"
+ (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty()
? Grasscutter.getConfig().getDispatchOptions().Ip
: Grasscutter.getConfig().getDispatchOptions().PublicIp)
+ ":"
+ (Grasscutter.getConfig().getDispatchOptions().PublicPort != 0
? Grasscutter.getConfig().getDispatchOptions().PublicPort
: Grasscutter.getConfig().getDispatchOptions().Port)
+ "/query_cur_region_" + defaultServerName)
.build(); .build();
usedNames.add(defaultServerName); usedNames.add(defaultServerName);
servers.add(server); servers.add(server);
RegionInfo serverRegion = regionQuery.getRegionInfo().toBuilder() RegionInfo serverRegion = regionQuery.getRegionInfo().toBuilder()
.setIp((Grasscutter.getConfig().getGameServerOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getGameServerOptions().Ip : Grasscutter.getConfig().getGameServerOptions().PublicIp)) .setIp((Grasscutter.getConfig().getGameServerOptions().PublicIp.isEmpty()
.setPort(Grasscutter.getConfig().getGameServerOptions().PublicPort != 0 ? Grasscutter.getConfig().getGameServerOptions().PublicPort : Grasscutter.getConfig().getGameServerOptions().Port) ? Grasscutter.getConfig().getGameServerOptions().Ip
.setSecretKey(ByteString.copyFrom(FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin"))) : Grasscutter.getConfig().getGameServerOptions().PublicIp))
.setPort(Grasscutter.getConfig().getGameServerOptions().PublicPort != 0
? Grasscutter.getConfig().getGameServerOptions().PublicPort
: Grasscutter.getConfig().getGameServerOptions().Port)
.setSecretKey(ByteString
.copyFrom(FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin")))
.build(); .build();
QueryCurrRegionHttpRsp parsedRegionQuery = regionQuery.toBuilder().setRegionInfo(serverRegion).build(); QueryCurrRegionHttpRsp parsedRegionQuery = regionQuery.toBuilder().setRegionInfo(serverRegion).build();
regions.put(defaultServerName, new RegionData(parsedRegionQuery, Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray()))); regions.put(defaultServerName, new RegionData(parsedRegionQuery,
Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray())));
} else { } else {
if (Grasscutter.getConfig().getDispatchOptions().getGameServers().length == 0) { if (Grasscutter.getConfig().getDispatchOptions().getGameServers().length == 0) {
Grasscutter.getLogger().error("[Dispatch] There are no game servers available. Exiting due to unplayable state."); Grasscutter.getLogger()
.error("[Dispatch] There are no game servers available. Exiting due to unplayable state.");
System.exit(1); System.exit(1);
} }
} }
for (Config.DispatchServerOptions.RegionInfo regionInfo : Grasscutter.getConfig().getDispatchOptions().getGameServers()) { for (Config.DispatchServerOptions.RegionInfo regionInfo : Grasscutter.getConfig().getDispatchOptions()
.getGameServers()) {
if (usedNames.contains(regionInfo.Name)) { if (usedNames.contains(regionInfo.Name)) {
Grasscutter.getLogger().error("Region name already in use."); Grasscutter.getLogger().error("Region name already in use.");
continue; continue;
@ -133,7 +153,12 @@ public final class DispatchServer {
.setName(regionInfo.Name) .setName(regionInfo.Name)
.setTitle(regionInfo.Title) .setTitle(regionInfo.Title)
.setType("DEV_PUBLIC") .setType("DEV_PUBLIC")
.setDispatchUrl("http" + (Grasscutter.getConfig().getDispatchOptions().FrontHTTPS ? "s" : "") + "://" + (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty() ? Grasscutter.getConfig().getDispatchOptions().Ip : Grasscutter.getConfig().getDispatchOptions().PublicIp) + ":" + getAddress().getPort() + "/query_cur_region_" + regionInfo.Name) .setDispatchUrl(
"http" + (Grasscutter.getConfig().getDispatchOptions().FrontHTTPS ? "s" : "") + "://"
+ (Grasscutter.getConfig().getDispatchOptions().PublicIp.isEmpty()
? Grasscutter.getConfig().getDispatchOptions().Ip
: Grasscutter.getConfig().getDispatchOptions().PublicIp)
+ ":" + getAddress().getPort() + "/query_cur_region_" + regionInfo.Name)
.build(); .build();
usedNames.add(regionInfo.Name); usedNames.add(regionInfo.Name);
servers.add(server); servers.add(server);
@ -141,11 +166,13 @@ public final class DispatchServer {
RegionInfo serverRegion = regionQuery.getRegionInfo().toBuilder() RegionInfo serverRegion = regionQuery.getRegionInfo().toBuilder()
.setIp(regionInfo.Ip) .setIp(regionInfo.Ip)
.setPort(regionInfo.Port) .setPort(regionInfo.Port)
.setSecretKey(ByteString.copyFrom(FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin"))) .setSecretKey(ByteString
.copyFrom(FileUtils.read(Grasscutter.getConfig().KEY_FOLDER + "dispatchSeed.bin")))
.build(); .build();
QueryCurrRegionHttpRsp parsedRegionQuery = regionQuery.toBuilder().setRegionInfo(serverRegion).build(); QueryCurrRegionHttpRsp parsedRegionQuery = regionQuery.toBuilder().setRegionInfo(serverRegion).build();
regions.put(regionInfo.Name, new RegionData(parsedRegionQuery, Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray()))); regions.put(regionInfo.Name, new RegionData(parsedRegionQuery,
Base64.getEncoder().encodeToString(parsedRegionQuery.toByteString().toByteArray())));
} }
QueryRegionListHttpRsp regionList = QueryRegionListHttpRsp.newBuilder() QueryRegionListHttpRsp regionList = QueryRegionListHttpRsp.newBuilder()
@ -161,52 +188,92 @@ public final class DispatchServer {
} }
} }
private HttpServer safelyCreateServer(InetSocketAddress address) {
try {
return HttpServer.create(address, 0);
} catch (BindException ignored) {
Grasscutter.getLogger().error("Unable to bind to port: " + getAddress().getPort() + " (HTTP)");
} catch (Exception exception) {
Grasscutter.getLogger().error("Unable to start HTTP server.", exception);
}
return null;
}
public void start() throws Exception { public void start() throws Exception {
HttpServer server; HttpServer server;
if (Grasscutter.getConfig().getDispatchOptions().UseSSL) { if (Grasscutter.getConfig().getDispatchOptions().UseSSL) {
HttpsServer httpsServer; HttpsServer httpsServer = HttpsServer.create(getAddress(), 0);
httpsServer = HttpsServer.create(getAddress(), 0);
SSLContext sslContext = SSLContext.getInstance("TLS"); SSLContext sslContext = SSLContext.getInstance("TLS");
try (FileInputStream fis = new FileInputStream(Grasscutter.getConfig().getDispatchOptions().KeystorePath)) { try (FileInputStream fis = new FileInputStream(Grasscutter.getConfig().getDispatchOptions().KeystorePath)) {
char[] keystorePassword = Grasscutter.getConfig().getDispatchOptions().KeystorePassword.toCharArray(); char[] keystorePassword = Grasscutter.getConfig().getDispatchOptions().KeystorePassword.toCharArray();
KeyManagerFactory _kmf;
try {
KeyStore ks = KeyStore.getInstance("PKCS12"); KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(fis, keystorePassword); ks.load(fis, keystorePassword);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
_kmf = kmf;
kmf.init(ks, keystorePassword); kmf.init(ks, keystorePassword);
} catch (Exception originalEx) {
try {
// try to initialize kmf with the default password
char[] defaultPassword = "123456".toCharArray();
sslContext.init(kmf.getKeyManagers(), null, null); Grasscutter.getLogger()
.warn("[Dispatch] Unable to load keystore. Trying default keystore password...");
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(fis, defaultPassword);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, defaultPassword);
_kmf = kmf;
Grasscutter.getLogger().warn(
"[Dispatch] The default keystore password was loaded successfully. Please consider setting the password in config.json.");
} catch (Exception ignored) {
Grasscutter.getLogger().warn("[Dispatch] Error while loading keystore!");
// don't care about the exception for the "123456" default password attempt
originalEx.printStackTrace();
throw originalEx;
}
}
sslContext.init(_kmf.getKeyManagers(), null, null);
httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext)); httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));
server = httpsServer; server = httpsServer;
} catch (BindException ignored) {
Grasscutter.getLogger().error("Unable to bind to port: " + getAddress().getPort() + " (HTTPS)");
server = this.safelyCreateServer(this.getAddress());
} catch (Exception e) { } catch (Exception e) {
Grasscutter.getLogger().warn("[Dispatch] No SSL cert found! Falling back to HTTP server."); Grasscutter.getLogger().warn("[Dispatch] No SSL cert found! Falling back to HTTP server.");
Grasscutter.getConfig().getDispatchOptions().UseSSL = false; Grasscutter.getConfig().getDispatchOptions().UseSSL = false;
server = HttpServer.create(getAddress(), 0); server = this.safelyCreateServer(this.getAddress());
} }
} else { } else {
server = HttpServer.create(getAddress(), 0); server = this.safelyCreateServer(this.getAddress());
} }
if (server == null)
throw new NullPointerException("An HTTP server was not created.");
server.createContext("/", t -> responseHTML(t, "Hello")); server.createContext("/", t -> responseHTML(t, "Hello"));
// Dispatch // Dispatch
server.createContext("/query_region_list", t -> { server.createContext("/query_region_list", t -> {
// Log incoming request. // Log
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s request: query_region_list", t.getRemoteAddress())); Grasscutter.getLogger()
.info(String.format("[Dispatch] Client %s request: query_region_list", t.getRemoteAddress()));
// Invoke event. responseHTML(t, regionListBase64);
QueryAllRegionsEvent event = new QueryAllRegionsEvent(this.regionListBase64); event.call();
// Respond with event result.
responseHTML(t, event.getRegionList());
}); });
for (String regionName : regions.keySet()) { for (String regionName : regions.keySet()) {
server.createContext("/query_cur_region_" + regionName, t -> { server.createContext("/query_cur_region_" + regionName, t -> {
String regionCurrentBase64 = regions.get(regionName).Base64; String regionCurrentBase64 = regions.get(regionName).Base64;
// Log incoming request. // Log
Grasscutter.getLogger().info(String.format("Client %s request: query_cur_region_%s", t.getRemoteAddress(), regionName)); Grasscutter.getLogger().info(
String.format("Client %s request: query_cur_region_%s", t.getRemoteAddress(), regionName));
// Create a response from the request query parameters. // Create a response form the request query parameters
URI uri = t.getRequestURI(); URI uri = t.getRequestURI();
String response = "CAESGE5vdCBGb3VuZCB2ZXJzaW9uIGNvbmZpZw=="; String response = "CAESGE5vdCBGb3VuZCB2ZXJzaW9uIGNvbmZpZw==";
if (uri.getQuery() != null && uri.getQuery().length() > 0) { if (uri.getQuery() != null && uri.getQuery().length() > 0) {
@ -227,7 +294,8 @@ public final class DispatchServer {
try { try {
String body = Utils.toString(t.getRequestBody()); String body = Utils.toString(t.getRequestBody());
requestData = getGsonFactory().fromJson(body, LoginAccountRequestJson.class); requestData = getGsonFactory().fromJson(body, LoginAccountRequestJson.class);
} catch (Exception ignored) { } } catch (Exception ignored) {
}
// Create response json // Create response json
if (requestData == null) { if (requestData == null) {
@ -235,16 +303,19 @@ public final class DispatchServer {
} }
LoginResultJson responseData = new LoginResultJson(); LoginResultJson responseData = new LoginResultJson();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s is trying to log in", t.getRemoteAddress())); Grasscutter.getLogger()
.info(String.format("[Dispatch] Client %s is trying to log in", t.getRemoteAddress()));
// Login // Login
Account account = DatabaseHelper.getAccountByName(requestData.account); Account account = DatabaseHelper.getAccountByName(requestData.account);
// Check if account exists, else create a new one. // Check if account exists, else create a new one.
if (account == null) { if (account == null) {
// Account doesnt exist, so we can either auto create it if the config value is set // Account doesnt exist, so we can either auto create it if the config value is
// set
if (Grasscutter.getConfig().getDispatchOptions().AutomaticallyCreateAccounts) { if (Grasscutter.getConfig().getDispatchOptions().AutomaticallyCreateAccounts) {
// This account has been created AUTOMATICALLY. There will be no permissions added. // This account has been created AUTOMATICALLY. There will be no permissions
// added.
account = DatabaseHelper.createAccountWithId(requestData.account, 0); account = DatabaseHelper.createAccountWithId(requestData.account, 0);
if (account != null) { if (account != null) {
@ -253,18 +324,22 @@ public final class DispatchServer {
responseData.data.account.token = account.generateSessionKey(); responseData.data.account.token = account.generateSessionKey();
responseData.data.account.email = account.getEmail(); responseData.data.account.email = account.getEmail();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to log in: Account %s created", t.getRemoteAddress(), responseData.data.account.uid)); Grasscutter.getLogger()
.info(String.format("[Dispatch] Client %s failed to log in: Account %s created",
t.getRemoteAddress(), responseData.data.account.uid));
} else { } else {
responseData.retcode = -201; responseData.retcode = -201;
responseData.message = "Username not found, create failed."; responseData.message = "Username not found, create failed.";
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to log in: Account create failed", t.getRemoteAddress())); Grasscutter.getLogger().info(String.format(
"[Dispatch] Client %s failed to log in: Account create failed", t.getRemoteAddress()));
} }
} else { } else {
responseData.retcode = -201; responseData.retcode = -201;
responseData.message = "Username not found."; responseData.message = "Username not found.";
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to log in: Account no found", t.getRemoteAddress())); Grasscutter.getLogger().info(String
.format("[Dispatch] Client %s failed to log in: Account no found", t.getRemoteAddress()));
} }
} else { } else {
// Account was found, log the player in // Account was found, log the player in
@ -273,7 +348,8 @@ public final class DispatchServer {
responseData.data.account.token = account.generateSessionKey(); responseData.data.account.token = account.generateSessionKey();
responseData.data.account.email = account.getEmail(); responseData.data.account.email = account.getEmail();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in as %s", t.getRemoteAddress(), responseData.data.account.uid)); Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in as %s", t.getRemoteAddress(),
responseData.data.account.uid));
} }
responseJSON(t, responseData); responseJSON(t, responseData);
@ -285,14 +361,16 @@ public final class DispatchServer {
try { try {
String body = Utils.toString(t.getRequestBody()); String body = Utils.toString(t.getRequestBody());
requestData = getGsonFactory().fromJson(body, LoginTokenRequestJson.class); requestData = getGsonFactory().fromJson(body, LoginTokenRequestJson.class);
} catch (Exception ignored) { } } catch (Exception ignored) {
}
// Create response json // Create response json
if (requestData == null) { if (requestData == null) {
return; return;
} }
LoginResultJson responseData = new LoginResultJson(); LoginResultJson responseData = new LoginResultJson();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s is trying to log in via token", t.getRemoteAddress())); Grasscutter.getLogger()
.info(String.format("[Dispatch] Client %s is trying to log in via token", t.getRemoteAddress()));
// Login // Login
Account account = DatabaseHelper.getAccountById(requestData.uid); Account account = DatabaseHelper.getAccountById(requestData.uid);
@ -302,14 +380,16 @@ public final class DispatchServer {
responseData.retcode = -111; responseData.retcode = -111;
responseData.message = "Game account cache information error"; responseData.message = "Game account cache information error";
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to log in via token", t.getRemoteAddress())); Grasscutter.getLogger()
.info(String.format("[Dispatch] Client %s failed to log in via token", t.getRemoteAddress()));
} else { } else {
responseData.message = "OK"; responseData.message = "OK";
responseData.data.account.uid = requestData.uid; responseData.data.account.uid = requestData.uid;
responseData.data.account.token = requestData.token; responseData.data.account.token = requestData.token;
responseData.data.account.email = account.getEmail(); responseData.data.account.email = account.getEmail();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in via token as %s", t.getRemoteAddress(), responseData.data.account.uid)); Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in via token as %s",
t.getRemoteAddress(), responseData.data.account.uid));
} }
responseJSON(t, responseData); responseJSON(t, responseData);
@ -321,13 +401,15 @@ public final class DispatchServer {
try { try {
String body = Utils.toString(t.getRequestBody()); String body = Utils.toString(t.getRequestBody());
requestData = getGsonFactory().fromJson(body, ComboTokenReqJson.class); requestData = getGsonFactory().fromJson(body, ComboTokenReqJson.class);
} catch (Exception ignored) { } } catch (Exception ignored) {
}
// Create response json // Create response json
if (requestData == null || requestData.data == null) { if (requestData == null || requestData.data == null) {
return; return;
} }
LoginTokenData loginData = getGsonFactory().fromJson(requestData.data, LoginTokenData.class); // Get login data LoginTokenData loginData = getGsonFactory().fromJson(requestData.data, LoginTokenData.class); // Get login
// data
ComboTokenResJson responseData = new ComboTokenResJson(); ComboTokenResJson responseData = new ComboTokenResJson();
// Login // Login
@ -338,14 +420,16 @@ public final class DispatchServer {
responseData.retcode = -201; responseData.retcode = -201;
responseData.message = "Wrong session key."; responseData.message = "Wrong session key.";
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s failed to exchange combo token", t.getRemoteAddress())); Grasscutter.getLogger().info(
String.format("[Dispatch] Client %s failed to exchange combo token", t.getRemoteAddress()));
} else { } else {
responseData.message = "OK"; responseData.message = "OK";
responseData.data.open_id = loginData.uid; responseData.data.open_id = loginData.uid;
responseData.data.combo_id = "157795300"; responseData.data.combo_id = "157795300";
responseData.data.combo_token = account.generateLoginToken(); responseData.data.combo_token = account.generateLoginToken();
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s succeed to exchange combo token", t.getRemoteAddress())); Grasscutter.getLogger().info(
String.format("[Dispatch] Client %s succeed to exchange combo token", t.getRemoteAddress()));
} }
responseJSON(t, responseData); responseJSON(t, responseData);
@ -353,81 +437,76 @@ public final class DispatchServer {
// Agreement and Protocol // Agreement and Protocol
server.createContext( // hk4e-sdk-os.hoyoverse.com server.createContext( // hk4e-sdk-os.hoyoverse.com
"/hk4e_global/mdk/agreement/api/getAgreementInfos", "/hk4e_global/mdk/agreement/api/getAgreementInfos",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"marketing_agreements\":[]}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"marketing_agreements\":[]}}"));
server.createContext( // hk4e-sdk-os.hoyoverse.com server.createContext( // hk4e-sdk-os.hoyoverse.com
"/hk4e_global/combo/granter/api/compareProtocolVersion", "/hk4e_global/combo/granter/api/compareProtocolVersion",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"modified\":true,\"protocol\":{\"id\":0,\"app_id\":4,\"language\":\"en\",\"user_proto\":\"\",\"priv_proto\":\"\",\"major\":7,\"minimum\":0,\"create_time\":\"0\",\"teenager_proto\":\"\",\"third_proto\":\"\"}}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"modified\":true,\"protocol\":{\"id\":0,\"app_id\":4,\"language\":\"en\",\"user_proto\":\"\",\"priv_proto\":\"\",\"major\":7,\"minimum\":0,\"create_time\":\"0\",\"teenager_proto\":\"\",\"third_proto\":\"\"}}}"));
// Game data // Game data
server.createContext( // hk4e-api-os.hoyoverse.com server.createContext( // hk4e-api-os.hoyoverse.com
"/common/hk4e_global/announcement/api/getAlertPic", "/common/hk4e_global/announcement/api/getAlertPic",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"total\":0,\"list\":[]}}") new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"total\":0,\"list\":[]}}"));
);
server.createContext( // hk4e-api-os.hoyoverse.com server.createContext( // hk4e-api-os.hoyoverse.com
"/common/hk4e_global/announcement/api/getAlertAnn", "/common/hk4e_global/announcement/api/getAlertAnn",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"alert\":false,\"alert_id\":0,\"remind\":true}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"alert\":false,\"alert_id\":0,\"remind\":true}}"));
server.createContext( // hk4e-api-os.hoyoverse.com server.createContext( // hk4e-api-os.hoyoverse.com
"/common/hk4e_global/announcement/api/getAnnList", "/common/hk4e_global/announcement/api/getAnnList",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"list\":[],\"total\":0,\"type_list\":[],\"alert\":false,\"alert_id\":0,\"timezone\":0,\"t\":\"" + System.currentTimeMillis() + "\"}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"list\":[],\"total\":0,\"type_list\":[],\"alert\":false,\"alert_id\":0,\"timezone\":0,\"t\":\""
+ System.currentTimeMillis() + "\"}}"));
server.createContext( // hk4e-api-os-static.hoyoverse.com server.createContext( // hk4e-api-os-static.hoyoverse.com
"/common/hk4e_global/announcement/api/getAnnContent", "/common/hk4e_global/announcement/api/getAnnContent",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"list\":[],\"total\":0}}") new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"list\":[],\"total\":0}}"));
);
server.createContext( // hk4e-sdk-os.hoyoverse.com server.createContext( // hk4e-sdk-os.hoyoverse.com
"/hk4e_global/mdk/shopwindow/shopwindow/listPriceTier", "/hk4e_global/mdk/shopwindow/shopwindow/listPriceTier",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"suggest_currency\":\"USD\",\"tiers\":[]}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"suggest_currency\":\"USD\",\"tiers\":[]}}"));
// Captcha // Captcha
server.createContext( // api-account-os.hoyoverse.com server.createContext( // api-account-os.hoyoverse.com
"/account/risky/api/check", "/account/risky/api/check",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":\"c8820f246a5241ab9973f71df3ddd791\",\"action\":\"\",\"geetest\":{\"challenge\":\"\",\"gt\":\"\",\"new_captcha\":0,\"success\":1}}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":\"c8820f246a5241ab9973f71df3ddd791\",\"action\":\"\",\"geetest\":{\"challenge\":\"\",\"gt\":\"\",\"new_captcha\":0,\"success\":1}}}"));
// Config // Config
server.createContext( // sdk-os-static.hoyoverse.com server.createContext( // sdk-os-static.hoyoverse.com
"/combo/box/api/config/sdk/combo", "/combo/box/api/config/sdk/combo",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"vals\":{\"disable_email_bind_skip\":\"false\",\"email_bind_remind_interval\":\"7\",\"email_bind_remind\":\"true\"}}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"vals\":{\"disable_email_bind_skip\":\"false\",\"email_bind_remind_interval\":\"7\",\"email_bind_remind\":\"true\"}}}"));
server.createContext( // hk4e-sdk-os-static.hoyoverse.com server.createContext( // hk4e-sdk-os-static.hoyoverse.com
"/hk4e_global/combo/granter/api/getConfig", "/hk4e_global/combo/granter/api/getConfig",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"protocol\":true,\"qr_enabled\":false,\"log_level\":\"INFO\",\"announce_url\":\"https://webstatic-sea.hoyoverse.com/hk4e/announcement/index.html?sdk_presentation_style=fullscreen\\u0026sdk_screen_transparent=true\\u0026game_biz=hk4e_global\\u0026auth_appid=announcement\\u0026game=hk4e#/\",\"push_alias_type\":2,\"disable_ysdk_guard\":false,\"enable_announce_pic_popup\":true}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"protocol\":true,\"qr_enabled\":false,\"log_level\":\"INFO\",\"announce_url\":\"https://webstatic-sea.hoyoverse.com/hk4e/announcement/index.html?sdk_presentation_style=fullscreen\\u0026sdk_screen_transparent=true\\u0026game_biz=hk4e_global\\u0026auth_appid=announcement\\u0026game=hk4e#/\",\"push_alias_type\":2,\"disable_ysdk_guard\":false,\"enable_announce_pic_popup\":true}}"));
server.createContext( // hk4e-sdk-os-static.hoyoverse.com server.createContext( // hk4e-sdk-os-static.hoyoverse.com
"/hk4e_global/mdk/shield/api/loadConfig", "/hk4e_global/mdk/shield/api/loadConfig",
new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":6,\"game_key\":\"hk4e_global\",\"client\":\"PC\",\"identity\":\"I_IDENTITY\",\"guest\":false,\"ignore_versions\":\"\",\"scene\":\"S_NORMAL\",\"name\":\"原神海外\",\"disable_regist\":false,\"enable_email_captcha\":false,\"thirdparty\":[\"fb\",\"tw\"],\"disable_mmt\":false,\"server_guest\":false,\"thirdparty_ignore\":{\"tw\":\"\",\"fb\":\"\"},\"enable_ps_bind_account\":false,\"thirdparty_login_configs\":{\"tw\":{\"token_type\":\"TK_GAME_TOKEN\",\"game_token_expires_in\":604800},\"fb\":{\"token_type\":\"TK_GAME_TOKEN\",\"game_token_expires_in\":604800}}}}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":6,\"game_key\":\"hk4e_global\",\"client\":\"PC\",\"identity\":\"I_IDENTITY\",\"guest\":false,\"ignore_versions\":\"\",\"scene\":\"S_NORMAL\",\"name\":\"原神海外\",\"disable_regist\":false,\"enable_email_captcha\":false,\"thirdparty\":[\"fb\",\"tw\"],\"disable_mmt\":false,\"server_guest\":false,\"thirdparty_ignore\":{\"tw\":\"\",\"fb\":\"\"},\"enable_ps_bind_account\":false,\"thirdparty_login_configs\":{\"tw\":{\"token_type\":\"TK_GAME_TOKEN\",\"game_token_expires_in\":604800},\"fb\":{\"token_type\":\"TK_GAME_TOKEN\",\"game_token_expires_in\":604800}}}}"));
// Test api? // Test api?
server.createContext( // abtest-api-data-sg.hoyoverse.com server.createContext( // abtest-api-data-sg.hoyoverse.com
"/data_abtest_api/config/experiment/list", "/data_abtest_api/config/experiment/list",
new DispatchHttpJsonHandler("{\"retcode\":0,\"success\":true,\"message\":\"\",\"data\":[{\"code\":1000,\"type\":2,\"config_id\":\"14\",\"period_id\":\"6036_99\",\"version\":\"1\",\"configs\":{\"cardType\":\"old\"}}]}") new DispatchHttpJsonHandler(
); "{\"retcode\":0,\"success\":true,\"message\":\"\",\"data\":[{\"code\":1000,\"type\":2,\"config_id\":\"14\",\"period_id\":\"6036_99\",\"version\":\"1\",\"configs\":{\"cardType\":\"old\"}}]}"));
// Log Server // Log Server
server.createContext( // log-upload-os.mihoyo.com server.createContext( // log-upload-os.mihoyo.com
"/log/sdk/upload", "/log/sdk/upload",
new DispatchHttpJsonHandler("{\"code\":0}") new DispatchHttpJsonHandler("{\"code\":0}"));
);
server.createContext( // log-upload-os.mihoyo.com server.createContext( // log-upload-os.mihoyo.com
"/sdk/upload", "/sdk/upload",
new DispatchHttpJsonHandler("{\"code\":0}") new DispatchHttpJsonHandler("{\"code\":0}"));
);
server.createContext( // /perf/config/verify?device_id=xxx&platform=x&name=xxx server.createContext( // /perf/config/verify?device_id=xxx&platform=x&name=xxx
"/perf/config/verify", "/perf/config/verify",
new DispatchHttpJsonHandler("{\"code\":0}") new DispatchHttpJsonHandler("{\"code\":0}"));
);
// Logging servers // Logging servers
server.createContext( // overseauspider.yuanshen.com server.createContext( // overseauspider.yuanshen.com
"/log", "/log",
new DispatchHttpJsonHandler("{\"code\":0}") new DispatchHttpJsonHandler("{\"code\":0}"));
);
server.createContext( // log-upload-os.mihoyo.com server.createContext( // log-upload-os.mihoyo.com
"/crash/dataUpload", "/crash/dataUpload",
new DispatchHttpJsonHandler("{\"code\":0}") new DispatchHttpJsonHandler("{\"code\":0}"));
); server.createContext("/gacha", t -> responseHTML(t,
server.createContext("/gacha", t -> responseHTML(t, "<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>")); "<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>"));
// Start server // Start server
server.start(); server.start();
@ -475,7 +554,8 @@ public final class DispatchServer {
if (eqPos < 0 || eqPos > next) { if (eqPos < 0 || eqPos > next) {
result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), ""); result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), "");
} else { } else {
result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8")); result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"),
URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8"));
} }
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java

View File

@ -0,0 +1,55 @@
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.RewardData;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketAvatarDataNotify;
import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
import emu.grasscutter.server.packet.send.PacketAvatarFetterLevelRewardRsp;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify;
import emu.grasscutter.net.packet.PacketHandler;
@Opcodes(PacketOpcodes.AvatarFetterLevelRewardReq)
public class HandlerAvatarFetterLevelRewardReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
AvatarFetterLevelRewardReq req = AvatarFetterLevelRewardReq.parseFrom(payload);
if (req.getFetterLevel() < 10) {
// You don't have a full level of fetter level, why do you want to get a divorce certificate?
session.send(new PacketAvatarFetterLevelRewardRsp(req.getAvatarGuid(), req.getFetterLevel()));
} else {
long avatarGuid = req.getAvatarGuid();
GenshinAvatar avatar = session
.getPlayer()
.getAvatars()
.getAvatarByGuid(avatarGuid);
int rewardId = avatar.getNameCardRewardId();
RewardData card = GenshinData.getRewardDataMap().get(rewardId);
int cardId = card.getRewardItemList().get(0).getItemId();
if (session.getPlayer().getNameCardList().contains(cardId)) {
// Already got divorce certificate.
session.getPlayer().sendPacket(new PacketAvatarFetterLevelRewardRsp(req.getAvatarGuid(), req.getFetterLevel(), rewardId));
return;
}
GenshinItem item = new GenshinItem(cardId);
session.getPlayer().getInventory().addItem(item);
session.getPlayer().sendPacket(new PacketItemAddHintNotify(item, ActionReason.FetterLevelReward));
session.getPlayer().sendPacket(new PacketUnlockNameCardNotify(cardId));
session.send(new PacketAvatarFetterDataNotify(avatar));
session.send(new PacketAvatarDataNotify(avatar.getPlayer()));
session.send(new PacketAvatarFetterLevelRewardRsp(avatarGuid, req.getFetterLevel(), rewardId));
}
}
}

View File

@ -1,28 +1,34 @@
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketGetPlayerSocialDetailRsp; import emu.grasscutter.server.packet.send.PacketGetPlayerSocialDetailRsp;
import emu.grasscutter.server.packet.send.PacketSetPlayerBirthdayRsp; import emu.grasscutter.server.packet.send.PacketSetPlayerBirthdayRsp;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq;
import com.google.gson.Gson;
@Opcodes(PacketOpcodes.SetPlayerBirthdayReq) @Opcodes(PacketOpcodes.SetPlayerBirthdayReq)
public class HandlerSetPlayerBirthdayReq extends PacketHandler { public class HandlerSetPlayerBirthdayReq 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 {
SetPlayerBirthdayReq req = SetPlayerBirthdayReq.parseFrom(payload); SetPlayerBirthdayReq req = SetPlayerBirthdayReq.parseFrom(payload);
if(req.getBirth() != null && req.getBirth().getDay() > 0 && req.getBirth().getMonth() > 0) // RET_BIRTHDAY_CANNOT_BE_SET_TWICE = 7009
{ if (session.getPlayer().hasBirthday()) {
int day = req.getBirth().getDay(); session.send(new PacketSetPlayerBirthdayRsp(7009));
int month = req.getBirth().getMonth(); return;
}
int month = req.getBirthday().getMonth();
int day = req.getBirthday().getDay();
// RET_BIRTHDAY_FORMAT_ERROR = 7022
if (!isValidBirthday(month, day)) {
session.send(new PacketSetPlayerBirthdayRsp(7022));
return;
}
// Update birthday value // Update birthday value
session.getPlayer().setBirthday(day, month); session.getPlayer().setBirthday(day, month);
@ -34,5 +40,28 @@ public class HandlerSetPlayerBirthdayReq extends PacketHandler {
session.send(new PacketSetPlayerBirthdayRsp(session.getPlayer())); session.send(new PacketSetPlayerBirthdayRsp(session.getPlayer()));
session.send(new PacketGetPlayerSocialDetailRsp(detail)); session.send(new PacketGetPlayerSocialDetailRsp(detail));
} }
private boolean isValidBirthday(int month, int day) {
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return day > 0 & day <= 31;
case 4:
case 6:
case 9:
case 11:
return day > 0 && day <= 30;
case 2:
return day > 0 & day <= 29;
} }
return false;
}
} }

View File

@ -0,0 +1,48 @@
package emu.grasscutter.server.packet.recv;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.common.RewardItemData;
import emu.grasscutter.game.inventory.GenshinItem;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import emu.grasscutter.server.packet.send.PacketTakePlayerLevelRewardRsp;
@Opcodes(PacketOpcodes.TakePlayerLevelRewardReq)
public class HandlerTakePlayerLevelRewardReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
TakePlayerLevelRewardReq req = TakePlayerLevelRewardReq.parseFrom(payload);
int level = req.getLevel();
int rewardId = GenshinData.getPlayerLevelDataMap().get(level).getRewardId();
if (rewardId != 0) {
List<RewardItemData> rewardItems = GenshinData.getRewardDataMap().get(rewardId).getRewardItemList();
List<GenshinItem> items = new LinkedList<>();
for (RewardItemData rewardItem : rewardItems) {
if (rewardItem != null) {
if (rewardItem.getItemId() != 0) {
items.add(new GenshinItem(rewardItem.getItemId(), rewardItem.getItemCount()));
}
}
}
session.getPlayer().getInventory().addItems(items);
session.getPlayer().sendPacket(new PacketItemAddHintNotify(items, ActionReason.PlayerUpgradeReward));
Set<Integer> rewardedLevels = session.getPlayer().getRewardedLevels();
rewardedLevels.add(level);
session.getPlayer().setRewardedLevels(rewardedLevels);
}
session.send(new PacketTakePlayerLevelRewardRsp(level, rewardId));
}
}

View File

@ -0,0 +1,49 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.props.FetterState;
import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarFetterDataNotifyOuterClass.AvatarFetterDataNotify;
import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo;
import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData;
public class PacketAvatarFetterDataNotify extends GenshinPacket {
public PacketAvatarFetterDataNotify(GenshinAvatar avatar) {
super(PacketOpcodes.AvatarFetterDataNotify);
int fetterLevel = avatar.getFetterLevel();
AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder()
.setExpLevel(avatar.getFetterLevel());
if (fetterLevel != 10) {
avatarFetter.setExpNumber(avatar.getFetterExp());
}
if (avatar.getFetterList() != null) {
for (int i = 0; i < avatar.getFetterList().size(); i++) {
avatarFetter.addFetterList(
FetterData.newBuilder()
.setFetterId(avatar.getFetterList().get(i))
.setFetterState(FetterState.FINISH.getValue())
);
}
}
int cardId = avatar.getNameCardId();
if (avatar.getPlayer().getNameCardList().contains(cardId)) {
avatarFetter.addRewardedFetterLevelList(10);
}
AvatarFetterInfo avatarFetterInfo = avatarFetter.build();
AvatarFetterDataNotify proto = AvatarFetterDataNotify.newBuilder()
.putFetterInfoMap(avatar.getGuid(), avatarFetterInfo)
.build();
this.setData(proto);
}
}

View File

@ -0,0 +1,35 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.AvatarFetterLevelRewardRspOuterClass.AvatarFetterLevelRewardRsp;
public class PacketAvatarFetterLevelRewardRsp extends GenshinPacket {
public PacketAvatarFetterLevelRewardRsp(long guid, int fetterLevel, int rewardId) {
super(PacketOpcodes.AvatarFetterLevelRewardRsp);
AvatarFetterLevelRewardRsp proto = AvatarFetterLevelRewardRsp.newBuilder()
.setAvatarGuid(guid)
.setFetterLevel(fetterLevel)
.setRetcode(0)
.setRewardId(rewardId)
.build();
this.setData(proto);
}
public PacketAvatarFetterLevelRewardRsp(long guid, int fetterLevel) {
super(PacketOpcodes.AvatarFetterLevelRewardRsp);
AvatarFetterLevelRewardRsp proto = AvatarFetterLevelRewardRsp.newBuilder()
.setAvatarGuid(guid)
.setFetterLevel(fetterLevel)
.setRetcode(1)
.setRewardId(0)
.build();
this.setData(proto);
}
}

View File

@ -0,0 +1,22 @@
package emu.grasscutter.server.packet.send;
import java.util.Set;
import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.PlayerLevelRewardUpdateNotifyOuterClass.PlayerLevelRewardUpdateNotify;
public class PacketPlayerLevelRewardUpdateNotify extends GenshinPacket {
public PacketPlayerLevelRewardUpdateNotify(Set<Integer> rewardedLevels) {
super(PacketOpcodes.PlayerLevelRewardUpdateNotify);
PlayerLevelRewardUpdateNotify.Builder proto = PlayerLevelRewardUpdateNotify.newBuilder();
for (Integer level : rewardedLevels) {
proto.addLevelList(level);
}
this.setData(proto.build());
}
}

View File

@ -1,18 +1,27 @@
package emu.grasscutter.server.packet.send; package emu.grasscutter.server.packet.send;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.GenshinPlayer; import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp; import emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp;
import emu.grasscutter.net.proto.BirthdayOuterClass.Birthday;
public class PacketSetPlayerBirthdayRsp extends GenshinPacket { public class PacketSetPlayerBirthdayRsp extends GenshinPacket {
public PacketSetPlayerBirthdayRsp(int retCode) {
super(PacketOpcodes.SetPlayerBirthdayRsp);
SetPlayerBirthdayRsp proto = SetPlayerBirthdayRsp.newBuilder()
.setRetcode(retCode)
.build();
this.setData(proto);
}
public PacketSetPlayerBirthdayRsp(GenshinPlayer player) { public PacketSetPlayerBirthdayRsp(GenshinPlayer player) {
super(PacketOpcodes.SetPlayerBirthdayRsp); super(PacketOpcodes.SetPlayerBirthdayRsp);
SetPlayerBirthdayRsp proto = SetPlayerBirthdayRsp.newBuilder() SetPlayerBirthdayRsp proto = SetPlayerBirthdayRsp.newBuilder()
.setBirth(player.getBirthday().toProto()) .setBirthday(player.getBirthday().toProto())
.build(); .build();
this.setData(proto); this.setData(proto);

View File

@ -0,0 +1,26 @@
package emu.grasscutter.server.packet.send;
import emu.grasscutter.net.packet.GenshinPacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TakePlayerLevelRewardRspOuterClass.TakePlayerLevelRewardRsp;
public class PacketTakePlayerLevelRewardRsp extends GenshinPacket {
public PacketTakePlayerLevelRewardRsp(int level, int rewardId) {
super(PacketOpcodes.TakePlayerLevelRewardRsp);
int retcode = 0;
if (rewardId == 0) {
retcode = 1;
}
TakePlayerLevelRewardRsp proto = TakePlayerLevelRewardRsp.newBuilder()
.setLevel(level)
.setRewardId(rewardId)
.setRetcode(retcode)
.build();
this.setData(proto);
}
}

View File

@ -74,10 +74,11 @@ for /f "tokens=2*" %%a in ('reg query "HKCU\Software\Microsoft\Windows\CurrentVe
@rem TODO: External proxy when ORIG_PROXY_ENABLE == 0x1 @rem TODO: External proxy when ORIG_PROXY_ENABLE == 0x1
echo set ws = createobject("wscript.shell") > "%temp%\proxy.vbs" echo set ws = createobject("wscript.shell") > "%temp%\proxy.vbs"
if not "%MITMDUMP_PATH%" == "" ( if not "%MITMDUMP_PATH%" == "" (
echo ws.currentdirectory = "%MITMDUMP_PATH%" >> "%temp%\proxy.vbs" echo ws.currentdirectory = "%MITMDUMP_PATH%" >> "%temp%\proxy.vbs"
) )
echo ws.run "cmd /c mitmdump.exe -s "^&chr(34)^&"%PROXY_SCRIPT_NAME%"^&chr(34)^&" -k",0 >> "%temp%\proxy.vbs" echo ws.run "cmd /c mitmdump.exe -s "^&chr(34)^&"%CUR_PATH%%PROXY_SCRIPT_NAME%"^&chr(34)^&" -k --allow-hosts "^&chr(34)^&".*\.yuanshen\.com|.*\.mihoyo\.com|.*\.hoyoverse\.com"^&chr(34),0 >> "%temp%\proxy.vbs"
"%temp%\proxy.vbs" "%temp%\proxy.vbs"
del /f /q "%temp%\proxy.vbs" >nul 2>nul del /f /q "%temp%\proxy.vbs" >nul 2>nul