UPGRADE TO 1.1.0 POG

Merge `development` into `stable`
This commit is contained in:
Magix 2022-05-07 18:18:18 -04:00 committed by GitHub
commit 658ee3b547
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1387 changed files with 229476 additions and 354986 deletions

View File

@ -0,0 +1,23 @@
---
name: Issues
about: Create an issue if you need any help
title: '[Issue] '
labels: 'help wanted, question'
assignees: ''
---
**Did you look for other closed issues that have the same problem?**
<!--- It will be easier for us to solve your problem if there is less duplication of problems -->
**Describe the issue**
<!--- A clear and concise description of what the issue is. -->
**Which branch did you use?**
<!--- Stable branch / Development branch -->
**Screenshots**
<!--- If applicable, add screenshots to help explain your problem. -->
**Additional context**
<!--- Add any other context about the problem here. -->

21
.github/ISSUE_TEMPLATE/b_bug_report.md vendored Normal file
View File

@ -0,0 +1,21 @@
---
name: Bug report
about: Create a bug report to help us improve Grasscutter
title: '[Bug] '
labels: 'bug'
assignees: ''
---
<!--- ONLY USE this form for bug reporting. If you need help or support, please USE issue report form instead. -->
**Describe the bug**
<!--- A clear and concise description of what the bug is. -->
**Which branch did you use?**
<!--- Stable branch / Development branch -->
**Screenshots**
<!--- If applicable, add screenshots to help explain your problem. -->
**Additional context**
<!--- Add any other context about the problem here. -->

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for Grasscutter
title: '[Feature Request] '
labels: 'enhancement, suggestion'
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. -->

6
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,6 @@
blank_issues_enabled: false
contact_links:
- name: Grasscutter Discord
url: https://discord.gg/T5vZU6UyeG
about: For support, discuss and and other things with Grasscutter.

22
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,22 @@
## Description
Please carefully read the [Contributing note](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) and [Code of conduct](https://github.com/Grasscutters/Grasscutter/blob/development/CODE_OF_CONDUCT.md) before making any pull requests.
And, **Do not make a pull request to merge into stable unless it is a hotfix. Use the development branch instead.**
## Issues fixed by this PR
<!--- Put the links of issues that may be fixed by this PR here (if any). -->
## Type of changes
<!--- Put an `x` in all the boxes that apply your changes. -->
- [ ] Bug fix
- [ ] New feature
- [ ] Enhancement
- [ ] Documentation
## Checklist:
- [ ] My code follows the style guidelines of this project
- [ ] My pull request is unique and no other pull requests have been opened for these changes
- [ ] I have read the [Contributing note](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) and [Code of conduct](https://github.com/Grasscutters/Grasscutter/blob/development/CODE_OF_CONDUCT.md)
- [ ] I am responsible for any copyright issues with my code if it occurs in the future.

View File

@ -1,11 +1,22 @@
name: "Build"
on:
workflow_dispatch: ~
push:
paths:
- "**.java"
branches:
- "stable"
- "development"
pull_request:
paths:
- "**.java"
types:
- opened
- synchronize
- reopened
jobs:
Build-Server-Jar:
runs-on: windows-latest
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
@ -13,12 +24,11 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: '8'
java-version: '17'
- name: Run Gradle
run: .\gradlew.bat && .\gradlew jar
run: ./gradlew && ./gradlew jar
- name: Upload build
uses: actions/upload-artifact@v3
with:
name: Grasscutter
path: grasscutter.jar
path: grasscutter-*-dev.jar

21
.gitignore vendored
View File

@ -30,6 +30,9 @@ hs_err_pid*
build/
out/
# Ignore Gradle properties
gradle.properties
# Eclipse
.project
.classpath
@ -45,14 +48,24 @@ tmp/
.loadpath
.recommenders
# VSCode
.vscode
# Grasscutter
resources/*
resources/
logs/
plugins/
data/AbilityEmbryos.json
data/OpenConfig.json
proto/auto/
proto/protoc.exe
GM Handbook.txt
config.json
mitmdump.exe
grasscutter.jar
*.jar
!lib/*.jar
mongod.exe
/src/generated/
/*.sh
language/
languages/
gacha-mapping.js
data/gacha_mappings.js

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "Grasscutter-Protos"]
path = Grasscutter-Protos
url = https://github.com/Melledy/Grasscutter-Protos

@ -1 +0,0 @@
Subproject commit 0537e9cc4c7856a7c6f88bbbaa908a80c4ee677e

172
README.md
View File

@ -1,79 +1,159 @@
# Grasscutter
A WIP server reimplementation for *some anime game* 2.3-2.6
![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_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
* Combat
* Friends list
* Teleportation
* Gacha system
* Co-op *partially* works
* Spawning monsters via console
* 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
* JDK-8u202 ([mirror link](https://mirrors.huaweicloud.com/java/jdk/8u202-b08/) since Oracle required an account to download old builds)
* Mongodb (recommended 4.0+)
## Quick setup guide
**Note:** For support please join our [Discord](https://discord.gg/T5vZU6UyeG).
### Requirements
* Java SE - 17 ([link](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html))
**Note:** If you just want to **run it**, then **jre** only is fine.
* MongoDB (recommended 4.0+)
* Proxy daemon: mitmproxy (mitmdump, recommended), Fiddler Classic, etc.
### Starting up Grasscutter server (Assuming you are on Windows)
1. Setup compile environment `gradlew.bat`
2. Compile Grasscutter with `gradlew jar`
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.
### Running
**Note:** If you updated from an older version, delete `config.json` to regenerate it.
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 move your `BinOutput` and `ExcelBinOutput` folders there *(Check the [wiki](https://github.com/Grasscutters/Grasscutter/wiki) for more details how to get those.)*
3. Run Grasscutter with `java -jar grasscutter.jar`. **Make sure mongodb service is running as well.**
### Connecting with the client
½. Create an account 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`
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).
- [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.
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
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.
### Building
`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 - 17
- 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
You may want to use this command (`java -jar grasscutter.jar -gachamap`) to generate a mapping file for the gacha record subsystem. The file will be generated to `GRASSCUTTER_RESOURCE/gcstatic` folder. Otherwise you may only see number IDs in the gacha record page.
`pos` - Gets your current coordinate.
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`
`weather [weather id] [climate id]` - Changes the current weather.
*More commands will be updated in the [wiki](https://github.com/Melledy/Grasscutter/wiki/).*
| Commands | Usage | Permission node | Availability | description | Alias |
| -------------- | ------------------------------------------------- | ------------------------- | ------------ | ------------------------------------------------------------ | ----------------------------------------------- |
| 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 |
| coop | coop \<playerId> \<target playerId> | server.coop | Both side | Forces someone to join the world of others. | |
| changescene | changescene \<scene id> | player.changescene | Client only | Switch scenes by scene ID. | scene |
| clear | clear <all\|wp\|art\|mat> [UID] | player.clearinv | Client only | Deletes all unequipped and unlocked level 0 artifacts(art)/weapons(wp)/material(all) or all, including 5-star rarity ones from your inventory. | clear |
| drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` |
| enterdungeon | enterdungeon \<dungeon id> | player.enterdungeon | Client only | Enter a dungeon by dungeon ID | |
| give | give [player] <itemId\|itemName> [amount] [level] [finement] | player.give | Both side | Gives item(s) to you or the specified player. (finement option only weapon.) | `g` `item` `giveitem` |
| givechar | givechar \<uid> \<avatarId> | player.givechar | Both side | Gives the player a specified character. | givec |
| giveart | giveart [player] \<artifactId> \<mainPropId> [\<appendPropId>[,\<times>]]... [level] | player.giveart | Both side | Gives the player a specified artifact. | gart |
| giveall | giveall [uid] [amount] | player.giveall | Both side | Gives all items. | givea |
| godmode | godmode [uid] | player.godmode | Client only | Prevents you from taking damage. | |
| heal | heal | player.heal | Client only | Heals 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 | Kills all entities in the current scene or specified scene of the corresponding player. | |
| list | list | | Both side | Lists online players. | |
| permission | permission <add\|remove> \<UID> \<permission> | * | Both side | Grants or removes a permission for a user. | |
| position | position | | Client only | Sends your current coordinates. | pos |
| reload | reload | server.reload | Both side | Reloads the server config | |
| resetconst | resetconst [all] | player.resetconstellation | Client only | Resets the constellation level on your currently selected 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 the friendship level for your currently selected character | setfetterlvl |
| setstats | setstats \<stat> \<value> | player.setstats | Client only | Sets a stat for your currently selected character | stats |
| setworldlevel | setworldlevel \<level> | player.setworldlevel | Client only | Sets your world level (Relog to see proper effects) | setworldlvl |
| spawn | spawn \<entityId> [amount] [level(monster only)] | server.spawn | Client only | Spawns some entities around you | |
| stop | stop | server.stop | Both side | Stops the server | |
| talent | talent \<talentID> \<value> | player.settalent | Client only | Sets talent level for your currently selected character | |
| teleport | teleport [@playerUid] \<x> \<y> \<z> [sceneId] | player.teleport | Both side | Change the player's position. | tp |
| tpall | | player.tpall | Client only | Teleports all players in your world to your position | |
| weather | weather \<weatherID> \<climateID> | player.weather | Client only | Changes the weather | w |
### 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.
- Teleporting
- When you want to teleport to somewhere, use the in-game marking function on Map.
- Mark a point on the map using the fish hook marking (the last one.)
- (Optional) rename the map marker to a number to override the default Y coordinate (height, default 300.)
- Confirm and close the map.
- You will see your character falling from a very high destination, exact location that you marked.
# 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
* Startup sequence: Mongodb > Grasscutter > Proxy daemon (mitmdump, fiddler, etc.) > Client
* If compiling wasn't successful, please check your JDK installation (JDK 17 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.) > Game

159
README_zh-CN.md Normal file
View File

@ -0,0 +1,159 @@
![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 - 17 (当您没有Oracle账户可以使用[镜像](https://mirrors.tuna.tsinghua.edu.cn/Adoptium/17/jdk/))
**注:** 如果您仅仅想要简单地**运行服务端**, 那么使用 **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 - 17
- 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等
你可能需要在终端中运行 `java -jar grasscutter.jar -gachamap` 来使得祈愿历史记录系统正常显示物品信息。 这个命令生成一个配置文件到如下文件夹:`GRASSCUTTER_RESOURCE/gcstatic`。 不执行此命令您的祈愿历史记录中将只会显示数字ID而非物品名称。目前仅支持自动生成英文记录信息
在每个玩家的朋友列表中都有一个名为“Server”的虚拟用户你可以通过发送消息来使用命令。命令也适用于其他聊天室例如私人/团队聊天。
要在游戏中使用命令,需要添加 `/``!` 前缀,如 `/pos`
| 命令 | 用法 | 权限节点 | 可用性 | 注释 | 别名 |
| -------------- | -------------------------------------------- | ------------------------- | -------- | ------------------------------------------ | ----------------------------------------------- |
| account | account <create\|delete> <用户名> [uid] | | 仅服务端 | 通过指定用户名和uid增删账户 | |
| broadcast | broadcast <消息内容> | server.broadcast | 均可使用 | 给所有玩家发送公告 | b |
| coop | coop \<uid> <目标uid> | server.coop | 均可使用 | 强制某位玩家进入指定玩家的多人世界 | |
| changescene | changescene <场景ID> | player.changescene | 仅客户端 | 切换到指定场景 | scene |
| clear | clear <all\|wp\|art\|mat> [UID] | player.clearinv | 仅客户端 | 删除所有未装备及未解锁的圣遗物(art)或武器(wp)或材料(mat)或者所有(all),包括五星 | clear |
| drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` |
| enterdungeon | enterdungeon <地牢ID> | player.enterdungeon | 仅客户端 | 进入某个地牢 | |
| give | give [uid] <物品ID\|物品名称> [数量] [等级] [精炼等级] | player.give | 均可使用 | 给予指定玩家一定数量及等级的物品 (精炼等级仅适用于武器) | `g` `item` `giveitem` |
| givechar | givechar \<uid> <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec |
| giveart | giveart [uid] \<圣遗物ID> \<主属性ID> [\<副属性ID>[,<次数>]]... [等级] | player.giveart | 均可使用 | 给予玩家指定属性的圣遗物 | gart |
| giveall | giveall [uid] [数量] | player.giveall | 均可使用 | 给予指定玩家全部物品 | givea |
| 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> <UID> <权限节点> | * | 均可使用 | 添加或移除玩家的权限 | |
| 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 | spawn <实体ID> [数量] [等级] | server.spawn | 仅客户端 | 在你周围生成实体 | |
| stop | stop | server.stop | 均可使用 | 停止服务器 | |
| talent | talent <天赋ID> <等级> | player.settalent | 仅客户端 | 设置当前角色的天赋等级 | |
| teleport | teleport [@playerUid] \<x> \<y> \<z> [sceneId] | player.teleport | 均可使用 | 传送玩家到指定坐标 | tp |
| tpall | | player.tpall | 仅客户端 | 传送多人世界中所有的玩家到自身地点 | |
| weather | weather <天气ID> <气候ID> | player.weather | 仅客户端 | 改变天气 | w |
### 额外功能
当你想传送到某个地点, 只需要在地图中创建标记, 关闭地图后即可到达目标地点上空
- 传送
- 当你想传送到某个地点时,可以使用游戏里的地图标记功能。
- 用鱼钩(最后一个图标)在地图上标记一个点位。
- (可选) 将标记名称改为数字即可修改传送位置的Y坐标高度缺省值是300
- 确认添加标记,并关闭地图。
- 你会看到你的角色从你选定点位的正上方高空落下。
# 快速排除问题
* 如果编译未能成功,请检查您的jdk安装 (JDK 17并确认jdk处于环境变量`PATH`中
* 我的客户端无法登录/连接, 4206, 其它... - 大部分情况下这是因为您的代理存在问题.如果使用Fiddler请确认Fiddler监听端口不是`8888`
* 启动顺序: MongoDB > Grasscutter > 代理程序 (mitmdump, fiddler等.) > 客户端

View File

@ -6,38 +6,90 @@
* User Manual available at https://docs.gradle.org/5.6.3/userguide/tutorial_java_projects.html
*/
buildscript {
repositories {
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.18'
}
}
plugins {
// Apply the application plugin to add support for building a CLI application
id 'application'
// Apply the java plugin to add support for Java
id 'java'
// Apply the application plugin to add support for building a CLI application
id 'application'
// Apply the protobuf auto generator
id 'com.google.protobuf' version "0.8.18"
// Eclipse Support
id 'eclipse'
// IntelliJ Support
id 'idea'
// Maven
id 'maven-publish'
id 'signing'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
compileJava.options.encoding = "UTF-8"
compileTestJava.options.encoding = "UTF-8"
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
group = 'xyz.grasscutters'
version = '1.1.0'
sourceCompatibility = 17
targetCompatibility = 17
java {
withJavadocJar()
withSourcesJar()
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation fileTree(dir: 'lib', include: ['*.jar'])
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-classic', version: '1.2.6'
implementation group: 'io.netty', name: 'netty-all', version: '4.1.69.Final'
implementation group: 'ch.qos.logback', name: 'logback-core', version: '1.2.9'
implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.9'
implementation group: 'org.jline', name: 'jline', version: '3.21.0'
implementation group: 'org.jline', name: 'jline-terminal-jna', version: '3.21.0'
implementation group: 'net.java.dev.jna', name: 'jna', version: '5.10.0'
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.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: 'dev.morphia.morphia', name: 'core', version: '1.6.1'
implementation group: 'dev.morphia.morphia', name: 'morphia-core', version: '2.2.6'
implementation group: 'org.greenrobot', name: 'eventbus-java', version: '3.3.1'
implementation group: 'org.danilopianini', name: 'java-quadtree', version: '0.1.9'
implementation group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.2'
implementation group: 'org.quartz-scheduler', name: 'quartz-jobs', version: '2.3.2'
implementation group: 'org.luaj', name: 'luaj-jse', version: '3.0.1'
protobuf files('proto/')
}
configurations.all {
exclude group: 'org.slf4j', module: 'slf4j'
}
application {
@ -65,3 +117,115 @@ jar {
destinationDir = file(".")
}
publishing {
publications {
mavenJava(MavenPublication) {
artifactId = 'grasscutter'
from components.java
versionMapping {
usage('java-api') {
fromResolutionOf('runtimeClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
pom {
name = 'Grasscutter'
description = 'A server software reimplementation for an anime game.'
url = 'https://github.com/Grasscutters/Grasscutter'
licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id = 'meledy'
name = 'Meledy'
email = 'meledy@xigam.tech' // not a real email kek
}
developer {
id = 'magix'
name = 'Magix'
email = 'magix@xigam.tech'
}
}
scm {
connection = 'scm:git:git@github.com:Grasscutters/Grasscutter.git'
developerConnection = 'scm:git:ssh://github.com:Grasscutters/Grasscutter.git'
url = 'https://github.com/Grasscutters/Grasscutter'
}
}
}
}
repositories {
maven {
// change URLs to point to your repos, e.g. http://my.org/repo
def releasesRepoUrl = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
def snapshotsRepoUrl = 'https://s01.oss.sonatype.org/content/repositories/snapshots/'
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
name = 'sonatype'
credentials(PasswordCredentials)
}
}
}
clean {
delete protobuf.generatedFilesBaseDir
}
protobuf {
protoc {
// The artifact spec for the Protobuf Compiler
artifact = 'com.google.protobuf:protoc:3.18.1'
}
// generatedFilesBaseDir = "$projectDir/src/main/java/emu/grasscutter/net/proto/"
generatedFilesBaseDir = "$projectDir/src/generated/"
}
sourceSets {
main {
proto {
// In addition to the default 'src/main/proto'
srcDir 'src/generated'
}
java {
srcDir 'src/java'
}
}
}
idea {
module {
// proto files and generated Java files are automatically added as
// source dirs.
// If you have additional sources, add them here:
sourceDirs += file("/proto/");
}
}
eclipse {
classpath {
file.whenMerged { cp ->
cp.entries.add( new org.gradle.plugins.ide.eclipse.model.SourceFolder('src/generated/main/java', null) )
}
}
}
signing {
sign publishing.publications.mavenJava
}
javadoc {
options.encoding = 'UTF-8'
if(JavaVersion.current().isJava9Compatible()) {
options.addBooleanOption('html5', true)
}
}
processResources {
dependsOn "generateProto"
}

199808
data/Drop.json Normal file

File diff suppressed because it is too large Load Diff

1072
data/ExpeditionReward.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
{
"list": [
{
"ann_id": 1,
"title": "<b>Welcome to Grasscutter!</b>",
"subtitle": "<b>Welcome</b>",
"banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/17/f4aa42d505822805eebf4a55d72a78d8_2755691727027973637.jpg",
"content": "Hi there!<br>First of all, welcome to Grasscutter. If you have any issues, please let us know so that Lawnmower can help you! Check out our:<br><div><p style=\"white-space: pre-wrap;\"><strong>¡þDiscord¡þ</strong></p><p style=\"white-space: pre-wrap;\"><a href=\"https://discord.gg/T5vZU6UyeG\">https://discord.gg/T5vZU6UyeG</a></p><p style=\"white-space: pre-wrap;\"><strong>¡þGitHub¡þ</strong></p><p style=\"white-space: pre-wrap;\"><a href=\"https://github.com/Grasscutters/Grasscutter\">https://github.com/Grasscutters/Grasscutter</a></p></div>",
"lang": "es-es"
},
{
"ann_id": 2,
"title": "<b>How to use announcements</b>",
"subtitle": "<b>How to use</b>",
"banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/17/f4aa42d505822805eebf4a55d72a78d8_2755691727027973637.jpg",
"content": "<strong>Tips<br></strong>>How to use announcements<br><br>>Announcement content can use HTML<br><br>>The specific content of the announcement is stored in the program directory<code>data/GameAnnouncement.json</code>, while<code>GameAnnouncementList.json</code> stores the announcement list data<br><br><strong>How to use</strong><br>>In <code>GameAnnouncement</code><table><thead><thead><tr><th>Parameters</th><th>Description</th></thead></thead><thbody><thead><tr><th>ann_Id</th><th>Announcement unique id</th></thead><thead><tr><th>title</th><th>Show at the top of the content</th></thead><thead><tr><th>subtitle</th><th>title shown on the left</th></thead><thead><tr><th>banner</th><th>Display between content and title</th></thead><thead><tr><th>content</th><th>as u see</th></thead><thead><tr><th>lang</th><th>display language</th></thead><thead><tr><th>total</th><th>Announcement quantity</th></thead></thbody></table><br><br>>In <code>GameAnnouncementList</code><br>If you want to add an annouement, please add the list data in the announcement type corresponding to GameAnnouncementList, and finally add the announcement content in GameAnnouncement",
"lang": "es-es"
},
{
"ann_id": 3,
"title": "<b>ÕâÊǻ¹«¸æ--This is the event announcement</b>",
"subtitle": "<b>Welcome</b>",
"banner":"https://uploadstatic-sea.mihoyo.com/announcement/2020/09/22/7d85f19b152d218e73224d7c138a0fd0_5818585260283672899.jpg",
"content": "Welcome",
"lang": "es-es"
}
],
"total": 3
}

View File

@ -0,0 +1,119 @@
{
"t": "System.currentTimeMillis()",
"list": [
{
"list": [
{
"ann_id": 1,
"title": "<b>Welcome to Grasscutter!</b>",
"subtitle": "<b>Welcome</b>",
"banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/22/7d85f19b152d218e73224d7c138a0fd0_5818585260283672899.jpg",
"content": "",
"type_label": "Juego",
"tag_label": "1",
"tag_icon": "https://uploadstatic-sea.mihoyo.com/announcement/2020/03/05/a2588f1a51faee9fa8dfe9aead649dd6_7237021399135895303.png",
"login_alert": 1,
"lang": "es-es",
"start_time": "2020-09-25 04:05:30",
"end_time": "2023-10-30 11:00:00",
"type": 2,
"remind": 0,
"alert": 0,
"tag_start_time": "2000-01-02 15:04:05",
"tag_end_time": "2030-01-02 15:04:05",
"remind_ver": 1,
"has_content": true,
"extra_remind": 0
},
{
"ann_id": 2,
"title": "<b>这是游戏公告 -- This is the game announcement</b>",
"subtitle": "<b>This is the game announcement</b>",
"banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/17/85b7163c95745a76d49b3d163d893592_6487108933004985049.jpg",
"content": "",
"type_label": "Juego",
"tag_label": "1",
"tag_icon": "https://uploadstatic-sea.mihoyo.com/announcement/2020/03/05/a2588f1a51faee9fa8dfe9aead649dd6_7237021399135895303.png",
"login_alert": 1,
"lang": "es-es",
"start_time": "2020-09-25 15:12:09",
"end_time": "2030-10-30 11:00:00",
"type": 2,
"remind": 0,
"alert": 0,
"tag_start_time": "2000-01-02 08:04:05",
"tag_end_time": "2030-01-02 08:04:05",
"remind_ver": 1,
"has_content": true,
"extra_remind": 0
}
],
"type_id": 2,
"type_label": "Juego"
},
{
"list": [
{
"ann_id": 3,
"title": "<b>这是活动公告--This is the event announcement</b>",
"subtitle": "<b>Welcome</b>",
"banner": "https://uploadstatic-sea.mihoyo.com/announcement/2020/09/22/7d85f19b152d218e73224d7c138a0fd0_5818585260283672899.jpg",
"content": "",
"type_label": "Eventos",
"tag_label": "1",
"tag_icon": "https://uploadstatic-sea.mihoyo.com/announcement/2020/03/05/a2588f1a51faee9fa8dfe9aead649dd6_7237021399135895303.png",
"login_alert": 1,
"lang": "es-es",
"start_time": "2020-09-25 04:05:30",
"end_time": "2022-05-02 00:51:00",
"type": 2,
"remind": 0,
"alert": 0,
"tag_start_time": "2000-01-02 15:04:05",
"tag_end_time": "2022-05-02 00:51:00",
"remind_ver": 1,
"has_content": true,
"extra_remind": 0
}
],
"type_id": 1,
"type_label": "Eventos"
},
{
"list": [
{}
],
"type_id": 3,
"type_label": "Others"
}
],
"total": 3,
"type_list": [
{
"id": 2,
"name": "游戏系统公告",
"mi18n_name": "Juego"
},
{
"id": 1,
"name": "活动公告",
"mi18n_name": "Eventos"
},
{
"id": 3,
"name": "其他",
"mi18n_name": "Others"
}
],
"alert": true,
"alert_id": 2,
"timezone": -5,
"pic_list": [
],
"pic_total": 0,
"pic_type_list": [
],
"pic_alert": false,
"pic_alert_id": 0,
"static_sign": ""
}

54
data/Shop.json Normal file
View File

@ -0,0 +1,54 @@
[
{
"shopId": 1004,
"items": [
{
"goodsId": 1004202,
"goodsItem": {
"Id": 202,
"Count": 1000000
},
"scoin": 1,
"buyLimit": 500,
"beginTime": 1575129600,
"endTime": 2051193600,
"minLevel": 1,
"maxLevel": 99,
"costItemList": [
{
"Id": 223,
"Count": 100
}
]
},
{
"goodsId": 10048006,
"goodsItem": {
"Id": 108006,
"Count": 20
},
"scoin": 100,
"hcoin": 100,
"mcoin": 100,
"buyLimit": 50000,
"beginTime": 1575129600,
"endTime": 2051193600,
"minLevel": 1,
"maxLevel": 99
},
{
"goodsId": 10048033,
"goodsItem": {
"Id": 108033,
"Count": 20
},
"scoin": 1,
"buyLimit": 50000,
"beginTime": 1575129600,
"endTime": 2051193600,
"minLevel": 1,
"maxLevel": 99
}
]
}
]

153
data/ShopChest.json Normal file
View File

@ -0,0 +1,153 @@
[
{
"itemId": 115019,
"containsItem": [
{
"Id": 104002,
"Count": 40
},
{
"Id": 202,
"Count": 30000
}
]
},
{
"itemId": 115020,
"containsItem": [
{
"Id": 104013,
"Count": 25
},
{
"Id": 202,
"Count": 30000
}
]
},
{
"itemId": 115021,
"containsItem": [
{
"Id": 115013,
"Count": 5
},
{
"Id": 104003,
"Count": 40
},
{
"Id": 202,
"Count": 120000
}
]
},
{
"itemId": 115022,
"containsItem": [
{
"Id": 115017,
"Count": 25
},
{
"Id": 202,
"Count": 150000
}
]
},
{
"itemId": 115023,
"containsItem": [
{
"Id": 115025,
"Count": 10
},
{
"Id": 202,
"Count": 60000
}
]
},
{
"itemId": 115029,
"containsItem": [
{
"Id": 104013,
"Count": 100
},
{
"Id": 202,
"Count": 100000
}
]
},
{
"itemId": 115030,
"containsItem": [
{
"Id": 104003,
"Count": 12
},
{
"Id": 202,
"Count": 10000
}
]
},
{
"itemId": 115034,
"containsItem": [
{
"Id": 115013,
"Count": 6
},
{
"Id": 202,
"Count": 60000
}
]
},
{
"itemId": 115032,
"containsItem": [
{
"Id": 115024,
"Count": 12
}
]
},
{
"itemId": 115010,
"containsItem": [
{
"Id": 104002,
"Count": 80
},
{
"Id": 104012,
"Count": 40
}
]
},
{
"itemId": 115011,
"containsItem": [
{
"Id": 104003,
"Count": 50
},
{
"Id": 104013,
"Count": 25
},
{
"Id": 107009,
"Count": 1
},
{
"Id": 202,
"Count": 50000
}
]
}
]

View File

@ -0,0 +1,55 @@
[
{
"itemId": 115017,
"optionItem": [
104302,
104305,
104308,
104311,
104314,
104317,
104321,
104324,
104327
]
},
{
"itemId": 115024,
"optionItem": [
114001,
114005,
114009,
114013,
114017,
114021,
114025,
114029,
114033
]
},
{
"itemId": 115013,
"optionItem": [
104112,
104122,
104142,
104152,
104162,
104172
]
},
{
"itemId": 115025,
"optionItem": [
114002,
114006,
114010,
114014,
114018,
114022,
114026,
114030,
114034
]
}
]

1
data/Spawns.json Normal file

File diff suppressed because one or more lines are too long

227
data/gacha_records.html Normal file
View File

@ -0,0 +1,227 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400&display=swap">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
<style>
body {
background-color: #f0f0f0;
}
p {
font-weight:300;
}
a,a:hover {
text-decoration:none !important;
color:#626976;
}
.content {
padding:3rem 0;
}
.container {
color:#626976;
position: relative;
}
h2 {
font-size:20px;
}
.custom-table {
min-width:900px;
}
.custom-table thead tr,.custom-table thead th {
padding-bottom:30px;
color:#000;
}
.custom-table tbody th,.custom-table tbody td {
color:#777;
font-weight:400;
padding-bottom:20px;
padding-top:20px;
font-weight:300;
border:none;
}
.yellow {
color: rgb(255, 162, 0);
}
.blue {
color: rgb(75, 107, 251);
}
.purple {
color: rgb(242, 40, 242);
}
</style>
<title>Gacha Records</title>
<script>
// Debug entry
// record = [
// {"time": 10000341, "item": 1041},
// {"time": 10000342, "item": 1032},
// {"time": 10000343, "item": 1035},
// ];
// maxPage = 5;
// in production environment
record = {{REPLACE_RECORD}};
maxPage = {{REPLACE_MAXPAGE}};
// TODO: implement this mapper by yourself
// I don't want to put real items' name here to avoid being DMCA'd
mappings = {
'en-us': {
200: "Standard",
301: "Event Avatar",
302: "Event Weapon",
1041 : ["M0n4", "blue"],
1032 : ["B4nn477", "purple"],
1035 : ["77", "yellow"]
},
'zh-cn': {
// encoding issues here, maybe we should consider load mappings remotely
// will display as "锟斤铐锟斤铐锟斤铐", lmao
// 200: "常驻",
// 301: "角色UP-1",
// 302: "武器UP"
200: "Standard",
301: "Event Avatar",
302: "Event Weapon",
}
};
</script>
<!-- This file could be generated automatically using `java -jar grasscutter.jar -gachamap` -->
<!-- You can also modify the file manually to customize it -->
<!-- Otherwise you may onle see number IDs in the gacha record -->
<script type="text/javascript" src="/gacha/mappings"></script>
<script>
mappings['default'] = mappings['en-us']; // make en-us as default/fallback option
</script>
</head>
<body>
<div class="content">
<div class="container">
<h2 class="mb-5">Gacha Records</h2>
<table id="container" class="table table-striped custom-table">
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Item</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div class="navbar">
<a href="" id="prev">&lt;&lt;&lt;</a>
<span id="curpage">1</span>
<a href="" id="next">&gt;&gt;&gt;</a>
</div>
</div>
</div>
<footer>
<div class="copyright">
<div class="container">
<div class="row">
<div class="col-md-6">
<span>
Template by BecodReyes. All rights reserved.
</span>
</div>
<div class="col-md-6">
<ul style="float:right">
<li class="list-inline-item">
<a href="https://github.com/Grasscutters/Grasscutter">Github</a>
</li>
<li class="list-inline-item">·</li>
<li class="list-inline-item">
<a href="https://github.com/Grasscutters/Grasscutter/blob/stable/LICENSE">License</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</footer>
<script>
var lang = new window.URLSearchParams(window.location.search).get("lang");
function itemMapper(itemID) {
if (mappings[lang] != null && mappings[lang][itemID] != null) {
var entry = mappings[lang][itemID];
if (entry){
return "<span class='" + entry[1] + "'>" + entry[0] + "</span>";
}
} else {
if (mappings['default'][itemID] != null) {
var entry = mappings['default'][itemID];
if (entry){
return "<span class='" + entry[1] + "'>" + entry[0] + "</span>";
}
}
}
return "<span class='blue'>" + itemID + "</span>";
}
function dateFormatter(timeStamp) {
var date = new Date(timeStamp);
if (lang == "en-us" || lang == null) { // MM/DD/YYYY hh:mm:ss.SSS
return String(date.getMonth()+1).padStart(2, "0") +
"/"+String(date.getDate()).padStart(2, "0")+
"/"+date.getFullYear()+
" "+String(date.getHours()).padStart(2, "0")+
":"+String(date.getMinutes()).padStart(2, "0")+
":"+String(date.getSeconds()).padStart(2, "0")+
"."+String(date.getMilliseconds()).padStart(3, "0");
} else if (lang == "zh-cn") { // YYYY/MM/DD hh:mm:ss.SSS
return date.getFullYear()+
"/" + String(date.getMonth()+1).padStart(2, "0") +
"/"+String(date.getDate()).padStart(2, "0")+
" "+String(date.getHours()).padStart(2, "0")+
":"+String(date.getMinutes()).padStart(2, "0")+
":"+String(date.getSeconds()).padStart(2, "0")+
"."+String(date.getMilliseconds()).padStart(3, "0");
}
}
(function (){
var container = document.getElementById("container");
record.forEach(element => {
var e = document.createElement("tr");
e.innerHTML= "<td>" + dateFormatter(element.time) + "</td><td>" + itemMapper(element.item) + "</td>";
container.appendChild(e);
});
// setup pagenation buttons
var page = parseInt(new window.URLSearchParams(window.location.search).get("p"));
if (!page){
page = 0;
}
document.getElementById("curpage").innerText = page + 1;
var href = new URL(window.location);
href.searchParams.set("p", page - 1);
document.getElementById("prev").href = href.toString();
href.searchParams.set("p", page + 1);
document.getElementById("next").href = href.toString();
if (page <= 0) {
document.getElementById("prev").style.display = "none";
}
if (page >= maxPage - 1) {
document.getElementById("next").style.display = "none";
}
// setup gacha type info
var gachaType = new window.URLSearchParams(window.location.search).get("gachaType");
var gachaString;
if (mappings[lang] != null && mappings[lang][gachaType] != null) {
gachaString = mappings[lang][gachaType];
}else{
gachaString = mappings['default'][gachaType];
if (gachaString == null) {
gachaString = gachaType;
}
}
document.getElementById("gacha-type").innerText = gachaString;
})();
</script>
</body>
</html>

0
gradlew vendored Normal file → Executable file
View File

Binary file not shown.

BIN
lib/java-express.jar Normal file

Binary file not shown.

BIN
lib/kcp-netty-1.5.0.jar Normal file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,13 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityString.proto";
import "AbilityScalarValueEntry.proto";
message AbilityAppliedAbility {
AbilityString ability_name = 1;
AbilityString ability_override = 2;
repeated AbilityScalarValueEntry override_map = 3;
uint32 instanced_ability_id = 4;
}

View File

@ -0,0 +1,23 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityString.proto";
import "AbilityAttachedModifier.proto";
import "ModifierDurability.proto";
message AbilityAppliedModifier {
int32 modifier_local_id = 1;
uint32 parent_ability_entity_id = 2;
AbilityString parent_ability_name = 3;
AbilityString parent_ability_override = 4;
uint32 instanced_ability_id = 5;
uint32 instanced_modifier_id = 6;
float exist_duration = 7;
AbilityAttachedModifier attached_instanced_modifier = 8;
uint32 apply_entity_id = 9;
bool is_attached_parent_ability = 10;
ModifierDurability modifier_durability = 11;
uint32 sbuff_uid = 12;
bool is_serverbuff_modifier = 13;
}

View File

@ -0,0 +1,12 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AbilityAttachedModifier {
bool is_invalid = 1;
uint32 owner_entity_id = 2;
uint32 instanced_modifier_id = 3;
bool is_serverbuff_modifier = 4;
int32 attach_name_hash = 5;
}

18
proto/AbilityChangeNotify.proto Executable file
View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityControlBlock.proto";
message AbilityChangeNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1112;
}
uint32 entity_id = 1;
AbilityControlBlock ability_control_block = 2;
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityEmbryo.proto";
message AbilityControlBlock {
repeated AbilityEmbryo ability_embryo_list = 1;
}

10
proto/AbilityEmbryo.proto Executable file
View File

@ -0,0 +1,10 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AbilityEmbryo {
uint32 ability_id = 1;
fixed32 ability_name_hash = 2;
fixed32 ability_override_name_hash = 3;
}

View File

@ -0,0 +1,10 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AbilityGadgetInfo {
uint32 camp_id = 1;
uint32 camp_target_type = 2;
uint32 target_entity_id = 3;
}

13
proto/AbilityIdentifier.proto Executable file
View File

@ -0,0 +1,13 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AbilityIdentifier {
uint32 instanced_ability_id = 1;
uint32 ability_caster_id = 2;
int32 local_id = 3;
uint32 instanced_modifier_id = 4;
uint32 modifier_owner_id = 5;
bool is_serverbuff_modifier = 6;
}

View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityInvokeEntry.proto";
message AbilityInvocationsNotify {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1118;
}
repeated AbilityInvokeEntry invokes = 1;
}

View File

@ -0,0 +1,54 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
enum AbilityInvokeArgument {
ABILITY_NONE = 0;
ABILITY_META_MODIFIER_CHANGE = 1;
ABILITY_META_COMMAND_MODIFIER_CHANGE_REQUEST = 2;
ABILITY_META_SPECIAL_FLOAT_ARGUMENT = 3;
ABILITY_META_OVERRIDE_PARAM = 4;
ABILITY_META_CLEAR_OVERRIDE_PARAM = 5;
ABILITY_META_REINIT_OVERRIDEMAP = 6;
ABILITY_META_GLOBAL_FLOAT_VALUE = 7;
ABILITY_META_CLEAR_GLOBAL_FLOAT_VALUE = 8;
ABILITY_META_ABILITY_ELEMENT_STRENGTH = 9;
ABILITY_META_ADD_OR_GET_ABILITY_AND_TRIGGER = 10;
ABILITY_META_SET_KILLED_SETATE = 11;
ABILITY_META_SET_ABILITY_TRIGGER = 12;
ABILITY_META_ADD_NEW_ABILITY = 13;
ABILITY_META_REMOVE_ABILITY = 14;
ABILITY_META_SET_MODIFIER_APPLY_ENTITY = 15;
ABILITY_META_MODIFIER_DURABILITY_CHANGE = 16;
ABILITY_META_ELEMENT_REACTION_VISUAL = 17;
ABILITY_META_SET_POSE_PARAMETER = 18;
ABILITY_META_UPDATE_BASE_REACTION_DAMAGE = 19;
ABILITY_META_TRIGGER_ELEMENT_REACTION = 20;
ABILITY_META_LOSE_HP = 21;
ABILITY_ACTION_TRIGGER_ABILITY = 50;
ABILITY_ACTION_SET_CRASH_DAMAGE = 51;
ABILITY_ACTION_EFFECT = 52;
ABILITY_ACTION_SUMMON = 53;
ABILITY_ACTION_BLINK = 54;
ABILITY_ACTION_CREATE_GADGET = 55;
ABILITY_ACTION_APPLY_LEVEL_MODIFIER = 56;
ABILITY_ACTION_GENERATE_ELEM_BALL = 57;
ABILITY_ACTION_SET_RANDOM_OVERRIDE_MAP_VALUE = 58;
ABILITY_ACTION_SERVER_MONSTER_LOG = 59;
ABILITY_ACTION_CREATE_TILE = 60;
ABILITY_ACTION_DESTROY_TILE = 61;
ABILITY_ACTION_FIRE_AFTER_IMAGE = 62;
ABILITY_MIXIN_AVATAR_STEER_BY_CAMERA = 100;
ABILITY_MIXIN_MONSTER_DEFEND = 101;
ABILITY_MIXIN_WIND_ZONE = 102;
ABILITY_MIXIN_COST_STAMINA = 103;
ABILITY_MIXIN_ELITE_SHIELD = 104;
ABILITY_MIXIN_ELEMENT_SHIELD = 105;
ABILITY_MIXIN_GLOBAL_SHIELD = 106;
ABILITY_MIXIN_SHIELD_BAR = 107;
ABILITY_MIXIN_WIND_SEED_SPAWNER = 108;
ABILITY_MIXIN_DO_ACTION_BY_ELEMENT_REACTION = 109;
ABILITY_MIXIN_FIELD_ENTITY_COUNT_CHANGE = 110;
ABILITY_MIXIN_SCENE_PROP_SYNC = 111;
ABILITY_MIXIN_WIDGET_MP_SUPPORT = 112;
}

18
proto/AbilityInvokeEntry.proto Executable file
View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityInvokeEntryHead.proto";
import "AbilityInvokeArgument.proto";
import "ForwardType.proto";
message AbilityInvokeEntry {
AbilityInvokeEntryHead head = 1;
AbilityInvokeArgument argument_type = 2;
bytes ability_data = 3;
uint32 entity_id = 4;
ForwardType forward_type = 5;
uint32 forward_peer = 6;
uint32 event_id = 7;
double total_tick_time = 8;
}

View File

@ -0,0 +1,14 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AbilityInvokeEntryHead {
uint32 instanced_ability_id = 1;
uint32 instanced_modifier_id = 2;
int32 local_id = 3;
int32 modifier_config_local_id = 4;
uint32 target_id = 5;
bool is_serverbuff_modifier = 6;
uint32 server_buff_uid = 7;
}

View File

@ -0,0 +1,16 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "MassivePropSyncInfo.proto";
message AbilityMixinRecoverInfo {
oneof Source {
uint32 instanced_ability_id = 1;
uint32 instanced_modifier_id = 2;
}
uint32 local_id = 3;
repeated uint32 data_list = 4;
bool is_serverbuff_modifier = 5;
repeated MassivePropSyncInfo massive_prop_list = 6;
}

13
proto/AbilityScalarType.proto Executable file
View File

@ -0,0 +1,13 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
enum AbilityScalarType {
UNKNOW = 0;
FLOAT = 1;
INT = 2;
BOOL = 3;
TRIGGER = 4;
STRING = 5;
UINT = 6;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityString.proto";
import "AbilityScalarType.proto";
message AbilityScalarValueEntry {
oneof Value {
float float_value = 3;
string string_value = 4;
int32 int_value = 5;
uint32 uint_value = 6;
}
AbilityString key = 1;
AbilityScalarType value_type = 2;
}

11
proto/AbilityString.proto Executable file
View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AbilityString {
oneof Type {
string str = 1;
uint32 hash = 2;
}
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityScalarValueEntry.proto";
import "AbilityAppliedAbility.proto";
import "AbilityAppliedModifier.proto";
import "AbilityMixinRecoverInfo.proto";
message AbilitySyncStateInfo {
bool is_inited = 1;
repeated AbilityScalarValueEntry dynamic_value_map = 2;
repeated AbilityAppliedAbility applied_abilities = 3;
repeated AbilityAppliedModifier applied_modifiers = 4;
repeated AbilityMixinRecoverInfo mixin_recover_infos = 5;
repeated AbilityScalarValueEntry sgv_dynamic_value_map = 6;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AchievementInfo {
enum AchievementInfoStatus {
ACHIEVEMENT_INVALID = 0;
ACHIEVEMENT_UNFINISHED = 1;
ACHIEVEMENT_FINISHED = 2;
ACHIEVEMENT_POINT_TAKEN = 3;
}
uint32 id = 1;
AchievementInfoStatus status = 2;
uint32 current = 3;
uint32 goal = 4;
uint32 achievedate = 5;
}

211
proto/ActionReasonType.proto Executable file
View File

@ -0,0 +1,211 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
enum ActionReasonType {
ACTION_REASON_NONE = 0;
ACTION_REASON_QUEST_ITEM = 1;
ACTION_REASON_QUEST_REWARD = 2;
ACTION_REASON_TRIFLE = 3;
ACTION_REASON_SHOP = 4;
ACTION_REASON_PLAYER_UPGRADE_REWARD = 5;
ACTION_REASON_ADD_AVATAR = 6;
ACTION_REASON_GADGET_ENV_ANIMAL = 7;
ACTION_REASON_MONSTER_ENV_ANIMAL = 8;
ACTION_REASON_COMPOUND = 9;
ACTION_REASON_COOK = 10;
ACTION_REASON_GATHER = 11;
ACTION_REASON_MAIL_ATTACHMENT = 12;
ACTION_REASON_CITY_LEVELUP_RETURN = 15;
ACTION_REASON_CITY_LEVELUP_REWARD = 17;
ACTION_REASON_AREA_EXPLORE_REWARD = 18;
ACTION_REASON_UNLOCK_POINT_REWARD = 19;
ACTION_REASON_DUNGEON_FIRST_PASS = 20;
ACTION_REASON_DUNGEON_PASS = 21;
ACTION_REASON_CHANGE_ELEM_TYPE = 23;
ACTION_REASON_FETTER_OPEN = 25;
ACTION_REASON_DAILY_TASK_SCORE = 26;
ACTION_REASON_DAILY_TASK_HOST = 27;
ACTION_REASON_RAND_TASK_HOST = 28;
ACTION_REASON_EXPEDITION = 29;
ACTION_REASON_GACHA = 30;
ACTION_REASON_COMBINE = 31;
ACTION_REASON_RAND_TASK_GUEST = 32;
ACTION_REASON_DAILY_TASK_GUEST = 33;
ACTION_REASON_FORGE_OUTPUT = 34;
ACTION_REASON_FORGE_RETURN = 35;
ACTION_REASON_INIT_AVATAR = 36;
ACTION_REASON_MONSTER_DIE = 37;
ACTION_REASON_GM = 38;
ACTION_REASON_OPEN_CHEST = 39;
ACTION_REASON_GADGET_DIE = 40;
ACTION_REASON_MONSTER_CHANGE_HP = 41;
ACTION_REASON_SUBFIELD_DROP = 42;
ACTION_REASON_PUSH_TIPS_REWARD = 43;
ACTION_REASON_ACTIVITY_MONSTER_DROP = 44;
ACTION_REASON_ACTIVITY_GATHER = 45;
ACTION_REASON_ACTIVITY_SUBFIELD_DROP = 46;
ACTION_REASON_TOWER_SCHEDULE_REWARD = 47;
ACTION_REASON_TOWER_FLOOR_STAR_REWARD = 48;
ACTION_REASON_TOWER_FIRST_PASS_REWARD = 49;
ACTION_REASON_TOWER_DAILY_REWARD = 50;
ACTION_REASON_HIT_CLIENT_TRIVIAL_ENTITY = 51;
ACTION_REASON_OPEN_WORLD_BOSS_CHEST = 52;
ACTION_REASON_MATERIAL_DELETE_RETURN = 53;
ACTION_REASON_SIGN_IN_REWARD = 54;
ACTION_REASON_OPEN_BLOSSOM_CHEST = 55;
ACTION_REASON_RECHARGE = 56;
ACTION_REASON_BONUS_ACTIVITY_REWARD = 57;
ACTION_REASON_TOWER_COMMEMORATIVE_REWARD = 58;
ACTION_REASON_TOWER_SKIP_FLOOR_REWARD = 59;
ACTION_REASON_RECHARGE_BONUS = 60;
ACTION_REASON_RECHARGE_CARD = 61;
ACTION_REASON_RECHARGE_CARD_DAILY = 62;
ACTION_REASON_RECHARGE_CARD_REPLACE = 63;
ACTION_REASON_RECHARGE_CARD_REPLACE_FREE = 64;
ACTION_REASON_RECHARGE_PLAY_REPLACE = 65;
ACTION_REASON_MP_PLAY_TAKE_REWARD = 66;
ACTION_REASON_ACTIVITY_WATCHER = 67;
ACTION_REASON_SALESMAN_DELIVER_ITEM = 68;
ACTION_REASON_SALESMAN_REWARD = 69;
ACTION_REASON_REBATE = 70;
ACTION_REASON_MCOIN_EXCHANGE_HCOIN = 71;
ACTION_REASON_DAILY_TASK_EXCHANGE_LEGENDARY_KEY = 72;
ACTION_REASON_UNLOCK_PERSON_LINE = 73;
ACTION_REASON_FETTER_LEVEL_REWARD = 74;
ACTION_REASON_BUY_RESIN = 75;
ACTION_REASON_RECHARGE_PACKAGE = 76;
ACTION_REASON_DELIVERY_DAILY_REWARD = 77;
ACTION_REASON_CITY_REPUTATION_LEVEL = 78;
ACTION_REASON_CITY_REPUTATION_QUEST = 79;
ACTION_REASON_CITY_REPUTATION_REQUEST = 80;
ACTION_REASON_CITY_REPUTATION_EXPLORE = 81;
ACTION_REASON_OFFERGING_LEVEL = 82;
ACTION_REASON_ROUTINE_HOST = 83;
ACTION_REASON_ROUTINE_GUEST = 84;
ACTION_REASON_TREASURE_MAP_SPOT_TOKEN = 89;
ACTION_REASON_TREASURE_MAP_BONUS_LEVEL_REWARD = 90;
ACTION_REASON_TREASURE_MAP_MP_REWARD = 91;
ACTION_REASON_CONVERT = 92;
ACTION_REASON_OVERFLOW_TRANSFORM = 93;
ACTION_REASON_ACTIVITY_AVATAR_SELECTION_REWARD = 96;
ACTION_REASON_ACTIVITY_WATCHER_BATCH = 97;
ACTION_REASON_HIT_TREE_DROP = 98;
ACTION_REASON_GET_HOME_LEVELUP_REWARD = 99;
ACTION_REASON_HOME_DEFAULT_FURNITURE = 100;
ACTION_REASON_ACTIVITY_COND = 101;
ACTION_REASON_BATTLE_PASS_NOTIFY = 102;
ACTION_REASON_RELIQUARY_DECOMPOSE = 103;
ACTION_REASON_RECHARGE_GOOGLE_GIFT_GARD = 104;
ACTION_REASON_RECHARGE_CONCERT_PRODUCT = 105;
ACTION_REASON_RECHARGE_CONCERT_PRODUCT_REPLACE = 106;
ACTION_REASON_SEND_CONCERT_PRODUCT_BY_MUIP = 107;
ACTION_REASON_RECHARGE_APPLE_GIFT_GARD = 108;
ACTION_REASON_PLAYER_USE_ITEM = 1001;
ACTION_REASON_DROP_ITEM = 1002;
ACTION_REASON_WEAPON_UPGRADE = 1011;
ACTION_REASON_WEAPON_PROMOTE = 1012;
ACTION_REASON_WEAPON_AWAKEN = 1013;
ACTION_REASON_RELIC_UPGRADE = 1014;
ACTION_REASON_ABILITY = 1015;
ACTION_REASON_DUNGEON_STATUE_DROP = 1016;
ACTION_REASON_OFFLINE_MSG = 1017;
ACTION_REASON_AVATAR_UPGRADE = 1018;
ACTION_REASON_AVATAR_PROMOTE = 1019;
ACTION_REASON_QUEST_ACTION = 1021;
ACTION_REASON_CITY_LEVELUP = 1022;
ACTION_REASON_UPGRADE_SKILL = 1024;
ACTION_REASON_UNLOCK_TALENT = 1025;
ACTION_REASON_UPGRADE_PROUD_SKILL = 1026;
ACTION_REASON_PLAYER_LEVEL_LIMIT_UP = 1027;
ACTION_REASON_DUNGEON_DAILY = 1028;
ACTION_REASON_ITEM_GIVING = 1030;
ACTION_REASON_FORGE_COST = 1031;
ACTION_REASON_INVESTIGATION_REWARD = 1032;
ACTION_REASON_INVESTIGATION_TARGET_REWARD = 1033;
ACTION_REASON_GADGET_INTERACT = 1034;
ACTION_REASON_SEA_LAMP_CI_MATERIAL = 1036;
ACTION_REASON_SEA_LAMP_CONTRIBUTION_REWARD = 1037;
ACTION_REASON_SEA_LAMP_PHASE_REWARD = 1038;
ACTION_REASON_SEA_LAMP_FLY_LAMP = 1039;
ACTION_REASON_AUTO_RECOVER = 1040;
ACTION_REASON_ACTIVITY_EXPIRE_ITEM = 1041;
ACTION_REASON_SUB_COIN_NEGATIVE = 1042;
ACTION_REASON_BARGAIN_DEDUCT = 1043;
ACTION_REASON_BATTLE_PASS_PAID_REWARD = 1044;
ACTION_REASON_BATTLE_PASS_LEVEL_REWARD = 1045;
ACTION_REASON_TRIAL_AVATAR_ACTIVITY_FIRST_PASS_REWARD = 1046;
ACTION_REASON_BUY_BATTLE_PASS_LEVEL = 1047;
ACTION_REASON_GRANT_BIRTHDAY_BENEFIT = 1048;
ACTION_REASON_ACHIEVEMENT_REWARD = 1049;
ACTION_REASON_ACHIEVEMENT_GOAL_REWARD = 1050;
ACTION_REASON_FIRST_SHARE_TO_SOCIAL_NETWORK = 1051;
ACTION_REASON_DESTROY_MATERIAL = 1052;
ACTION_REASON_CODEX_LEVELUP_REWARD = 1053;
ACTION_REASON_HUNTING_OFFER_REWARD = 1054;
ACTION_REASON_USE_WIDGET_ANCHOR_POINT = 1055;
ACTION_REASON_USE_WIDGET_BONFIRE = 1056;
ACTION_REASON_UNGRADE_WEAPON_RETURN_MATERIAL = 1057;
ACTION_REASON_USE_WIDGET_ONEOFF_GATHER_POINT_DETECTOR = 1058;
ACTION_REASON_USE_WIDGET_CLIENT_COLLECTOR = 1059;
ACTION_REASON_USE_WIDGET_CLIENT_DETECTOR = 1060;
ACTION_REASON_TAKE_GENERAL_REWARD = 1061;
ACTION_REASON_ASTER_TAKE_SPECIAL_REWARD = 1062;
ACTION_REASON_REMOVE_CODEX_BOOK = 1063;
ACTION_REASON_OFFERING_ITEM = 1064;
ACTION_REASON_USE_WIDGET_GADGET_BUILDER = 1065;
ACTION_REASON_EFFIGY_FIRST_PASS_REWARD = 1066;
ACTION_REASON_EFFIGY_REWARD = 1067;
ACTION_REASON_REUNION_FIRST_GIFT_REWARD = 1068;
ACTION_REASON_REUNION_SIGN_IN_REWARD = 1069;
ACTION_REASON_REUNION_WATCHER_REWARD = 1070;
ACTION_REASON_SALESMAN_MP_REWARD = 1071;
ACTION_REASION_AVATAR_PROMOTE_REWARD = 1072;
ACTION_REASON_BLESSING_REDEEM_REWARD = 1073;
ACTION_MIRACLE_RING_REWARD = 1074;
ACTION_REASON_EXPEDITION_REWARD = 1075;
ACTION_REASON_TREASURE_MAP_REMOVE_DETECTOR = 1076;
ACTION_REASON_MECHANICUS_DUNGEON_TICKET = 1077;
ACTION_REASON_MECHANICUS_LEVELUP_GEAR = 1078;
ACTION_REASON_MECHANICUS_BATTLE_SETTLE = 1079;
ACTION_REASON_REGION_SEARCH_REWARD = 1080;
ACTION_REASON_UNLOCK_COOP_CHAPTER = 1081;
ACTION_REASON_TAKE_COOP_REWARD = 1082;
ACTION_REASON_FLEUR_FAIR_DUNGEON_REWARD = 1083;
ACTION_REASON_ACTIVITY_SCORE = 1084;
ACTION_REASON_CHANNELLER_SLAB_ONEOFF_DUNGEON_REWARD = 1085;
ACTION_REASON_FURNITURE_MAKE_START = 1086;
ACTION_REASON_FURNITURE_MAKE_TAKE = 1087;
ACTION_REASON_FURNITURE_MAKE_CANCEL = 1088;
ACTION_REASON_FURNITURE_MAKE_FAST_FINISH = 1089;
ACTION_REASON_CHANNELLER_SLAB_LOOP_DUNGEON_FIRST_PASS_REWARD = 1090;
ACTION_REASON_CHANNELLER_SLAB_LOOP_DUNGEON_SCORE_REWARD = 1091;
ACTION_REASON_HOME_LIMITED_SHOP_BUY = 1092;
ACTION_REASON_HOME_COIN_COLLECT = 1093;
ACTION_REASON_SUMMER_TIME_SENTRY_TOWER_REWARD = 1094;
ACTION_REASON_SUMMER_TIME_SPRINT_BOAT_REWARD = 1095;
ACTION_REASON_SUMMER_TIME_BOSS_REWARD = 1096;
ACTION_REASON_SUMMER_TIME_BOMB_REWARD = 1097;
ACTION_REASON_HOME_FETTER_COLLECT = 1098;
ACTION_REASON_ECHO_SHELL_REWARD = 1099;
ACTION_REASON_HOME_EVENT_REWARD = 1100;
ACTION_REASON_BLITZ_RUSH_DUNGEON_REWARD = 1101;
ACTION_REASON_FURNITURE_MAKE_RETURN = 1102;
ACTION_REASON_HOME_PLANT_BOX_GATHER = 1103;
ACTION_REASON_HOME_PLANT_SEED = 1104;
ACTION_REASON_HOME_PLANT_GATHER = 1105;
ACTION_REASON_CHESS_DUNGEON_REWARD = 1106;
ACTION_REASON_GROUP_LINK_BUNDLE_FINISH = 1107;
ACTION_REASON_LUNA_RITE_SACRIFICE = 1108;
ACTION_REASON_LUNA_RITE_TAKE_SACRIFICE_REWARD = 1109;
ACTION_REASON_FISH_BITE = 1110;
ACTION_REASON_FISH_SUCC = 1111;
ACTION_REASON_PLANT_FLOWER_REWARD = 1112;
ACTION_REASON_PLANT_FLOWER_DELIVER_ITEM = 1113;
ACTION_REASON_PLANT_FLOWER_GIVE_FLOWER = 1114;
ACTION_REASON_PLANT_FLOWER_RECV_FLOWER = 1115;
ACTION_REASON_ROGUE_CHALLENGE_SETTLE = 1116;
ACTION_REASON_ROGUE_TAKE_FIRST_PASS_REWARD = 1117;
ACTION_REASON_ROGUE_UPGRADE_SHIKIGAMI = 1118;
ACTION_REASON_ROGUE_REFRESH_CARD = 1119;
}

62
proto/ActivityInfo.proto Executable file
View File

@ -0,0 +1,62 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "ActivityNullDetailInfo.proto";
import "ActivityWatcherInfo.proto";
message ActivityInfo {
oneof Detail {
ActivityNullDetailInfo sam_lamp_info = 11;
ActivityNullDetailInfo crucible_info = 12;
ActivityNullDetailInfo salesman_info = 13;
ActivityNullDetailInfo trial_avatar_info = 14;
ActivityNullDetailInfo delivery_info = 16;
ActivityNullDetailInfo aster_info = 21;
ActivityNullDetailInfo flight_info = 25;
ActivityNullDetailInfo dragon_spine_info = 31;
ActivityNullDetailInfo effigy_info = 32;
ActivityNullDetailInfo treasure_map_info = 35;
ActivityNullDetailInfo blessing_info = 41;
ActivityNullDetailInfo sea_lamp_info = 42;
ActivityNullDetailInfo expedition_info = 43;
ActivityNullDetailInfo arena_challenge_info = 44;
ActivityNullDetailInfo fleur_fair_info = 51;
ActivityNullDetailInfo water_spirit_info = 52;
ActivityNullDetailInfo challneler_slab_info = 61;
ActivityNullDetailInfo mist_trial_activity_info = 62;
ActivityNullDetailInfo hide_and_seek_info = 63;
ActivityNullDetailInfo find_hilichurl_info = 64;
ActivityNullDetailInfo summer_time_info = 65;
ActivityNullDetailInfo buoyant_combat_info = 66;
ActivityNullDetailInfo echo_shell_info = 67;
ActivityNullDetailInfo bounce_conjuring_info = 68;
ActivityNullDetailInfo blitz_rush_info = 69;
ActivityNullDetailInfo chess_info = 70;
ActivityNullDetailInfo sumo_info = 71;
ActivityNullDetailInfo moonfin_trial_info = 72;
ActivityNullDetailInfo luna_rite_info = 73;
ActivityNullDetailInfo plant_flower_info = 74;
ActivityNullDetailInfo music_game_info = 75;
ActivityNullDetailInfo roguelike_dungoen_info = 76;
ActivityNullDetailInfo dig_info = 77;
}
uint32 activity_id = 1;
uint32 schedule_id = 2;
uint32 begin_time = 3;
uint32 end_time = 4;
uint32 activity_type = 5;
bool is_play_open_anim = 6;
bool is_finished = 7;
bool is_starting = 8;
repeated ActivityWatcherInfo watcher_info_list = 9;
repeated uint32 meet_cond_list = 10;
repeated uint32 expire_cond_list = 15;
uint32 selected_avatar_reward_id = 17;
map<uint32, uint32> activity_coin_map = 18;
uint32 score_limit = 19;
uint32 cur_score = 20;
repeated uint32 taken_reward_list = 24;
bool is_hidden = 26;
uint32 first_day_start_time = 27;
}

View File

@ -0,0 +1,7 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message ActivityNullDetailInfo {
}

11
proto/ActivityWatcherInfo.proto Executable file
View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message ActivityWatcherInfo {
uint32 watcher_id = 1;
uint32 cur_progress = 2;
uint32 total_progress = 3;
bool is_taken_reward = 4;
}

View File

@ -0,0 +1,12 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AdjustTrackingInfo {
string idfa = 1;
string gps_adid = 2;
string fire_adid = 3;
string adid = 4;
string event_token = 5;
string app_token = 6;
}

9
proto/AiSkillCdInfo.proto Executable file
View File

@ -0,0 +1,9 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AiSkillCdInfo {
map<uint32, uint32> skill_cd_map = 1;
map<uint32, uint32> skill_group_cd_map = 2;
}

10
proto/AiSyncInfo.proto Executable file
View File

@ -0,0 +1,10 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AiSyncInfo {
uint32 entity_id = 1;
bool has_path_to_target = 2;
bool is_self_killing = 3;
}

8
proto/AiThreatInfo.proto Executable file
View File

@ -0,0 +1,8 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AiThreatInfo {
map<uint32, uint32> ai_threat_map = 1;
}

View File

@ -0,0 +1,13 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AnimatorParameterValueInfo {
oneof ParaVal {
int32 int_val = 2;
float float_val = 3;
bool bool_val = 4;
}
uint32 para_type = 1;
}

View File

@ -0,0 +1,10 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AnimatorParameterValueInfo.proto";
message AnimatorParameterValueInfoPair {
int32 name_id = 1;
AnimatorParameterValueInfo animator_para = 2;
}

18
proto/AskAddFriendNotify.proto Executable file
View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "FriendBrief.proto";
message AskAddFriendNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 4006;
}
uint32 target_uid = 1;
FriendBrief target_friend_brief = 2;
}

17
proto/AskAddFriendReq.proto Executable file
View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AskAddFriendReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 4100;
}
uint32 target_uid = 1;
}

19
proto/AskAddFriendRsp.proto Executable file
View File

@ -0,0 +1,19 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AskAddFriendRsp {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 4001;
}
int32 retcode = 1;
uint32 target_uid = 2;
uint32 param = 3;
}

View File

@ -0,0 +1,13 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AttackHitEffectResult {
uint32 hit_eff_level = 1;
float retreat_strength = 2;
float air_strength = 3;
float hit_halt_time = 4;
float hit_halt_time_scale = 5;
uint32 original_hit_eff_level = 6;
}

40
proto/AttackResult.proto Executable file
View File

@ -0,0 +1,40 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilityIdentifier.proto";
import "HitCollision.proto";
import "Vector.proto";
import "AttackHitEffectResult.proto";
message AttackResult {
uint32 attacker_id = 1;
uint32 defense_id = 2;
string anim_event_id = 3;
AbilityIdentifier ability_identifier = 4;
float damage = 6;
bool is_crit = 7;
HitCollision hit_collision = 8;
uint32 hit_pos_type = 9;
uint32 endure_break = 10;
Vector resolved_dir = 11;
int32 hit_retreat_angle_compat = 12;
AttackHitEffectResult hit_eff_result = 13;
uint32 element_type = 14;
bool use_gadget_damage_action = 19;
uint32 gadget_damage_action_idx = 20;
bool is_resist_text = 22;
uint32 critical_rand = 23;
float element_amplify_rate = 24;
float damage_shield = 26;
bool mute_element_hurt = 27;
uint32 amplify_reaction_type = 30;
uint32 addhurt_reaction_type = 31;
uint32 bullet_fly_time_ms = 32;
uint32 attack_count = 33;
uint32 hashed_anim_event_id = 34;
uint32 attack_timestamp_ms = 36;
float endure_delta = 37;
uint32 target_type = 38;
float element_durability_attenuation = 39;
}

18
proto/AvatarAddNotify.proto Executable file
View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarInfo.proto";
message AvatarAddNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1795;
}
AvatarInfo avatar = 1;
bool is_in_team = 2;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "SceneEntityInfo.proto";
message AvatarChangeCostumeNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1724;
}
SceneEntityInfo entity_info = 1;
}

View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarChangeCostumeReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1606;
}
uint64 avatar_guid = 1;
uint32 costume_id = 2;
}

View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarChangeCostumeRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1748;
}
int32 retcode = 1;
uint64 avatar_guid = 2;
uint32 costume_id = 3;
}

24
proto/AvatarDataNotify.proto Executable file
View File

@ -0,0 +1,24 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarInfo.proto";
import "AvatarTeam.proto";
message AvatarDataNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1694;
}
repeated AvatarInfo avatar_list = 1;
map<uint32, AvatarTeam> avatar_team_map = 2;
uint32 cur_avatar_team_id = 3;
fixed64 choose_avatar_guid = 4;
repeated uint64 temp_avatar_guid_list = 5;
repeated uint32 owned_flycloak_list = 6;
repeated uint32 owned_costume_list = 7;
}

View File

@ -0,0 +1,20 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "Vector.proto";
message AvatarDieAnimationEndReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1737;
}
uint64 die_guid = 1;
uint32 skill_id = 2;
Vector reborn_pos = 3;
}

View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarDieAnimationEndRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1697;
}
int32 retcode = 1;
uint64 die_guid = 2;
uint32 skill_id = 3;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AbilitySyncStateInfo.proto";
import "ServerBuff.proto";
message AvatarEnterSceneInfo {
uint64 avatar_guid = 1;
uint32 avatar_entity_id = 2;
AbilitySyncStateInfo avatar_ability_info = 3;
repeated uint32 buff_id_list = 4;
uint64 weapon_guid = 5;
uint32 weapon_entity_id = 6;
AbilitySyncStateInfo weapon_ability_info = 7;
repeated ServerBuff server_buff_list = 8;
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarEquipAffixInfo {
uint32 equip_affix_id = 1;
uint32 left_cd_time = 2;
}

View File

@ -0,0 +1,24 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "SceneWeaponInfo.proto";
import "SceneReliquaryInfo.proto";
message AvatarEquipChangeNotify {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 615;
}
uint64 avatar_guid = 1;
uint32 equip_type = 2;
uint32 item_id = 3;
uint64 equip_guid = 4;
SceneWeaponInfo weapon = 5;
SceneReliquaryInfo reliquary = 6;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarExcelInfo {
uint64 prefab_path_hash = 1;
uint64 prefab_path_remote_hash = 2;
uint64 controller_path_hash = 3;
uint64 controller_path_remote_hash = 4;
uint64 combat_config_hash = 5;
}

View File

@ -0,0 +1,19 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarExpeditionInfo.proto";
message AvatarExpeditionAllDataRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1783;
}
int32 retcode = 1;
map<uint64, AvatarExpeditionInfo> expedition_info_map = 2;
repeated uint32 open_expedition_list = 3;
uint32 expedition_count_limit = 4;
}

View File

@ -0,0 +1,16 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarExpeditionCallBackReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1618;
}
repeated uint64 avatar_guid = 1;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarExpeditionInfo.proto";
message AvatarExpeditionCallBackRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1633;
}
int32 retcode = 1;
map<uint64, AvatarExpeditionInfo> expedition_info_map = 2;
}

View File

@ -0,0 +1,16 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarExpeditionInfo.proto";
message AvatarExpeditionDataNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1621;
}
map<uint64, AvatarExpeditionInfo> expedition_info_map = 1;
}

View File

@ -0,0 +1,16 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarExpeditionGetRewardReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1610;
}
uint64 avatar_guid = 1;
}

View File

@ -0,0 +1,19 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarExpeditionInfo.proto";
import "ItemParam.proto";
message AvatarExpeditionGetRewardRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1670;
}
int32 retcode = 1;
map<uint64, AvatarExpeditionInfo> expedition_info_map = 2;
repeated ItemParam item_list = 3;
}

View File

@ -0,0 +1,12 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarExpeditionState.proto";
message AvatarExpeditionInfo {
AvatarExpeditionState state = 1;
uint32 exp_id = 2;
uint32 hour_time = 3;
uint32 start_time = 4;
float shorten_ratio = 5;
}

View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarExpeditionStartReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1609;
}
uint64 avatar_guid = 1;
uint32 exp_id = 2;
uint32 hour_time = 3;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarExpeditionInfo.proto";
message AvatarExpeditionStartRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1646;
}
int32 retcode = 1;
map<uint64, AvatarExpeditionInfo> expedition_info_map = 2;
}

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
enum AvatarExpeditionState {
AVATAR_EXPEDITION_NONE = 0;
AVATAR_EXPEDITION_DOING = 1;
AVATAR_EXPEDITION_FINISH_WAIT_REWARD = 2;
AVATAR_EXPEDITION_CALLBACK_WAIT_REWARD = 3;
AVATAR_EXPEDITION_LOCKED = 4;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarFetterInfo.proto";
message AvatarFetterDataNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1685;
}
map<uint64, AvatarFetterInfo> fetter_info_map = 1;
}

14
proto/AvatarFetterInfo.proto Executable file
View File

@ -0,0 +1,14 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "FetterData.proto";
message AvatarFetterInfo {
uint32 exp_number = 1;
uint32 exp_level = 2;
repeated uint32 open_id_list = 3;
repeated uint32 finish_id_list = 4;
repeated uint32 rewarded_fetter_level_list = 5;
repeated FetterData fetter_list = 6;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarFetterLevelRewardReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1624;
}
uint64 avatar_guid = 1;
uint32 fetter_level = 2;
}

View File

@ -0,0 +1,18 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarFetterLevelRewardRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1704;
}
int32 retcode = 1;
uint64 avatar_guid = 2;
uint32 fetter_level = 3;
uint32 reward_id = 4;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarFightPropNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1300;
}
uint64 avatar_guid = 1;
map<uint32, float> fight_prop_map = 2;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarFightPropUpdateNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1201;
}
uint64 avatar_guid = 1;
map<uint32, float> fight_prop_map = 2;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarFlycloakChangeNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1759;
}
uint64 avatar_guid = 1;
uint32 flycloak_id = 2;
}

View File

@ -0,0 +1,16 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarGainCostumeNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1734;
}
uint32 costume_id = 1;
}

View File

@ -0,0 +1,16 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarGainFlycloakNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1604;
}
uint32 flycloak_id = 1;
}

40
proto/AvatarInfo.proto Executable file
View File

@ -0,0 +1,40 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "TrialAvatarInfo.proto";
import "AvatarFetterInfo.proto";
import "AvatarExpeditionState.proto";
import "AvatarExcelInfo.proto";
import "PropValue.proto";
import "AvatarSkillInfo.proto";
import "AvatarEquipAffixInfo.proto";
message AvatarInfo {
uint32 avatar_id = 1;
uint64 guid = 2;
map<uint32, PropValue> prop_map = 3;
uint32 life_state = 4;
repeated uint64 equip_guid_list = 5;
repeated uint32 talent_id_list = 6;
map<uint32, float> fight_prop_map = 7;
TrialAvatarInfo trial_avatar_info = 9;
map<uint32, AvatarSkillInfo> skill_map = 10;
uint32 skill_depot_id = 11;
AvatarFetterInfo fetter_info = 12;
uint32 core_proud_skill_level = 13;
repeated uint32 inherent_proud_skill_list = 14;
map<uint32, uint32> skill_level_map = 15;
AvatarExpeditionState expedition_state = 16;
map<uint32, uint32> proud_skill_extra_level_map = 17;
bool is_focus = 18;
uint32 avatar_type = 19;
repeated uint32 team_resonance_list = 20;
uint32 wearing_flycloak_id = 21;
repeated AvatarEquipAffixInfo equip_affix_list = 22;
uint32 born_time = 23;
repeated uint32 pending_promote_reward_list = 24;
uint32 costume_id = 25;
AvatarExcelInfo excel_info = 26;
uint32 anim_hash = 27;
}

View File

@ -0,0 +1,24 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "PlayerDieType.proto";
import "ServerBuff.proto";
message AvatarLifeStateChangeNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1242;
}
uint64 avatar_guid = 1;
uint32 life_state = 2;
uint32 source_entity_id = 3;
string attack_tag = 4;
PlayerDieType die_type = 5;
uint32 move_reliable_seq = 6;
repeated ServerBuff server_buff_list = 7;
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarPromoteGetRewardReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1701;
}
uint64 avatar_guid = 1;
uint32 promote_level = 2;
}

View File

@ -0,0 +1,19 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarPromoteGetRewardRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1764;
}
int32 retcode = 1;
uint64 avatar_guid = 2;
uint32 promote_level = 3;
uint32 reward_id = 4;
}

17
proto/AvatarPromoteReq.proto Executable file
View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarPromoteReq {
enum CmdId {
option allow_alias = true;
ENET_CHANNEL_ID = 0;
NONE = 0;
ENET_IS_RELIABLE = 1;
IS_ALLOW_CLIENT = 1;
CMD_ID = 1692;
}
uint64 guid = 1;
}

17
proto/AvatarPromoteRsp.proto Executable file
View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarPromoteRsp {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1728;
}
int32 retcode = 1;
uint64 guid = 2;
}

17
proto/AvatarPropNotify.proto Executable file
View File

@ -0,0 +1,17 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarPropNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1212;
}
uint64 avatar_guid = 1;
map<uint32, int64> prop_map = 2;
}

View File

@ -0,0 +1,21 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarSkillChangeNotify {
enum CmdId {
option allow_alias = true;
NONE = 0;
ENET_CHANNEL_ID = 0;
ENET_IS_RELIABLE = 1;
CMD_ID = 1091;
}
uint64 avatar_guid = 1;
uint32 entity_id = 2;
uint32 skill_depot_id = 3;
uint32 avatar_skill_id = 4;
uint32 old_level = 5;
uint32 cur_level = 6;
}

10
proto/AvatarSkillInfo.proto Executable file
View File

@ -0,0 +1,10 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarSkillInfo {
uint32 pass_cd_time = 1;
repeated uint32 full_cd_time_list = 2;
uint32 max_charge_count = 3;
}

View File

@ -0,0 +1,10 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
import "AvatarSkillInfo.proto";
message AvatarSkillInfoNotify {
uint64 guid = 1;
map<uint32, AvatarSkillInfo> skill_map = 2;
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
option java_package = "emu.grasscutter.net.proto";
message AvatarSkillMaxChargeCountNotify {
uint64 avatar_guid = 1;
uint32 skill_id = 2;
uint32 max_charge_count = 3;
}

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