62 Commits

Author SHA1 Message Date
cd48328f59 Merge pull request #4 from brenoepics/dependabot/gradle/org.junit.jupiter-junit-jupiter-engine-5.10.2
chore(deps): bump org.junit.jupiter:junit-jupiter-engine from 5.8.2 to 5.10.2
2024-06-09 13:22:16 -03:00
a05d6cdc2f Merge pull request #3 from brenoepics/dependabot/gradle/org.jline-jline-terminal-jna-3.26.1
chore(deps): bump org.jline:jline-terminal-jna from 3.21.0 to 3.26.1
2024-06-09 13:22:06 -03:00
22c7f3c45f Merge pull request #2 from brenoepics/dependabot/gradle/com.fasterxml.jackson-jackson-bom-2.17.1
chore(deps): bump com.fasterxml.jackson:jackson-bom from 2.14.0 to 2.17.1
2024-06-09 13:21:53 -03:00
fa283d8d17 Merge pull request #1 from brenoepics/dependabot/gradle/com.google.protobuf-protoc-4.27.1
chore(deps): bump com.google.protobuf:protoc from 3.18.1 to 4.27.1
2024-06-09 13:21:38 -03:00
0736956317 Format code [skip actions] 2024-06-09 16:08:43 +00:00
75d8ed0777 Merge branch 'development' of https://github.com/brenoepics/Grasscutter into development 2024-06-09 13:07:04 -03:00
63fbe66158 security: add secure mode and padding scheme 2024-06-09 13:06:59 -03:00
ff2aeac9a5 chore(deps): bump org.junit.jupiter:junit-jupiter-engine
Bumps [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) from 5.8.2 to 5.10.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.8.2...r5.10.2)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter-engine
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-09 15:27:08 +00:00
bbec09d444 chore(deps): bump org.jline:jline-terminal-jna from 3.21.0 to 3.26.1
Bumps [org.jline:jline-terminal-jna](https://github.com/jline/jline3) from 3.21.0 to 3.26.1.
- [Release notes](https://github.com/jline/jline3/releases)
- [Changelog](https://github.com/jline/jline3/blob/master/changelog.md)
- [Commits](https://github.com/jline/jline3/compare/jline-parent-3.21.0...jline-parent-3.26.1)

---
updated-dependencies:
- dependency-name: org.jline:jline-terminal-jna
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-09 15:27:04 +00:00
52b7ca6b09 chore(deps): bump com.fasterxml.jackson:jackson-bom
Bumps [com.fasterxml.jackson:jackson-bom](https://github.com/FasterXML/jackson-bom) from 2.14.0 to 2.17.1.
- [Commits](https://github.com/FasterXML/jackson-bom/compare/jackson-bom-2.14.0...jackson-bom-2.17.1)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson:jackson-bom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-09 15:27:00 +00:00
62d53f37ea chore(deps): bump com.google.protobuf:protoc from 3.18.1 to 4.27.1
Bumps [com.google.protobuf:protoc](https://github.com/protocolbuffers/protobuf) from 3.18.1 to 4.27.1.
- [Release notes](https://github.com/protocolbuffers/protobuf/releases)
- [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl)
- [Commits](https://github.com/protocolbuffers/protobuf/commits)

---
updated-dependencies:
- dependency-name: com.google.protobuf:protoc
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-09 15:26:57 +00:00
1234d184c8 ci: Create dependabot.yml 2024-06-09 12:26:04 -03:00
c313939ec0 Merge branch 'development' of https://github.com/brenoepics/Grasscutter into development 2024-06-09 12:23:05 -03:00
dbb4f857ef ci: bump actions 2024-06-09 12:22:37 -03:00
2bb2da44bc Format code [skip actions] 2024-06-09 15:12:09 +00:00
bfc2c7c096 refactor: fix lombok 2024-06-09 12:09:50 -03:00
8c53f2b679 Format code [skip actions] 2024-06-09 13:49:49 +00:00
d4ce7aac08 refactor: fix nullable params 2024-06-09 10:26:58 -03:00
3b68645330 refactor: number comparison 2024-06-09 10:09:59 -03:00
db280387ba chore: fix codestyle indentation 2024-06-09 10:06:57 -03:00
809009f96c refactor: null check is not necessary, we have instanceof 2024-06-09 10:02:56 -03:00
45bf5edb13 perf: stream api can be simplified here 2024-06-09 10:01:03 -03:00
3d00abcc91 perf: we can just equalsIgnoreCase 2024-06-09 10:00:07 -03:00
85ca8777c9 perf: remove redundant collection operation 2024-06-09 09:59:16 -03:00
8f8a6a7bfe perf: simplify optional chain 2024-06-09 09:58:25 -03:00
f01da54eaa perf: size cannot be negative 2024-06-09 09:57:41 -03:00
4b03304cdc perf: this is just Math.min 2024-06-09 09:56:58 -03:00
dd9f59fbfc refactor(lombok): add Setter where possible 2024-06-09 09:55:51 -03:00
8f4120fcd3 refactor(lombok): add Getter where possible 2024-06-09 09:52:49 -03:00
7ee644c794 perf: add Serial annotation here 2024-06-09 09:46:29 -03:00
aeadf6bba7 perf: equals "" can be isEmpty here 2024-06-09 09:45:05 -03:00
1e2ccc9fc6 perf: we can chain append here 2024-06-09 09:44:23 -03:00
1424405c64 perf: fix redundant addAll 2024-06-09 09:43:31 -03:00
33d5c5238a perf: findAny().isPresent() is cleaner here 2024-06-09 09:42:43 -03:00
b7735295f1 perf: count > 0 can be anyMatch 2024-06-09 09:42:06 -03:00
e4123f47d6 perf: class initializer may be static 2024-06-09 09:39:46 -03:00
4f1ad7b576 perf: Call to 'asList()' with only one argument 2024-06-09 09:39:21 -03:00
6e3b3b20a0 refactor: implicit cast from double to float may be lossy 2024-06-09 09:38:33 -03:00
d5ad077ce1 fix: integer division in floating point 2024-06-09 09:37:06 -03:00
6e7418a89d refactor: replace concatenation log with parameterized 2024-06-09 09:35:38 -03:00
77e246213f refactor: fix javadoc issues 2024-06-09 09:33:59 -03:00
c9b42a6dfb refactor: replace switch with enhanced switch 2024-06-09 09:25:14 -03:00
7db8b6f0c7 refactor: Integer.ParseInt is more appropriate here 2024-06-09 09:20:19 -03:00
6d669bd47a refactor: Integer.ParseInt is more appropriate here 2024-06-09 09:19:41 -03:00
bb82e21c82 refactor: replace for loop with enhanced loop 2024-06-09 09:18:48 -03:00
b5d0afd0fe refactor: we don't need explicit types here 2024-06-09 09:17:05 -03:00
fcd409320d refactor: replace statement with expression lambda 2024-06-09 09:15:22 -03:00
c7119aae68 refactor: simplify map operations
we can use computeIfAbsent here
2024-06-09 09:13:18 -03:00
3119e0fffc refactor: replace lambda with method reference 2024-06-09 09:11:58 -03:00
870085fc91 refactor: replace lambda with method reference 2024-06-09 09:10:48 -03:00
8c35c89bf5 refactor: replace Collections.sort with list.sort
Collections.sort is just a wrapper, so it is better to use an instance method directly.
2024-06-09 09:09:45 -03:00
9c946e9d2e chore: remove unused import 2024-06-09 09:07:54 -03:00
427a1cf5f5 fix: variable is assigned to itself 2024-06-09 09:06:12 -03:00
0161b4d73d refactor: replace protected with private for final class 2024-06-09 09:04:26 -03:00
ca6ddfd2cc refactor: replace protected with private for final class 2024-06-09 09:03:50 -03:00
7d3abb083b refactor: this can also be final 2024-06-09 09:00:39 -03:00
9fa0f2bcad refactor: unwrap redundant code block 2024-06-09 08:58:01 -03:00
029ef823e1 refactor: remove unnecessary semicolons 2024-06-09 08:56:58 -03:00
c3eafba072 refactor: remove unnecessary toString call 2024-06-09 08:55:58 -03:00
ef58ab3e5a refactor: replace size() == 0 with isEmpty() 2024-06-09 08:54:37 -03:00
da61d30f44 refactor: make getGoodsLimit one liner 2024-06-09 08:50:40 -03:00
6bb349d92b fix: make those fields final 2024-06-09 08:47:56 -03:00
368 changed files with 1831 additions and 3067 deletions

11
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "gradle" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"

View File

@ -20,9 +20,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
@ -44,7 +44,7 @@ jobs:
- name: Run Gradle
run: ./gradlew -PskipHandbook=1 && ./gradlew jar -PskipHandbook=1
- name: Upload build
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: Grasscutter
path: grasscutter-*.jar

View File

@ -18,12 +18,6 @@
* Spawning monsters via console
* Inventory features (receiving items/characters, upgrading items/characters, etc)
## Foreward
### **Grasscutter beyond the latest release will have no handholding in terms of instructions.**
Grasscutter has not been actively maintained and currently (as of January 12th, 2025) only works up to version REL4.0.1 (introduction to Fontaine). If you have a beta version/unofficial version of Grasscutter, this guide should theoretically still work, however, we will not provide official support these versions. You can still try your luck in the Discord if you are stuck, but please don't act entitled.
## Quick setup guide
**Note**: For support please join our [Discord](https://discord.gg/T5vZU6UyeG).
@ -35,7 +29,6 @@ Grasscutter has not been actively maintained and currently (as of January 12th,
- Get game version REL4.0.x (If you don't have a 4.0.x client, you can find it here and open any of the links to download it):
[4.0.x Client-github](https://github.com/JRSKelvin/GenshinRepository/blob/main/Version%204.0.0.md)
[4.0.x Client-cloud drive](https://www.123pan.com/s/HoqUVv-U7SBA.html)
- ***UPDATE JAN 12, 2025: YOU CANNOT MIX AND MATCH GAME VERSIONS AND SERVER VERSIONS, PLEASE DOWNLOAD THE CORRECT VERSION OF GRASSCUTTER FOR YOUR VERSION OF THE GAME.***
- Download the [latest Cultivation version](https://github.com/Grasscutters/Cultivation/releases/latest). Use the `.msi` installer.
- After opening Cultivation (as admin), press the download button in the upper right corner.

View File

@ -82,7 +82,7 @@ dependencies {
// Line reading libraries.
implementation group: 'org.jline', name: 'jline', version: '3.21.0'
implementation group: 'org.jline', name: 'jline-terminal-jna', version: '3.21.0'
implementation group: 'org.jline', name: 'jline-terminal-jna', version: '3.26.1'
implementation group: 'net.java.dev.jna', name: 'jna', version: '5.10.0'
// Java Netty for networking.
@ -96,7 +96,7 @@ dependencies {
implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.19.6'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.2'
implementation platform('com.fasterxml.jackson:jackson-bom:2.14.0')
implementation platform('com.fasterxml.jackson:jackson-bom:2.17.1')
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.2'
// Reflections libraries.
@ -130,7 +130,7 @@ dependencies {
// Testing libraries.
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.2'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: '5.8.2'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.2'
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.2'
// HTTP client library for testing.
testImplementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.10.0'
@ -261,7 +261,7 @@ clean {
protobuf {
protoc {
// The artifact spec for the Protobuf Compiler
artifact = 'com.google.protobuf:protoc:3.18.1'
artifact = 'com.google.protobuf:protoc:4.27.1'
}
generatedFilesBaseDir = "$projectDir/src/generated/"

View File

@ -5,7 +5,7 @@
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Aantekening:** We verwelkomen altijd bijdragers aan het project. Lees onze [Gedragscode](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) zorgvuldig door voordat u uw bijdrage toevoegt.
**Aantekening:** We verwelkomen altijd bijdragers aan het project. Lees onze [Gedragscode](https://github.com/Grasscutters/Grasscutter/blob/development/README_NL.md#bijdragen-aan-het-project) zorgvuldig door voordat u uw bijdrage toevoegt.
## Huidige functies

View File

@ -22,25 +22,52 @@
**각주 :** 도움이 필요할 경우 [Discord](https://discord.gg/T5vZU6UyeG)에 가입하세요.
### 빠른 설치 (자동)
### 설치에 필요한 것들
- [Java 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) 설치
- [MongoDB Community Server](https://www.mongodb.com/try/download/community) 설치
- 게임 버전 REL4.0.x 다운로드 (만약 4.0.x 클라이언트를 가지고 있지 않다면, 여기서 찾을 수 있습니다.):
[4.0.x 클라이언트 - GitHub](https://github.com/JRSKelvin/GenshinRepository/blob/main/Version%204.0.0.md)
[4.0.x 클라이언트 - 구글 드라이브브](https://www.123pan.com/s/HoqUVv-U7SBA.html)
* Java SE - 17 ([링크](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html))
- [최신 Cultivation](https://github.com/Grasscutters/Cultivation/releases/latest) 다운로드하세요. `.msi` 설치파일을 사용하면 됩니다.
- (관리자 권한으로) Cultivation을 실행한 후, 우측 상단에 위치한 다운로드 버튼을 클릭하세요.
- `올인원 다운로드`를 클릭하세요.
- 우측 상단에 위치한 톱니바퀴 버튼을 누르세요.
- 게임 설치 경로를 게임이 위치한 경로로 설정하세요.
- 사용자 지정 Java 경로 설정을 `C:\Program Files\Java\jdk-17\bin\java.exe`로 설정하세요.
- 다른 모든 설정은 기본값으로 두세요.
**각주 :** **실행**만을 원한다면, **jre**만 있어도 괜찮습니다.
- 게임 시작 버튼 옆에 위치한 작은 버튼을 누르세요.
- 게임 시작 버튼을 누르세요.
- 원하는 사용자 이름으로 로그인하세요. 비밀번호는 무엇이든 가능합니다.
* [MongoDB](https://www.mongodb.com/try/download/community) (4.0 이상의 버전 추천)
* 프록시 데몬 : mitmproxy (mitmdump 추천), Fiddler Classic 등.
### 실행
**각주 :** 구버전에서 업데이트 했을 경우, `config.json` 파일을 재생성하기 위해 파일을 삭제하세요.
1. `grasscutter.jar` 얻기
- [Actions](https://github.com/Grasscutters/Grasscutter/suites/6895963598/artifacts/267483297) 탭에서 다운로드
- [직접 빌드하기](#빌드하기)
2. grasscutter.jar 파일이 위치한 폴더에 `resources` 폴더를 생성하고, `BinOutput``ExcelBinOutput` 폴더를 생성한 폴더 내로 옮기세요. *(이 파일들을 얻는 더 자세한 방법에 대해서는 [위키](https://github.com/Grasscutters/Grasscutter/wiki)를 참조하세요.)*
3. Grasscutter를 `java -jar grasscutter.jar` 명령어로 실행합니다. **MongoDB 서비스가 정상적으로 실행되고 있는지 확인하세요.**
### 클라이언트와의 연결
½. [서버 콘솔 명령어](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting)를 이용해서 계정을 생성합니다.
1. 리다이렉트 트래픽 : (1가지 선택)
- mitmdump: `mitmdump -s proxy.py -k`
신뢰하는 인증 기관 인증서 (CA Cert) :
**각주 :** 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을 실행한 후, Setting에서 `Decrypt https traffic` 옵션을 켜고, Tools -> Options -> Connections에 있는 기본 포트를 `8888`을 제외한 다른 포트로 지정합니다. 그리고 [이 스크립트](https://github.lunatic.moe/fiddlerscript)를 불러옵니다.
- [호스트 파일](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
2. 네트워크 프록시를 `127.0.0.1:8080` 로 설정하거나 지정한 프록시 포트로 설정합니다.
**또한 `start.cmd`를 실행함으로써, 서버와 프록시 데몬을 자동으로 실행되게 할 수 있습니다. 이를 이용하기 위해서는 JAVA_HOME 환경 변수를 등록해야 합니다.**
### 빌드하기
@ -50,50 +77,39 @@ Grasscutter는 종속성 및 컴파일 처리를 위해 Gradle을 이용합니
- [Java SE 개발 키트 - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
- [Git](https://git-scm.com/downloads)
- [NodeJS](https://nodejs.org/en/download) (선택, 핸드북을 빌드하기 위해 필요함.)
##### 클론
##### 윈도우 (온라인)
```shell
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
git clone https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
.\gradlew.bat # 개발 환경 설정
.\gradlew jar # 컴파일
```
##### 컴파일
**각주**: 핸드북 생성은 일부 시스템에서 실패할 수도 있습니다. 핸드북 생성을 비활성화하려면, `gradlew jar`명령에 `-PskipHandbook=1`명령줄 스위치를 추가하세요.
윈도우:
##### 윈도우 (로컬)
```shell
.\gradlew.bat # 환경 준비
.\gradlew jar
cd <로컬 주소>/Grasscutter
.\gradlew.bat # 개발 환경 설정
.\gradlew jar # 컴파일
```
리눅스 (GNU):
##### 리눅스
```bash
git clone https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
chmod +x gradlew
./gradlew jar
```
##### 핸드북 컴파일 (수동동)
Gradle 사용:
```shell
./gradlew generateHandbook
```
NPM 사용:
```shell
cd src/handbook
npm install
npm run build
./gradlew jar # 컴파일
```
프로젝트 폴더의 최상단에서 jar 파일을 찾을 수 있습니다.
### 문제 해결
흔한 문제들의 해결방법과 도움을 요청하려면, [우리의 디스코드 서버](https://discord.gg/T5vZU6UyeG)에 참가하고 support 채널에 가보세요.
### 명령어들은 [위키](https://github.com/Grasscutters/Grasscutter/wiki/Commands)에서 확인할 수 있습니다.
# 빠른 문제 해결
* 만약 컴파일링이 정상적으로 완료되지 않을 경우, JDK 설치를 확인하세요. (JDK 버전 17 및 JDK의 bin 경로 변수 등록을 확인)
* 클라이언트가 연결되지 않거나, 로그인이 안 되거나, 4206 오류가 뜨는 등의 경우 - 대부분 프록시 데몬의 설치에 문제가 있을 것입니다. Fiddler를 사용하고 있다면, 8888을 제외한 다른 포트에서 구동되고 있는지 확인하세요.
* 구동 순서 : MongoDB > Grasscutter > 프록시 데몬 (mitmdump, fiddler 등) > 게임

View File

@ -1,12 +1,12 @@
package emu.grasscutter;
public final class DebugConstants {
public static boolean LOG_ABILITIES = false;
public static boolean LOG_LUA_SCRIPTS = false;
public static boolean LOG_QUEST_START = false;
public static boolean LOG_MISSING_ABILITIES = false;
public static boolean LOG_MISSING_LUA_SCRIPTS = false;
public static boolean LOG_MISSING_ABILITY_HANDLERS = false;
public static final boolean LOG_ABILITIES = false;
public static final boolean LOG_LUA_SCRIPTS = false;
public static final boolean LOG_QUEST_START = false;
public static final boolean LOG_MISSING_ABILITIES = false;
public static final boolean LOG_MISSING_LUA_SCRIPTS = false;
public static final boolean LOG_MISSING_ABILITY_HANDLERS = false;
/**
* WARNING: THIS IS A DANGEROUS SETTING. DO NOT ENABLE UNLESS YOU KNOW WHAT YOU ARE DOING. This

View File

@ -7,8 +7,8 @@ import emu.grasscutter.utils.objects.SparseSet;
import java.util.Arrays;
public final class GameConstants {
public static String VERSION = "4.0.0";
public static int[] VERSION_PARTS = {4, 0, 0};
public static final String VERSION = "4.0.0";
public static final int[] VERSION_PARTS = {4, 0, 0};
public static boolean DEBUG = false;
public static final int DEFAULT_TEAMS = 4;

View File

@ -312,7 +312,7 @@ public final class Grasscutter {
public static void updateDayOfWeek() {
Calendar calendar = Calendar.getInstance();
Grasscutter.currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
logger.debug("Set day of week to " + currentDayOfWeek);
logger.debug("Set day of week to {}", currentDayOfWeek);
}
public static void startConsole() {

View File

@ -103,7 +103,7 @@ public final class DefaultAuthenticators {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKey private_key = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, private_key);

View File

@ -53,7 +53,7 @@ public final class CommandMap {
* @return Instance chaining.
*/
public CommandMap registerCommand(String label, CommandHandler command) {
Grasscutter.getLogger().trace("Registered command: " + label);
Grasscutter.getLogger().trace("Registered command: {}", label);
label = label.toLowerCase();
// Get command data.
@ -76,7 +76,7 @@ public final class CommandMap {
* @return Instance chaining.
*/
public CommandMap unregisterCommand(String label) {
Grasscutter.getLogger().trace("Un-registered command: " + label);
Grasscutter.getLogger().trace("Un-registered command: {}", label);
CommandHandler handler = this.commands.get(label);
if (handler == null) return this;
@ -231,14 +231,12 @@ public final class CommandMap {
if (player != null) {
Grasscutter.getLogger()
.info(
"Command used by ["
+ player.getAccount().getUsername()
+ " (Player UID: "
+ player.getUid()
+ ")]: "
+ rawMessage);
"Command used by [{} (Player UID: {})]: {}",
player.getAccount().getUsername(),
player.getUid(),
rawMessage);
} else {
Grasscutter.getLogger().info("Command used by server console: " + rawMessage);
Grasscutter.getLogger().info("Command used by server console: {}", rawMessage);
}
}
@ -350,11 +348,12 @@ public final class CommandMap {
this.registerCommand(cmdData.label(), (CommandHandler) object);
else
Grasscutter.getLogger()
.error("Class " + annotated.getName() + " is not a CommandHandler!");
.error("Class {} is not a CommandHandler!", annotated.getName());
} catch (Exception exception) {
Grasscutter.getLogger()
.error(
"Failed to register command handler for " + annotated.getSimpleName(),
"Failed to register command handler for {}",
annotated.getSimpleName(),
exception);
}
});

View File

@ -69,7 +69,7 @@ public final class AchievementCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) {
if (args.isEmpty()) {
this.sendUsageMessage(sender);
return;
}
@ -88,7 +88,7 @@ public final class AchievementCommand implements CommandHandler {
private void grant(
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
if (args.size() < 1) {
if (args.isEmpty()) {
this.sendUsageMessage(sender);
}
@ -109,7 +109,7 @@ public final class AchievementCommand implements CommandHandler {
private void revoke(
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
if (args.size() < 1) {
if (args.isEmpty()) {
this.sendUsageMessage(sender);
}
@ -136,7 +136,7 @@ public final class AchievementCommand implements CommandHandler {
parseInt(args.remove(0))
.ifPresentOrElse(
integer -> {
integer ->
parseInt(args.remove(0))
.ifPresentOrElse(
progress -> {
@ -148,8 +148,7 @@ public final class AchievementCommand implements CommandHandler {
sender, ret.getRet().getKey());
}
},
() -> this.sendUsageMessage(sender));
},
() -> this.sendUsageMessage(sender)),
() -> this.sendUsageMessage(sender));
}
}

View File

@ -19,7 +19,7 @@ public final class AnnounceCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
var manager = Grasscutter.getGameServer().getAnnouncementSystem();
if (args.size() < 1) {
if (args.isEmpty()) {
sendUsageMessage(sender);
return;
}

View File

@ -51,7 +51,7 @@ public final class ClearCommand implements CommandHandler {
// Extract any tagged int arguments (e.g. "lv90", "x100", "r5")
parseIntParameters(args, param, intCommandHandlers);
if (args.size() < 1) {
if (args.isEmpty()) {
sendUsageMessage(sender);
return;
}
@ -93,9 +93,10 @@ public final class ClearCommand implements CommandHandler {
}
}
@Setter
private static class ClearItemParameters {
@Setter public int lvl = 1;
@Setter public int refinement = 1;
@Setter public int rank = 4;
public int lvl = 1;
public int refinement = 1;
public int rank = 4;
}
}

View File

@ -16,7 +16,7 @@ public final class EnterDungeonCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) {
if (args.isEmpty()) {
sendUsageMessage(sender);
return;
}

View File

@ -3,16 +3,23 @@ package emu.grasscutter.command.commands;
import static emu.grasscutter.GameConstants.*;
import static emu.grasscutter.command.CommandHelpers.*;
import emu.grasscutter.command.*;
import emu.grasscutter.data.*;
import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameDepot;
import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.data.excels.avatar.AvatarData;
import emu.grasscutter.data.excels.reliquary.*;
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.inventory.*;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.*;
import java.util.*;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.FightProperty;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.regex.Pattern;
import lombok.Setter;
@ -279,7 +286,7 @@ public final class GiveCommand implements CommandHandler {
parseIntParameters(args, param, intCommandHandlers);
// At this point, first remaining argument MUST be itemId/avatarId
if (args.size() < 1) {
if (args.isEmpty()) {
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
throw new IllegalArgumentException();
}
@ -362,7 +369,7 @@ public final class GiveCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) { // *No args*
if (args.isEmpty()) { // *No args*
sendUsageMessage(sender);
return;
}

View File

@ -63,9 +63,7 @@ public final class GroupCommand implements CommandHandler {
CommandHandler.sendMessage(sender, translate(sender, "commands.group.refreshed", groupId));
}
default -> {
sendUsageMessage(sender);
}
default -> sendUsageMessage(sender);
}
}
}

View File

@ -19,14 +19,14 @@ public final class ListCommand implements CommandHandler {
Map<Integer, Player> playersMap = Grasscutter.getGameServer().getPlayers();
boolean needUID = false;
if (args.size() > 0) {
if (!args.isEmpty()) {
needUID = args.get(0).equals("uid");
}
CommandHandler.sendMessage(
sender, translate(sender, "commands.list.success", playersMap.size()));
if (playersMap.size() != 0) {
if (!playersMap.isEmpty()) {
StringBuilder playerSet = new StringBuilder();
boolean finalNeedUID = needUID;

View File

@ -18,7 +18,7 @@ public final class ResetConstCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() > 0 && args.get(0).equalsIgnoreCase("all")) {
if (!args.isEmpty() && args.get(0).equalsIgnoreCase("all")) {
targetPlayer.getAvatars().forEach(this::resetConstellation);
CommandHandler.sendMessage(sender, translate(sender, "commands.resetConst.reset_all"));
} else {

View File

@ -24,8 +24,7 @@ public final class SendMailCommand implements CommandHandler {
// the command system (again). For now this will do
// Key = User that is constructing the mail.
private static final HashMap<Integer, MailBuilder> mailBeingConstructed =
new HashMap<Integer, MailBuilder>();
private static final HashMap<Integer, MailBuilder> mailBeingConstructed = new HashMap<>();
// Yes this is awful and I hate it.
@Override
@ -69,7 +68,7 @@ public final class SendMailCommand implements CommandHandler {
} else {
MailBuilder mailBuilder = mailBeingConstructed.get(senderId);
if (args.size() >= 1) {
if (!args.isEmpty()) {
switch (args.get(0).toLowerCase()) {
case "stop" -> {
mailBeingConstructed.remove(senderId);
@ -106,14 +105,12 @@ public final class SendMailCommand implements CommandHandler {
getConstructionArgs(mailBuilder.constructionStage, sender)));
}
}
case "help" -> {
CommandHandler.sendMessage(
case "help" -> CommandHandler.sendMessage(
sender,
translate(
sender,
"commands.sendMail.please_use",
getConstructionArgs(mailBuilder.constructionStage, sender)));
}
default -> {
switch (mailBuilder.constructionStage) {
case 0 -> {

View File

@ -17,7 +17,7 @@ public final class SendMessageCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() == 0) {
if (args.isEmpty()) {
sendUsageMessage(sender);
return;
}

View File

@ -17,7 +17,7 @@ import java.util.List;
public final class SetConstCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) {
if (args.isEmpty()) {
sendUsageMessage(sender);
return;
}

View File

@ -291,9 +291,9 @@ public final class SetPropCommand implements CommandHandler {
}
static class Prop {
String name;
PlayerProperty prop;
PseudoProp pseudoProp;
final String name;
final PlayerProperty prop;
final PseudoProp pseudoProp;
public Prop(PlayerProperty prop) {
this(prop.toString(), prop, PseudoProp.NONE);

View File

@ -95,9 +95,8 @@ public final class SetSceneTagCommand implements CommandHandler {
// Only remove for big world as some other scenes only have defaults
.filter(sceneTag -> sceneTag.getSceneId() == 3)
.forEach(
sceneTag -> {
targetPlayer.getSceneTags().get(sceneTag.getSceneId()).remove(sceneTag.getId());
});
sceneTag ->
targetPlayer.getSceneTags().get(sceneTag.getSceneId()).remove(sceneTag.getId()));
this.setSceneTags(targetPlayer);
}

View File

@ -171,8 +171,8 @@ public final class SetStatsCommand implements CommandHandler {
}
private static class Stat {
String name;
FightProperty prop;
final String name;
final FightProperty prop;
public Stat(FightProperty prop) {
this.name = prop.toString();

View File

@ -49,7 +49,7 @@ public final class SpawnCommand implements CommandHandler {
parseIntParameters(args, param, intCommandHandlers);
// At this point, first remaining argument MUST be the id and the rest the pos
if (args.size() < 1) {
if (args.isEmpty()) {
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
throw new IllegalArgumentException();
}

View File

@ -17,11 +17,9 @@ public final class StopCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
CommandHandler.sendMessage(null, translate("commands.stop.success"));
if (Grasscutter.getGameServer() != null) {
for (Player p : Grasscutter.getGameServer().getPlayers().values()) {
CommandHandler.sendMessage(p, translate(p, "commands.stop.success"));
}
}
System.exit(1000);
}

View File

@ -27,7 +27,7 @@ public final class TalentCommand implements CommandHandler {
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) {
if (args.isEmpty()) {
sendUsageMessage(sender);
return;
}
@ -45,9 +45,7 @@ public final class TalentCommand implements CommandHandler {
String cmdSwitch = args.get(0).toLowerCase();
switch (cmdSwitch) {
default -> {
sendUsageMessage(sender);
}
default -> sendUsageMessage(sender);
case "set" -> {
if (args.size() < 3) {
sendUsageMessage(sender);

View File

@ -131,7 +131,7 @@ public final class TrialAvatarActivityCommand implements CommandHandler {
translate(
sender, "commands.trialAvatarActivity.success_reward", Integer.parseInt(param)));
} else {
if (!param.toLowerCase().equals("all")) {
if (!param.equalsIgnoreCase("all")) {
CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
return;

View File

@ -78,11 +78,11 @@ public class ConfigContainer {
}
}
public Structure folderStructure = new Structure();
public Database databaseInfo = new Database();
public Language language = new Language();
public Account account = new Account();
public Server server = new Server();
public final Structure folderStructure = new Structure();
public final Database databaseInfo = new Database();
public final Language language = new Language();
public final Account account = new Account();
public final Server server = new Server();
// DO NOT. TOUCH. THE VERSION NUMBER.
public int version = version();
@ -90,99 +90,99 @@ public class ConfigContainer {
/* Option containers. */
public static class Database {
public DataStore server = new DataStore();
public DataStore game = new DataStore();
public final DataStore server = new DataStore();
public final DataStore game = new DataStore();
public static class DataStore {
public String connectionUri = "mongodb://localhost:27017";
public String collection = "grasscutter";
public final String connectionUri = "mongodb://localhost:27017";
public final String collection = "grasscutter";
}
}
public static class Structure {
public String resources = "./resources/";
public String data = "./data/";
public String packets = "./packets/";
public String scripts = "resources:Scripts/";
public String plugins = "./plugins/";
public String cache = "./cache/";
public final String resources = "./resources/";
public final String data = "./data/";
public final String packets = "./packets/";
public final String scripts = "resources:Scripts/";
public final String plugins = "./plugins/";
public final String cache = "./cache/";
// UNUSED (potentially added later?)
// public String dumps = "./dumps/";
}
public static class Server {
public Set<Integer> debugWhitelist = Set.of();
public Set<Integer> debugBlacklist = Set.of();
public ServerRunMode runMode = ServerRunMode.HYBRID;
public boolean logCommands = false;
public final Set<Integer> debugWhitelist = Set.of();
public final Set<Integer> debugBlacklist = Set.of();
public final ServerRunMode runMode = ServerRunMode.HYBRID;
public final boolean logCommands = false;
/**
* If enabled, the 'require' Lua function will load the script's compiled varient into the context. (faster; doesn't work as well)
* If disabled, all 'require' calls will be replaced with the referenced script's source. (slower; works better)
*/
public boolean fastRequire = true;
public final boolean fastRequire = true;
public HTTP http = new HTTP();
public Game game = new Game();
public final HTTP http = new HTTP();
public final Game game = new Game();
public Dispatch dispatch = new Dispatch();
public DebugMode debugMode = new DebugMode();
public final Dispatch dispatch = new Dispatch();
public final DebugMode debugMode = new DebugMode();
}
public static class Language {
public Locale language = Locale.getDefault();
public Locale fallback = Locale.US;
public String document = "EN";
public final Locale fallback = Locale.US;
public final String document = "EN";
}
public static class Account {
public boolean autoCreate = false;
public boolean EXPERIMENTAL_RealPassword = false;
public String[] defaultPermissions = {};
public String playerEmail = "grasscutter.io";
public int maxPlayer = -1;
public final boolean autoCreate = false;
public final boolean EXPERIMENTAL_RealPassword = false;
public final String[] defaultPermissions = {};
public final String playerEmail = "grasscutter.io";
public final int maxPlayer = -1;
}
/* Server options. */
public static class HTTP {
/* This starts the HTTP server before the game server. */
public boolean startImmediately = false;
public final boolean startImmediately = false;
public String bindAddress = "0.0.0.0";
public int bindPort = 443;
public final String bindAddress = "0.0.0.0";
public final int bindPort = 443;
/* This is the address used in URLs. */
public String accessAddress = "127.0.0.1";
public final String accessAddress = "127.0.0.1";
/* This is the port used in URLs. */
public int accessPort = 0;
public final int accessPort = 0;
public Encryption encryption = new Encryption();
public Policies policies = new Policies();
public Files files = new Files();
public final Encryption encryption = new Encryption();
public final Policies policies = new Policies();
public final Files files = new Files();
}
public static class Game {
public String bindAddress = "0.0.0.0";
public int bindPort = 22102;
public final String bindAddress = "0.0.0.0";
public final int bindPort = 22102;
/* This is the address used in the default region. */
public String accessAddress = "127.0.0.1";
public final String accessAddress = "127.0.0.1";
/* This is the port used in the default region. */
public int accessPort = 0;
public final int accessPort = 0;
/* Enabling this will generate a unique packet encryption key for each player. */
public boolean useUniquePacketKey = true;
public final boolean useUniquePacketKey = true;
/* Entities within a certain range will be loaded for the player */
public int loadEntitiesForPlayerRange = 300;
public final int loadEntitiesForPlayerRange = 300;
/* Start in 'unstable-quests', Lua scripts will be enabled by default. */
public boolean enableScriptInBigWorld = true;
public final boolean enableScriptInBigWorld = true;
public boolean enableConsole = true;
/* Kcp internal work interval (milliseconds) */
public int kcpInterval = 20;
public final int kcpInterval = 20;
/* Controls whether packets should be logged in console or not */
public ServerDebugMode logPackets = ServerDebugMode.NONE;
/* Show packet payload in console or no (in any case the payload is shown in encrypted view) */
@ -190,13 +190,13 @@ public class ConfigContainer {
/* Show annoying loop packets or no */
public boolean isShowLoopPackets = false;
public boolean cacheSceneEntitiesEveryRun = false;
public final boolean cacheSceneEntitiesEveryRun = false;
public GameOptions gameOptions = new GameOptions();
public JoinOptions joinOptions = new JoinOptions();
public ConsoleAccount serverAccount = new ConsoleAccount();
public final GameOptions gameOptions = new GameOptions();
public final JoinOptions joinOptions = new JoinOptions();
public final ConsoleAccount serverAccount = new ConsoleAccount();
public VisionOptions[] visionOptions = new VisionOptions[] {
public final VisionOptions[] visionOptions = new VisionOptions[] {
new VisionOptions("VISION_LEVEL_NORMAL" , 80 , 20),
new VisionOptions("VISION_LEVEL_LITTLE_REMOTE" , 16 , 40),
new VisionOptions("VISION_LEVEL_REMOTE" , 1000 , 250),
@ -210,17 +210,17 @@ public class ConfigContainer {
public static class Dispatch {
/* An array of servers. */
public List<Region> regions = List.of();
public final List<Region> regions = List.of();
/* The URL used to make HTTP requests to the dispatch server. */
public String dispatchUrl = "ws://127.0.0.1:1111";
public final String dispatchUrl = "ws://127.0.0.1:1111";
/* A unique key used for encryption. */
public byte[] encryptionKey = Crypto.createSessionKey(32);
public final byte[] encryptionKey = Crypto.createSessionKey(32);
/* A unique key used for authentication. */
public String dispatchKey = Utils.base64Encode(
public final String dispatchKey = Utils.base64Encode(
Crypto.createSessionKey(32));
public String defaultName = "Grasscutter";
public final String defaultName = "Grasscutter";
/* Controls whether http requests should be logged in console or not */
public ServerDebugMode logRequests = ServerDebugMode.NONE;
@ -230,127 +230,127 @@ public class ConfigContainer {
* (see StartupArguments.enableDebug) */
public static class DebugMode {
/* Log level of the main server code (works only with -debug arg) */
public Level serverLoggerLevel = Level.DEBUG;
public final Level serverLoggerLevel = Level.DEBUG;
/* Log level of the third-party services (works only with -debug arg):
javalin, quartz, reflections, jetty, mongodb.driver */
public Level servicesLoggersLevel = Level.INFO;
public final Level servicesLoggersLevel = Level.INFO;
/* Controls whether packets should be logged in console or not */
public ServerDebugMode logPackets = ServerDebugMode.ALL;
public final ServerDebugMode logPackets = ServerDebugMode.ALL;
/* Show packet payload in console or no (in any case the payload is shown in encrypted view) */
public boolean isShowPacketPayload = false;
public final boolean isShowPacketPayload = false;
/* Show annoying loop packets or no */
public boolean isShowLoopPackets = false;
public final boolean isShowLoopPackets = false;
/* Controls whether http requests should be logged in console or not */
public ServerDebugMode logRequests = ServerDebugMode.ALL;
public final ServerDebugMode logRequests = ServerDebugMode.ALL;
}
public static class Encryption {
public boolean useEncryption = true;
/* Should 'https' be appended to URLs? */
public boolean useInRouting = true;
public String keystore = "./keystore.p12";
public String keystorePassword = "123456";
public final String keystore = "./keystore.p12";
public final String keystorePassword = "123456";
}
public static class Policies {
public Policies.CORS cors = new Policies.CORS();
public final Policies.CORS cors = new Policies.CORS();
public static class CORS {
public boolean enabled = true;
public String[] allowedOrigins = new String[]{"*"};
public final boolean enabled = true;
public final String[] allowedOrigins = new String[]{"*"};
}
}
public static class GameOptions {
public InventoryLimits inventoryLimits = new InventoryLimits();
public AvatarLimits avatarLimits = new AvatarLimits();
public int sceneEntityLimit = 1000; // Unenforced. TODO: Implement.
public final InventoryLimits inventoryLimits = new InventoryLimits();
public final AvatarLimits avatarLimits = new AvatarLimits();
public final int sceneEntityLimit = 1000; // Unenforced. TODO: Implement.
public boolean watchGachaConfig = false;
public boolean enableShopItems = true;
public boolean staminaUsage = true;
public boolean energyUsage = true;
public boolean fishhookTeleport = true;
public boolean trialCostumes = false;
public final boolean watchGachaConfig = false;
public final boolean enableShopItems = true;
public final boolean staminaUsage = true;
public final boolean energyUsage = true;
public final boolean fishhookTeleport = true;
public final boolean trialCostumes = false;
@SerializedName(value = "questing", alternate = "questOptions")
public Questing questing = new Questing();
public ResinOptions resinOptions = new ResinOptions();
public Rates rates = new Rates();
public final Questing questing = new Questing();
public final ResinOptions resinOptions = new ResinOptions();
public final Rates rates = new Rates();
public HandbookOptions handbook = new HandbookOptions();
public final HandbookOptions handbook = new HandbookOptions();
public static class InventoryLimits {
public int weapons = 2000;
public int relics = 2000;
public int materials = 2000;
public int furniture = 2000;
public int all = 30000;
public final int weapons = 2000;
public final int relics = 2000;
public final int materials = 2000;
public final int furniture = 2000;
public final int all = 30000;
}
public static class AvatarLimits {
public int singlePlayerTeam = 4;
public int multiplayerTeam = 4;
public final int singlePlayerTeam = 4;
public final int multiplayerTeam = 4;
}
public static class Rates {
public float adventureExp = 1.0f;
public final float adventureExp = 1.0f;
public float mora = 1.0f;
public float leyLines = 1.0f;
}
public static class ResinOptions {
public boolean resinUsage = false;
public int cap = 160;
public int rechargeTime = 480;
public final boolean resinUsage = false;
public final int cap = 160;
public final int rechargeTime = 480;
}
public static class Questing {
/* Should questing behavior be used? */
public boolean enabled = true;
public final boolean enabled = true;
}
public static class HandbookOptions {
public boolean enable = false;
public boolean allowCommands = true;
public final boolean enable = false;
public final boolean allowCommands = true;
public Limits limits = new Limits();
public Server server = new Server();
public final Limits limits = new Limits();
public final Server server = new Server();
public static class Limits {
/* Are rate limits checked? */
public boolean enabled = false;
public final boolean enabled = false;
/* The time for limits to expire. */
public int interval = 3;
public final int interval = 3;
/* The maximum amount of normal requests. */
public int maxRequests = 10;
public final int maxRequests = 10;
/* The maximum amount of entities to be spawned in one request. */
public int maxEntities = 25;
public final int maxEntities = 25;
}
public static class Server {
/* Are the server settings sent to the handbook? */
public boolean enforced = false;
public final boolean enforced = false;
/* The default server address for the handbook's authentication. */
public String address = "127.0.0.1";
public final String address = "127.0.0.1";
/* The default server port for the handbook's authentication. */
public int port = 443;
public final int port = 443;
/* Should the defaults be enforced? */
public boolean canChange = true;
public final boolean canChange = true;
}
}
}
public static class VisionOptions {
public String name;
public int visionRange;
public int gridWidth;
public final String name;
public final int visionRange;
public final int gridWidth;
public VisionOptions(String name, int visionRange, int gridWidth) {
this.name = name;
@ -360,21 +360,21 @@ public class ConfigContainer {
}
public static class JoinOptions {
public int[] welcomeEmotes = {2007, 1002, 4010};
public String welcomeMessage = "Welcome to a Grasscutter server.";
public JoinOptions.Mail welcomeMail = new JoinOptions.Mail();
public final int[] welcomeEmotes = {2007, 1002, 4010};
public final String welcomeMessage = "Welcome to a Grasscutter server.";
public final JoinOptions.Mail welcomeMail = new JoinOptions.Mail();
public static class Mail {
public String title = "Welcome to Grasscutter!";
public String content = """
public final String title = "Welcome to Grasscutter!";
public final String content = """
Hi there!\r
First of all, welcome to Grasscutter. If you have any issues, please let us know so that Lawnmower can help you! \r
\r
Check out our:\r
<type="browser" text="Discord" href="https://discord.gg/T5vZU6UyeG"/>
""";
public String sender = "Lawnmower";
public emu.grasscutter.game.mail.Mail.MailItem[] items = {
public final String sender = "Lawnmower";
public final emu.grasscutter.game.mail.Mail.MailItem[] items = {
new emu.grasscutter.game.mail.Mail.MailItem(13509, 1, 1),
new emu.grasscutter.game.mail.Mail.MailItem(201, 99999, 1)
};
@ -382,18 +382,18 @@ public class ConfigContainer {
}
public static class ConsoleAccount {
public int avatarId = 10000007;
public int nameCardId = 210001;
public int adventureRank = 1;
public int worldLevel = 0;
public final int avatarId = 10000007;
public final int nameCardId = 210001;
public final int adventureRank = 1;
public final int worldLevel = 0;
public String nickName = "Server";
public String signature = "Welcome to Grasscutter!";
public final String nickName = "Server";
public final String signature = "Welcome to Grasscutter!";
}
public static class Files {
public String indexFile = "./index.html";
public String errorFile = "./404.html";
public final String indexFile = "./index.html";
public final String errorFile = "./404.html";
}
/* Objects. */

View File

@ -1,10 +1,17 @@
package emu.grasscutter.data;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.utils.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.utils.JsonUtils;
import emu.grasscutter.utils.TsvUtils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import lombok.val;
public class DataLoader {
@ -15,7 +22,7 @@ public class DataLoader {
*
* @param resourcePath The path to the data file to be loaded.
* @return InputStream of the data file.
* @throws FileNotFoundException
* @throws FileNotFoundException If the file is not found.
* @see #load(String, boolean)
*/
public static InputStream load(String resourcePath) throws FileNotFoundException {
@ -24,22 +31,18 @@ public class DataLoader {
/**
* Creates an input stream reader for a data file. If the file isn't found within the /data
* directory then it will fallback to the default within the jar resources
* directory then it will fall back to the default within the jar resources
*
* @param resourcePath The path to the data file to be loaded.
* @return InputStreamReader of the data file.
* @throws IOException
* @throws FileNotFoundException
* @throws IOException If the file is not found.
* @throws FileNotFoundException If the file is not found.
* @see #load(String, boolean)
*/
public static InputStreamReader loadReader(String resourcePath)
throws IOException, FileNotFoundException {
try {
public static InputStreamReader loadReader(String resourcePath) throws IOException {
InputStream is = load(resourcePath, true);
if (is == null) throw new FileNotFoundException("File not found: " + resourcePath);
return new InputStreamReader(is);
} catch (FileNotFoundException exception) {
throw exception;
}
}
/**
@ -49,7 +52,7 @@ public class DataLoader {
* @param useFallback If the file does not exist in the /data directory, should it use the default
* file in the jar?
* @return InputStream of the data file.
* @throws FileNotFoundException
* @throws FileNotFoundException If the file is not found.
*/
public static InputStream load(String resourcePath, boolean useFallback)
throws FileNotFoundException {
@ -89,7 +92,7 @@ public class DataLoader {
public static <T> List<T> loadTableToList(String resourcePath, Class<T> classType)
throws IOException {
val path = FileUtils.getDataPathTsjJsonTsv(resourcePath);
Grasscutter.getLogger().trace("Loading data table from: " + path);
Grasscutter.getLogger().trace("Loading data table from: {}", path);
return switch (FileUtils.getFileExtension(path)) {
case "json" -> JsonUtils.loadToList(path, classType);
case "tsj" -> TsvUtils.loadTsjToListSetField(path, classType);
@ -120,10 +123,9 @@ public class DataLoader {
if (!Files.exists(filePath)) {
var root = filePath.getParent();
if (root.toFile().mkdirs())
Grasscutter.getLogger().info("Created data folder '" + root + "'");
if (root.toFile().mkdirs()) Grasscutter.getLogger().info("Created data folder '{}'", root);
Grasscutter.getLogger().debug("Creating default '" + name + "' data");
Grasscutter.getLogger().debug("Creating default '{}' data", name);
FileUtils.copyResource("/defaults/data/" + name, filePath.toString());
}
}

View File

@ -569,8 +569,8 @@ public final class GameData {
private static final Int2IntMap trialAvatarIndexIdTrialActivityDataDataMap =
new Int2IntOpenHashMap();
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
private static final Map<Integer, List<Integer>> fetters = new HashMap<>();
private static final Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
// Getters with different names that stay for now
public static Int2ObjectMap<MainQuestData> getMainQuestDataMap() {
@ -630,15 +630,21 @@ public final class GameData {
// Non-nullable value getters
public static int getAvatarLevelExpRequired(int level) {
return Optional.ofNullable(avatarLevelDataMap.get(level)).map(d -> d.getExp()).orElse(0);
return Optional.ofNullable(avatarLevelDataMap.get(level))
.map(AvatarLevelData::getExp)
.orElse(0);
}
public static int getAvatarFetterLevelExpRequired(int level) {
return Optional.ofNullable(avatarFetterLevelDataMap.get(level)).map(d -> d.getExp()).orElse(0);
return Optional.ofNullable(avatarFetterLevelDataMap.get(level))
.map(AvatarFetterLevelData::getExp)
.orElse(0);
}
public static int getRelicExpRequired(int rankLevel, int level) {
return Optional.ofNullable(getRelicLevelData(rankLevel, level)).map(d -> d.getExp()).orElse(0);
return Optional.ofNullable(getRelicLevelData(rankLevel, level))
.map(ReliquaryLevelData::getExp)
.orElse(0);
}
// Generic getter
@ -655,7 +661,7 @@ public final class GameData {
field.setAccessible(false);
} catch (Exception e) {
Grasscutter.getLogger()
.error("Error fetching resource map for " + resourceDefinition.getSimpleName(), e);
.error("Error fetching resource map for {}", resourceDefinition.getSimpleName(), e);
}
return map;
@ -713,8 +719,8 @@ public final class GameData {
/**
* Fetches the trial data
*
* @param trialAvatarIndexId
* @return
* @param trialAvatarIndexId The ID of the trial avatar
* @return The trial data for the trial avatar
*/
@Nullable public static TrialAvatarActivityDataData getTrialAvatarActivityDataByAvatarIndex(
int trialAvatarIndexId) {

View File

@ -13,17 +13,17 @@ import lombok.*;
public class GameDepot {
public static final int[] BLOCK_SIZE = new int[] {50, 500}; // Scales
private static Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot =
private static final Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot =
new Int2ObjectOpenHashMap<>();
private static Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
new Int2ObjectOpenHashMap<>();
private static Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
new Int2ObjectOpenHashMap<>();
@Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
@Getter
private static HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
new HashMap<>();
@Getter @Setter private static BlossomConfig blossomConfig;
@ -50,7 +50,7 @@ public class GameDepot {
list.add(data);
}
// Let the server owner know if theyre missing weights
if (relicMainPropDepot.size() == 0 || relicAffixDepot.size() == 0) {
if (relicMainPropDepot.isEmpty() || relicAffixDepot.isEmpty()) {
Grasscutter.getLogger()
.error(
"Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder.");

View File

@ -63,7 +63,7 @@ public final class ResourceLoader {
private static List<Set<Class<?>>> getResourceDefClassesPrioritySets() {
val classes = Grasscutter.reflector.getSubTypesOf(GameResource.class);
val priorities = ResourceType.LoadPriority.getInOrder();
Grasscutter.getLogger().debug("Priorities are " + priorities);
Grasscutter.getLogger().debug("Priorities are {}", priorities);
val map = new LinkedHashMap<ResourceType.LoadPriority, Set<Class<?>>>(priorities.size());
priorities.forEach(p -> map.put(p, new HashSet<>()));
@ -140,7 +140,7 @@ public final class ResourceLoader {
getResourceDefClassesPrioritySets()
.forEach(
classes -> {
classes ->
classes.stream()
.parallel()
.unordered()
@ -157,19 +157,18 @@ public final class ResourceLoader {
} catch (Exception e) {
errors.add(Pair.of(Arrays.toString(type.name()), e));
}
});
});
}));
errors.forEach(
pair ->
Grasscutter.getLogger()
.error("Error loading resource file: " + pair.left(), pair.right()));
.error("Error loading resource file: {}", pair.left(), pair.right()));
long endTime = System.nanoTime();
long ns = (endTime - startTime); // divide by 1000000 to get milliseconds.
Grasscutter.getLogger().debug("Loading resources took " + ns + "ns == " + ns / 1000000 + "ms");
Grasscutter.getLogger().debug("Loading resources took {}ns == {}ms", ns, ns / 1000000);
}
@SuppressWarnings("rawtypes")
protected static void loadFromResource(
private static void loadFromResource(
Class<?> c, ResourceType type, Int2ObjectMap map, boolean doReload) throws Exception {
val simpleName = c.getSimpleName();
if (doReload || !loadedResources.contains(simpleName)) {
@ -181,7 +180,7 @@ public final class ResourceLoader {
}
@SuppressWarnings({"rawtypes", "unchecked"})
protected static <T> void loadFromResource(Class<T> c, Path filename, Int2ObjectMap map)
private static <T> void loadFromResource(Class<T> c, Path filename, Int2ObjectMap map)
throws Exception {
val results =
switch (FileUtils.getFileExtension(filename)) {
@ -200,7 +199,7 @@ public final class ResourceLoader {
}
@SuppressWarnings({"rawtypes", "unchecked"})
protected static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map)
private static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map)
throws Exception {
JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c)
.forEach(
@ -283,7 +282,7 @@ public final class ResourceLoader {
}
});
Grasscutter.getLogger()
.debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneRouteDatas.");
.debug("Loaded {} SceneRouteDatas.", GameData.getSceneNpcBornData().size());
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to load SceneRouteData folder.");
}
@ -404,7 +403,7 @@ public final class ResourceLoader {
.forEach(data -> loadAbilityData(data.Default));
} catch (IOException e) {
Grasscutter.getLogger()
.error("Error loading ability modifiers from path " + path.toString() + ": ", e);
.error("Error loading ability modifiers from path {}: ", path.toString(), e);
}
}
@ -413,7 +412,7 @@ public final class ResourceLoader {
GameData.getAbilityHashes().put(Utils.abilityHash(data.abilityName), data.abilityName);
var modifiers = data.modifiers;
if (modifiers == null || modifiers.size() == 0) return;
if (modifiers == null || modifiers.isEmpty()) return;
var name = data.abilityName;
var modifierEntry = new AbilityModifierEntry(name);
@ -466,7 +465,7 @@ public final class ResourceLoader {
path, String.class, new TypeToken<List<TalentData>>() {}.getType()));
} catch (IOException e) {
Grasscutter.getLogger()
.error("Error loading ability modifiers from path " + path.toString() + ": ", e);
.error("Error loading ability modifiers from path {}: ", path.toString(), e);
}
}
@ -533,7 +532,7 @@ public final class ResourceLoader {
});
} catch (IOException e) {
Grasscutter.getLogger()
.error("Error loading open config: no files found in " + folderName);
.error("Error loading open config: no files found in {}", folderName);
return;
}
}
@ -589,7 +588,7 @@ public final class ResourceLoader {
}
Grasscutter.getLogger()
.debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
.debug("Loaded {} MainQuestDatas.", GameData.getMainQuestDataMap().size());
}
public static void loadScriptSceneData() {
@ -607,7 +606,7 @@ public final class ResourceLoader {
}
});
Grasscutter.getLogger()
.debug("Loaded " + GameData.getScriptSceneDataMap().size() + " ScriptSceneDatas.");
.debug("Loaded {} ScriptSceneDatas.", GameData.getScriptSceneDataMap().size());
} catch (IOException e) {
Grasscutter.getLogger().debug("ScriptSceneData folder missing or empty.");
}
@ -632,9 +631,8 @@ public final class ResourceLoader {
});
Grasscutter.getLogger()
.debug(
"Loaded "
+ GameData.getHomeworldDefaultSaveData().size()
+ " HomeworldDefaultSaveDatas.");
"Loaded {} HomeworldDefaultSaveDatas.",
GameData.getHomeworldDefaultSaveData().size());
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to load HomeworldDefaultSave folder.");
}
@ -647,7 +645,7 @@ public final class ResourceLoader {
path -> {
try {
val data = JsonUtils.loadToClass(path, SceneNpcBornData.class);
if (data.getBornPosList() == null || data.getBornPosList().size() == 0) {
if (data.getBornPosList() == null || data.getBornPosList().isEmpty()) {
return;
}
@ -659,7 +657,7 @@ public final class ResourceLoader {
}
});
Grasscutter.getLogger()
.debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneNpcBornDatas.");
.debug("Loaded {} SceneNpcBornDatas.", GameData.getSceneNpcBornData().size());
} catch (IOException e) {
Grasscutter.getLogger().error("Failed to load SceneNpcBorn folder.");
}
@ -837,7 +835,6 @@ public final class ResourceLoader {
try {
JsonUtils.loadToList(getResourcePath("Server/SubfieldMapping.json"), SubfieldMapping.class)
.forEach(entry -> subfieldMap.put(entry.getEntityId(), entry));
;
} catch (IOException | NullPointerException ignored) {
}
Grasscutter.getLogger().debug("Loaded {} subfield mappings.", subfieldMap.size());
@ -851,7 +848,6 @@ public final class ResourceLoader {
JsonUtils.loadToList(
getResourcePath("Server/DropSubfieldMapping.json"), DropSubfieldMapping.class)
.forEach(entry -> dropSubfieldMap.put(entry.getDropId(), entry));
;
} catch (IOException | NullPointerException ignored) {
}
Grasscutter.getLogger().debug("Loaded {} drop subfield mappings.", dropSubfieldMap.size());
@ -866,7 +862,6 @@ public final class ResourceLoader {
getResourcePath("Server/DropTableExcelConfigData.json"),
DropTableExcelConfigData.class)
.forEach(entry -> dropTableExcelConfigDataMap.put(entry.getId(), entry));
;
} catch (IOException | NullPointerException ignored) {
}
Grasscutter.getLogger()

View File

@ -1,5 +1,8 @@
package emu.grasscutter.data.binout;
import lombok.Getter;
@Getter
public class AbilityEmbryoEntry {
private String name;
private String[] abilities;
@ -10,12 +13,4 @@ public class AbilityEmbryoEntry {
this.name = avatarName;
this.abilities = array;
}
public String getName() {
return name;
}
public String[] getAbilities() {
return abilities;
}
}

View File

@ -3,17 +3,18 @@ package emu.grasscutter.data.binout;
import com.google.gson.*;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.io.Serial;
import java.io.Serializable;
import java.util.*;
public class AbilityMixinData implements Serializable {
private static final long serialVersionUID = -2001232313615923575L;
@Serial private static final long serialVersionUID = -2001232313615923575L;
public enum Type {
AttachToGadgetStateMixin,
AttachToStateIDMixin,
ShieldBarMixin,
TileAttackManagerMixin;
TileAttackManagerMixin
}
@SerializedName("$type")
@ -27,7 +28,7 @@ public class AbilityMixinData implements Serializable {
List<String> list = (new Gson()).fromJson(modifierName, listType);
return list;
} else {
return Arrays.asList(modifierName.getAsString());
return Collections.singletonList(modifierName.getAsString());
}
}
}

View File

@ -3,11 +3,12 @@ package emu.grasscutter.data.binout;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.common.DynamicFloat;
import emu.grasscutter.game.props.ElementType;
import java.io.Serial;
import java.io.Serializable;
import lombok.ToString;
public class AbilityModifier implements Serializable {
private static final long serialVersionUID = -2001232313615923575L;
@Serial private static final long serialVersionUID = -2001232313615923575L;
public State state;
@ -264,7 +265,7 @@ public class AbilityModifier implements Serializable {
TurnDirectionToPos,
UpdateReactionDamage,
UseSkillEliteSet,
WidgetSkillStart;
WidgetSkillStart
}
@SerializedName("$type")

View File

@ -2,12 +2,13 @@ package emu.grasscutter.data.binout;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
import java.util.*;
import lombok.Getter;
public class AbilityModifierEntry {
public List<AbilityModifierAction> onModifierAdded;
public List<AbilityModifierAction> onThinkInterval;
public List<AbilityModifierAction> onRemoved;
private final String name; // Custom value
public final List<AbilityModifierAction> onModifierAdded;
@Getter public final List<AbilityModifierAction> onThinkInterval;
@Getter public final List<AbilityModifierAction> onRemoved;
@Getter private final String name; // Custom value
public AbilityModifierEntry(String name) {
this.name = name;
@ -16,19 +17,7 @@ public class AbilityModifierEntry {
this.onRemoved = new ArrayList<>();
}
public String getName() {
return name;
}
public List<AbilityModifierAction> getOnAdded() {
return onModifierAdded;
}
public List<AbilityModifierAction> getOnThinkInterval() {
return onThinkInterval;
}
public List<AbilityModifierAction> getOnRemoved() {
return onRemoved;
}
}

View File

@ -5,53 +5,22 @@ import emu.grasscutter.data.GameData;
import emu.grasscutter.game.quest.enums.QuestType;
import java.util.*;
import lombok.Data;
import lombok.Getter;
public class MainQuestData {
private int id;
@Getter private int id;
private int ICLLDPJFIMA;
private int series;
private QuestType type;
@Getter private int series;
@Getter private QuestType type;
private long titleTextMapHash;
private int[] suggestTrackMainQuestList;
private int[] rewardIdList;
@Getter private long titleTextMapHash;
@Getter private int[] suggestTrackMainQuestList;
@Getter private int[] rewardIdList;
private SubQuestData[] subQuests;
private List<TalkData> talks;
@Getter private SubQuestData[] subQuests;
@Getter private List<TalkData> talks;
private long[] preloadLuaList;
public int getId() {
return id;
}
public int getSeries() {
return series;
}
public QuestType getType() {
return type;
}
public long getTitleTextMapHash() {
return titleTextMapHash;
}
public int[] getSuggestTrackMainQuestList() {
return suggestTrackMainQuestList;
}
public int[] getRewardIdList() {
return rewardIdList;
}
public SubQuestData[] getSubQuests() {
return subQuests;
}
public List<TalkData> getTalks() {
return talks;
}
public void onLoad() {
if (this.talks == null) this.talks = new ArrayList<>();
if (this.subQuests == null) this.subQuests = new SubQuestData[0];

View File

@ -2,7 +2,9 @@ package emu.grasscutter.data.binout;
import emu.grasscutter.data.ResourceLoader.OpenConfigData;
import java.util.*;
import lombok.Getter;
@Getter
public class OpenConfigEntry {
private final String name;
private String[] addAbilities;
@ -25,46 +27,23 @@ public class OpenConfigEntry {
}
}
if (abilityList.size() > 0) {
if (!abilityList.isEmpty()) {
this.addAbilities = abilityList.toArray(new String[0]);
}
if (modList.size() > 0) {
if (!modList.isEmpty()) {
this.skillPointModifiers = modList.toArray(new SkillPointModifier[0]);
}
}
public String getName() {
return name;
}
public String[] getAddAbilities() {
return addAbilities;
}
public int getExtraTalentIndex() {
return extraTalentIndex;
}
public SkillPointModifier[] getSkillPointModifiers() {
return skillPointModifiers;
}
@Getter
public static class SkillPointModifier {
private int skillId;
private int delta;
private final int skillId;
private final int delta;
public SkillPointModifier(int skillId, int delta) {
this.skillId = skillId;
this.delta = delta;
}
public int getSkillId() {
return skillId;
}
public int getDelta() {
return delta;
}
}
}

View File

@ -3,9 +3,10 @@ package emu.grasscutter.data.binout;
import emu.grasscutter.data.common.PointData;
import lombok.Getter;
@Getter
public class ScenePointEntry {
@Getter private final int sceneId;
@Getter private final PointData pointData;
private final int sceneId;
private final PointData pointData;
@Deprecated(forRemoval = true)
public ScenePointEntry(String name, PointData pointData) {

View File

@ -10,7 +10,7 @@ public class TalentData implements Serializable {
ModifySkillCD,
UnlockTalentParam,
AddTalentExtraLevel,
ModifyAbility;
ModifyAbility
}
@SerializedName("$type")

View File

@ -4,13 +4,14 @@ import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
import java.util.List;
import lombok.Getter;
@Getter
public class ConfigLevelEntity {
@Getter private List<ConfigAbilityData> abilities;
@Getter private List<ConfigAbilityData> monsterAbilities;
@Getter private List<ConfigAbilityData> avatarAbilities;
@Getter private List<ConfigAbilityData> teamAbilities;
@Getter private List<Integer> preloadMonsterEntityIDs;
private List<ConfigAbilityData> abilities;
private List<ConfigAbilityData> monsterAbilities;
private List<ConfigAbilityData> avatarAbilities;
private List<ConfigAbilityData> teamAbilities;
private List<Integer> preloadMonsterEntityIDs;
@Getter private String dropElemControlType;
private String dropElemControlType;
}

View File

@ -3,13 +3,14 @@ package emu.grasscutter.data.binout.routes;
// import emu.grasscutter.scripts.constants.IntValueEnum;
import lombok.Getter;
@Getter
public enum RotAngleType /*implements IntValueEnum */ {
ROT_NONE(-1),
ROT_ANGLE_X(0),
ROT_ANGLE_Y(1),
ROT_ANGLE_Z(2);
@Getter private final int id;
private final int id;
RotAngleType(int id) {
this.id = id;

View File

@ -3,13 +3,14 @@ package emu.grasscutter.data.binout.routes;
// import emu.grasscutter.scripts.constants.IntValueEnum;
import lombok.Getter;
@Getter
public enum RouteType /*implements IntValueEnum*/ {
Unknown(-1),
OneWay(0),
Reciprocate(1),
Loop(2);
@Getter private final int id;
private final int id;
RouteType(int id) {
this.id = id;

View File

@ -1,19 +1,10 @@
package emu.grasscutter.data.common;
import lombok.Getter;
@Getter
public class CurveInfo {
private String type;
private String arith;
private float value;
public String getType() {
return type;
}
public String getArith() {
return arith;
}
public float getValue() {
return value;
}
}

View File

@ -92,7 +92,7 @@ public class DynamicFloat {
}
public static class StackOp {
public Op op;
public final Op op;
public float fValue;
public String sValue;

View File

@ -1,24 +1,14 @@
package emu.grasscutter.data.common;
import emu.grasscutter.game.props.FightProperty;
import lombok.Getter;
@Getter
public class FightPropData {
private String propType;
private FightProperty prop;
private float value;
public String getPropType() {
return propType;
}
public float getValue() {
return value;
}
public FightProperty getProp() {
return prop;
}
public void onLoad() {
this.prop = FightProperty.getPropByName(propType);
}

View File

@ -1,8 +1,10 @@
package emu.grasscutter.data.common;
import com.google.gson.annotations.SerializedName;
import lombok.Getter;
// Used in excels
@Getter
public class ItemParamData {
@SerializedName(
value = "id",
@ -21,18 +23,10 @@ public class ItemParamData {
this.count = count;
}
public int getId() {
return id;
}
public int getItemId() {
return id;
}
public int getCount() {
return count;
}
public int getItemCount() {
return count;
}

View File

@ -1,19 +1,14 @@
package emu.grasscutter.data.common;
import lombok.Getter;
@Getter
public class ItemParamStringData {
private int id;
private String count;
public ItemParamStringData() {}
public int getId() {
return id;
}
public String getCount() {
return count;
}
public ItemParamData toItemParamData() {
if (count.contains(";")) {
String[] split = count.split(";");

View File

@ -1,10 +1,11 @@
package emu.grasscutter.data.common;
import emu.grasscutter.game.props.ItemUseOp;
import lombok.Getter;
public class ItemUseData {
private ItemUseOp useOp;
private String[] useParam;
@Getter private String[] useParam;
public ItemUseOp getUseOp() {
if (useOp == null) {
@ -12,8 +13,4 @@ public class ItemUseData {
}
return useOp;
}
public String[] getUseParam() {
return useParam;
}
}

View File

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

View File

@ -1,14 +1,9 @@
package emu.grasscutter.data.common;
import lombok.Getter;
@Getter
public class PropGrowCurve {
private String type;
private String growCurve;
public String getType() {
return this.type;
}
public String getGrowCurve() {
return this.growCurve;
}
}

View File

@ -4,21 +4,22 @@ import emu.grasscutter.data.*;
import emu.grasscutter.data.common.ItemParamData;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Getter;
@ResourceType(name = "CombineExcelConfigData.json")
public class CombineData extends GameResource {
private int combineId;
private int playerLevel;
@Getter private int combineId;
@Getter private int playerLevel;
private boolean isDefaultShow;
private int combineType;
private int subCombineType;
private int resultItemId;
private int resultItemCount;
private int scoinCost;
private List<ItemParamData> randomItems;
private List<ItemParamData> materialItems;
private String recipeType;
@Getter private int combineType;
@Getter private int subCombineType;
@Getter private int resultItemId;
@Getter private int resultItemCount;
@Getter private int scoinCost;
@Getter private List<ItemParamData> randomItems;
@Getter private List<ItemParamData> materialItems;
@Getter private String recipeType;
@Override
public int getId() {
@ -35,47 +36,7 @@ public class CombineData extends GameResource {
materialItems.stream().filter(item -> item.getId() > 0).collect(Collectors.toList());
}
public int getCombineId() {
return combineId;
}
public int getPlayerLevel() {
return playerLevel;
}
public boolean isDefaultShow() {
return isDefaultShow;
}
public int getCombineType() {
return combineType;
}
public int getSubCombineType() {
return subCombineType;
}
public int getResultItemId() {
return resultItemId;
}
public int getResultItemCount() {
return resultItemCount;
}
public int getScoinCost() {
return scoinCost;
}
public List<ItemParamData> getRandomItems() {
return randomItems;
}
public List<ItemParamData> getMaterialItems() {
return materialItems;
}
public String getRecipeType() {
return recipeType;
}
}

View File

@ -2,7 +2,9 @@ package emu.grasscutter.data.excels;
import emu.grasscutter.data.*;
import emu.grasscutter.data.ResourceType.LoadPriority;
import lombok.Getter;
@Getter
@ResourceType(
name = {"CookBonusExcelConfigData.json"},
loadPriority = LoadPriority.LOW)
@ -17,22 +19,6 @@ public class CookBonusData extends GameResource {
return this.avatarId;
}
public int getAvatarId() {
return avatarId;
}
public int getRecipeId() {
return recipeId;
}
public int[] getParamVec() {
return paramVec;
}
public int[] getComplexParamVec() {
return complexParamVec;
}
public int getReplacementItemId() {
return this.paramVec[0];
}

View File

@ -3,13 +3,14 @@ package emu.grasscutter.data.excels;
import emu.grasscutter.data.*;
import emu.grasscutter.data.common.ItemParamData;
import java.util.List;
import lombok.Getter;
@ResourceType(
name = "EnvAnimalGatherExcelConfigData.json",
loadPriority = ResourceType.LoadPriority.LOW)
public class EnvAnimalGatherConfigData extends GameResource {
private int animalId;
private String entityType;
@Getter private int animalId;
@Getter private String entityType;
private List<ItemParamData> gatherItemId;
private String excludeWeathers;
private int aliveTime;
@ -21,15 +22,7 @@ public class EnvAnimalGatherConfigData extends GameResource {
return animalId;
}
public int getAnimalId() {
return animalId;
}
public String getEntityType() {
return entityType;
}
public ItemParamData getGatherItem() {
return gatherItemId.size() > 0 ? gatherItemId.get(0) : null;
return !gatherItemId.isEmpty() ? gatherItemId.get(0) : null;
}
}

View File

@ -3,17 +3,18 @@ package emu.grasscutter.data.excels;
import emu.grasscutter.data.*;
import emu.grasscutter.data.common.FightPropData;
import java.util.ArrayList;
import lombok.Getter;
@ResourceType(name = "EquipAffixExcelConfigData.json")
public class EquipAffixData extends GameResource {
private int affixId;
private int id;
private int level;
private long nameTextMapHash;
private String openConfig;
private FightPropData[] addProps;
private float[] paramList;
@Getter private int level;
@Getter private long nameTextMapHash;
@Getter private String openConfig;
@Getter private FightPropData[] addProps;
@Getter private float[] paramList;
@Override
public int getId() {
@ -24,29 +25,9 @@ public class EquipAffixData extends GameResource {
return id;
}
public int getLevel() {
return level;
}
public long getNameTextMapHash() {
return nameTextMapHash;
}
public String getOpenConfig() {
return openConfig;
}
public FightPropData[] getAddProps() {
return addProps;
}
public float[] getParamList() {
return paramList;
}
@Override
public void onLoad() {
ArrayList<FightPropData> parsed = new ArrayList<FightPropData>(getAddProps().length);
ArrayList<FightPropData> parsed = new ArrayList<>(getAddProps().length);
for (FightPropData prop : getAddProps()) {
if (prop.getPropType() != null && prop.getValue() != 0f) {
prop.onLoad();

View File

@ -2,21 +2,18 @@ package emu.grasscutter.data.excels;
import emu.grasscutter.data.*;
import emu.grasscutter.data.ResourceType.LoadPriority;
import lombok.Getter;
@ResourceType(name = "FetterCharacterCardExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
public class FetterCharacterCardData extends GameResource {
private int avatarId;
private int rewardId;
@Getter private int rewardId;
@Override
public int getId() {
return avatarId;
}
public int getRewardId() {
return rewardId;
}
@Override
public void onLoad() {}
}

View File

@ -4,6 +4,7 @@ import emu.grasscutter.data.*;
import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.common.OpenCondData;
import java.util.List;
import lombok.Getter;
@ResourceType(
name = {
@ -15,7 +16,7 @@ import java.util.List;
},
loadPriority = LoadPriority.HIGHEST)
public class FetterData extends GameResource {
private int avatarId;
@Getter private int avatarId;
private int fetterId;
private List<OpenCondData> openCond;
@ -24,10 +25,6 @@ public class FetterData extends GameResource {
return fetterId;
}
public int getAvatarId() {
return avatarId;
}
public List<OpenCondData> getOpenConds() {
return openCond;
}

View File

@ -1,14 +1,15 @@
package emu.grasscutter.data.excels;
import emu.grasscutter.data.*;
import lombok.Getter;
@ResourceType(name = "GatherExcelConfigData.json")
public class GatherData extends GameResource {
private int pointType;
private int id;
private int gadgetId;
private int itemId;
private int cd; // Probably hours
@Getter private int gadgetId;
@Getter private int itemId;
@Getter private int cd; // Probably hours
private boolean isForbidGuest;
private boolean initDisableInteract;
@ -21,18 +22,6 @@ public class GatherData extends GameResource {
return id;
}
public int getGadgetId() {
return gadgetId;
}
public int getItemId() {
return itemId;
}
public int getCd() {
return cd;
}
public boolean isForbidGuest() {
return isForbidGuest;
}

View File

@ -24,7 +24,7 @@ public class ItemData extends GameResource {
@Getter(onMethod_ = @Override)
private int id;
private int stackLimit = 1;
private final int stackLimit = 1;
private int maxUseCount;
private int rankLevel;
private String effectName;
@ -37,7 +37,7 @@ public class ItemData extends GameResource {
private int[] destroyReturnMaterialCount;
// Enums
private ItemType itemType = ItemType.ITEM_NONE;
private final ItemType itemType = ItemType.ITEM_NONE;
private MaterialType materialType = MaterialType.MATERIAL_NONE;
private EquipType equipType = EquipType.EQUIP_NONE;
private String effectType;
@ -48,10 +48,10 @@ public class ItemData extends GameResource {
private int[] satiationParams;
// Usable item
private ItemUseTarget useTarget = ItemUseTarget.ITEM_USE_TARGET_NONE;
private final ItemUseTarget useTarget = ItemUseTarget.ITEM_USE_TARGET_NONE;
private List<ItemUseData> itemUse;
private List<ItemUseAction> itemUseActions;
private boolean useOnGain = false;
private final boolean useOnGain = false;
// Relic
private int mainPropDepotId;
@ -79,7 +79,7 @@ public class ItemData extends GameResource {
private int comfort;
private List<Integer> furnType;
private List<Integer> furnitureGadgetID;
private SpecialFurnitureType specialFurnitureType = SpecialFurnitureType.NOT_SPECIAL;
private final SpecialFurnitureType specialFurnitureType = SpecialFurnitureType.NOT_SPECIAL;
@SerializedName(
value = "roomSceneId",

View File

@ -39,12 +39,10 @@ public class OpenStateData extends GameResource {
OPEN_STATE_COND_PARENT_QUEST
}
@Getter
public static class OpenStateCond {
@Getter
private OpenStateCondType condType;
@Getter
private int param;
@Getter
private int param2;
}
}

View File

@ -9,7 +9,7 @@ public class PlayerLevelData extends GameResource {
private int level;
private int exp;
private int rewardId;
private int expeditionLimitAdd = 0;
private final int expeditionLimitAdd = 0;
private int unlockWorldLevel;
private long unlockDescTextMapHash;

View File

@ -25,7 +25,8 @@ public class ProudSkillData extends GameResource {
@Getter private long nameTextMapHash;
@Transient private Iterable<ItemParamData> totalCostItems;
@Transient @Getter private Object2FloatMap<String> paramListMap = new Object2FloatOpenHashMap<>();
@Transient @Getter
private final Object2FloatMap<String> paramListMap = new Object2FloatOpenHashMap<>();
@Override
public int getId() {

View File

@ -6,11 +6,12 @@ import emu.grasscutter.game.world.World;
import java.util.*;
import lombok.Getter;
@Getter
@ResourceType(name = "RefreshPolicyExcelConfigData.json")
public class RefreshPolicyExcelConfigData extends GameResource {
@Getter private int id;
@Getter private RefreshType type;
@Getter private String time;
private int id;
private RefreshType type;
private String time;
private static int upperBound(List<Integer> list, int low, int high, int value) {
while (low < high) {
@ -48,9 +49,9 @@ public class RefreshPolicyExcelConfigData extends GameResource {
upperBound(
params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp);
var upper_bound = params.get(upper_bound_idx);
if (params.get(params.size() - 1) == upper_bound) {
if (params.get(params.size() - 1).equals(upper_bound)) {
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
} else if (params.get(0) == upper_bound) {
} else if (params.get(0).equals(upper_bound)) {
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
}
return (params.get(upper_bound_idx - 1) - params.get(0));
@ -64,15 +65,15 @@ public class RefreshPolicyExcelConfigData extends GameResource {
upperBound(
params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp);
var upper_bound = params.get(upper_bound_idx);
if (params.get(params.size() - 1) == upper_bound) {
if (params.get(params.size() - 1).equals(upper_bound)) {
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
} else if (params.get(0) == upper_bound) {
} else if (params.get(0).equals(upper_bound)) {
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
}
return (params.get(upper_bound_idx - 1) - params.get(0));
}
case REFRESH_DAYBEGIN_INTERVAL:
if (params.size() == 0) return -1;
if (params.isEmpty()) return -1;
return params.get(0) * 60 * 60 * 24;
}
} catch (Exception e) {

View File

@ -3,21 +3,18 @@ package emu.grasscutter.data.excels;
import emu.grasscutter.data.*;
import emu.grasscutter.data.common.ItemParamData;
import java.util.List;
import lombok.Getter;
@ResourceType(name = "RewardExcelConfigData.json")
public class RewardData extends GameResource {
public int rewardId;
public List<ItemParamData> rewardItemList;
@Getter public List<ItemParamData> rewardItemList;
@Override
public int getId() {
return rewardId;
}
public List<ItemParamData> getRewardItemList() {
return rewardItemList;
}
@Override
public void onLoad() {
rewardItemList = rewardItemList.stream().filter(i -> i.getId() > 0).toList();

View File

@ -8,7 +8,7 @@ import lombok.Getter;
@ResourceType(name = "RewardPreviewExcelConfigData.json", loadPriority = LoadPriority.HIGH)
public class RewardPreviewData extends GameResource {
@Getter(onMethod_ = @Override)
@Getter(onMethod = @__(@Override))
private int id;
private ItemParamStringData[] previewItems;
@ -25,7 +25,7 @@ public class RewardPreviewData extends GameResource {
Arrays.stream(this.previewItems)
.filter(d -> d.getId() > 0 && d.getCount() != null && !d.getCount().isEmpty())
.map(ItemParamStringData::toItemParamData)
.toArray(size -> new ItemParamData[size]);
.toArray(ItemParamData[]::new);
} else {
this.previewItemsArray = new ItemParamData[0];
}

View File

@ -5,25 +5,27 @@ import emu.grasscutter.data.*;
import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.game.shop.ShopInfo;
import java.util.List;
import lombok.Getter;
@ResourceType(name = "ShopGoodsExcelConfigData.json")
public class ShopGoodsData extends GameResource {
private int goodsId;
private int shopType;
private int itemId;
@Getter private int goodsId;
@Getter private int shopType;
@Getter private int itemId;
private int itemCount;
@Getter private int itemCount;
private int costScoin;
private int costHcoin;
private int costMcoin;
@Getter private int costScoin;
@Getter private int costHcoin;
@Getter private int costMcoin;
private List<ItemParamData> costItems;
private int minPlayerLevel;
private int maxPlayerLevel;
@Getter private List<ItemParamData> costItems;
@Getter private int minPlayerLevel;
@Getter private int maxPlayerLevel;
private int buyLimit;
@Getter private int buyLimit;
@Getter
@SerializedName(
value = "subTabId",
alternate = {"secondarySheetId"})
@ -32,7 +34,7 @@ public class ShopGoodsData extends GameResource {
private String refreshType;
private transient ShopInfo.ShopRefreshType refreshTypeEnum;
private int refreshParam;
@Getter private int refreshParam;
@Override
public void onLoad() {
@ -53,59 +55,7 @@ public class ShopGoodsData extends GameResource {
return getGoodsId();
}
public int getGoodsId() {
return goodsId;
}
public int getShopType() {
return shopType;
}
public int getItemId() {
return itemId;
}
public int getItemCount() {
return itemCount;
}
public int getCostScoin() {
return costScoin;
}
public int getCostHcoin() {
return costHcoin;
}
public int getCostMcoin() {
return costMcoin;
}
public List<ItemParamData> getCostItems() {
return costItems;
}
public int getMinPlayerLevel() {
return minPlayerLevel;
}
public int getMaxPlayerLevel() {
return maxPlayerLevel;
}
public int getBuyLimit() {
return buyLimit;
}
public int getSubTabId() {
return subTabId;
}
public ShopInfo.ShopRefreshType getRefreshType() {
return refreshTypeEnum;
}
public int getRefreshParam() {
return refreshParam;
}
}

View File

@ -4,13 +4,15 @@ import emu.grasscutter.data.*;
import emu.grasscutter.data.common.ItemParamData;
import lombok.*;
@Setter
@Getter
@ResourceType(name = "StatuePromoteExcelConfigData.json")
public class StatuePromoteData extends GameResource {
@Getter @Setter private int level;
@Getter @Setter private int cityId;
@Getter @Setter private ItemParamData[] costItems;
@Getter @Setter private int[] rewardIdList;
@Getter @Setter private int stamina;
private int level;
private int cityId;
private ItemParamData[] costItems;
private int[] rewardIdList;
private int stamina;
@Override
public int getId() {

View File

@ -14,7 +14,7 @@ public class AchievementData extends GameResource {
private static final AtomicBoolean isDivided = new AtomicBoolean();
private int goalId;
private int preStageAchievementId;
private Set<Integer> groupAchievementIdList = new HashSet<>();
private final Set<Integer> groupAchievementIdList = new HashSet<>();
private boolean isParent;
private long titleTextMapHash;
private long descTextMapHash;

View File

@ -15,9 +15,10 @@ public class ActivityCondExcelConfigData extends GameResource {
LogicType condComb;
List<ActivityConfigCondition> cond;
@Getter
public static class ActivityConfigCondition {
@Getter private ActivityConditions type;
@Getter private List<Integer> param;
private ActivityConditions type;
private List<Integer> param;
public int[] paramArray() {
return param.stream().mapToInt(Integer::intValue).toArray();

View File

@ -5,11 +5,12 @@ import emu.grasscutter.game.shop.ShopType;
import java.util.List;
import lombok.Getter;
@Getter
@ResourceType(name = "ActivityShopOverallExcelConfigData.json")
public class ActivityShopData extends GameResource {
@Getter private int scheduleId;
@Getter private ShopType shopType;
@Getter private List<Integer> sheetList;
private int scheduleId;
private ShopType shopType;
private List<Integer> sheetList;
@Override
public int getId() {

View File

@ -2,33 +2,22 @@ package emu.grasscutter.data.excels.avatar;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.*;
import lombok.Getter;
@ResourceType(name = "AvatarCostumeExcelConfigData.json")
public class AvatarCostumeData extends GameResource {
@SerializedName(value = "skinId", alternate = "costumeId")
private int skinId;
private int itemId;
private int characterId;
private int quality;
@Getter private int itemId;
@Getter private int characterId;
@Getter private int quality;
@Override
public int getId() {
return this.skinId;
}
public int getItemId() {
return this.itemId;
}
public int getCharacterId() {
return characterId;
}
public int getQuality() {
return quality;
}
@Override
public void onLoad() {
GameData.getAvatarCostumeDataItemIdMap().put(this.getItemId(), this);

View File

@ -4,10 +4,11 @@ import emu.grasscutter.data.*;
import emu.grasscutter.data.common.CurveInfo;
import java.util.*;
import java.util.stream.Stream;
import lombok.Getter;
@ResourceType(name = "AvatarCurveExcelConfigData.json")
public class AvatarCurveData extends GameResource {
private int level;
@Getter private int level;
private CurveInfo[] curveInfos;
private Map<String, Float> curveInfoMap;
@ -17,10 +18,6 @@ public class AvatarCurveData extends GameResource {
return this.level;
}
public int getLevel() {
return level;
}
public Map<String, Float> getCurveInfos() {
return curveInfoMap;
}

View File

@ -55,7 +55,7 @@ public class AvatarData extends GameResource {
@Getter
private IntList abilities;
@Getter
private List<String> abilitieNames = new ArrayList<>();
private final List<String> abilitieNames = new ArrayList<>();
@Getter
private List<Integer> fetters;

View File

@ -1,21 +1,18 @@
package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.*;
import lombok.Getter;
@ResourceType(name = "AvatarFlycloakExcelConfigData.json")
public class AvatarFlycloakData extends GameResource {
private int flycloakId;
private long nameTextMapHash;
@Getter private long nameTextMapHash;
@Override
public int getId() {
return this.flycloakId;
}
public long getNameTextMapHash() {
return nameTextMapHash;
}
@Override
public void onLoad() {}
}

View File

@ -1,7 +1,9 @@
package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.*;
import lombok.Getter;
@Getter
@ResourceType(name = "AvatarLevelExcelConfigData.json")
public class AvatarLevelData extends GameResource {
private int level;
@ -11,12 +13,4 @@ public class AvatarLevelData extends GameResource {
public int getId() {
return this.level;
}
public int getLevel() {
return level;
}
public int getExp() {
return exp;
}
}

View File

@ -3,51 +3,28 @@ package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.*;
import emu.grasscutter.data.common.*;
import java.util.ArrayList;
import lombok.Getter;
@ResourceType(name = "AvatarPromoteExcelConfigData.json")
public class AvatarPromoteData extends GameResource {
private int avatarPromoteId;
private int promoteLevel;
@Getter private int avatarPromoteId;
@Getter private int promoteLevel;
private int scoinCost;
private ItemParamData[] costItems;
private int unlockMaxLevel;
private FightPropData[] addProps;
private int requiredPlayerLevel;
@Getter private ItemParamData[] costItems;
@Getter private int unlockMaxLevel;
@Getter private FightPropData[] addProps;
@Getter private int requiredPlayerLevel;
@Override
public int getId() {
return (avatarPromoteId << 8) + promoteLevel;
}
public int getAvatarPromoteId() {
return avatarPromoteId;
}
public int getPromoteLevel() {
return promoteLevel;
}
public ItemParamData[] getCostItems() {
return costItems;
}
public int getCoinCost() {
return scoinCost;
}
public FightPropData[] getAddProps() {
return addProps;
}
public int getUnlockMaxLevel() {
return unlockMaxLevel;
}
public int getRequiredPlayerLevel() {
return requiredPlayerLevel;
}
@Override
public void onLoad() {
// Trim item params

View File

@ -52,7 +52,7 @@ public class AvatarSkillDepotData extends GameResource {
this.elementType = ElementType.None;
}
// Set embryo abilities (if player skill depot)
if (getSkillDepotAbilityGroup() != null && getSkillDepotAbilityGroup().length() > 0) {
if (getSkillDepotAbilityGroup() != null && !getSkillDepotAbilityGroup().isEmpty()) {
AvatarConfig config = GameDepot.getPlayerAbilities().get(getSkillDepotAbilityGroup());
if (config != null) {
@ -67,7 +67,7 @@ public class AvatarSkillDepotData extends GameResource {
Optional.ofNullable(this.talents)
.map(talents -> talents.get(0))
.map(i -> GameData.getAvatarTalentDataMap().get((int) i))
.map(talentData -> talentData.getMainCostItemId())
.map(AvatarTalentData::getMainCostItemId)
.ifPresent(itemId -> this.talentCostItemId = itemId);
}

View File

@ -4,18 +4,19 @@ import emu.grasscutter.data.*;
import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.common.FightPropData;
import java.util.ArrayList;
import lombok.Getter;
@ResourceType(name = "AvatarTalentExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
public class AvatarTalentData extends GameResource {
private int talentId;
private int prevTalent;
private long nameTextMapHash;
private String icon;
private int mainCostItemId;
private int mainCostItemCount;
private String openConfig;
private FightPropData[] addProps;
private float[] paramList;
@Getter private long nameTextMapHash;
@Getter private String icon;
@Getter private int mainCostItemId;
@Getter private int mainCostItemCount;
@Getter private String openConfig;
@Getter private FightPropData[] addProps;
@Getter private float[] paramList;
@Override
public int getId() {
@ -26,37 +27,9 @@ public class AvatarTalentData extends GameResource {
return prevTalent;
}
public long getNameTextMapHash() {
return nameTextMapHash;
}
public String getIcon() {
return icon;
}
public int getMainCostItemId() {
return mainCostItemId;
}
public int getMainCostItemCount() {
return mainCostItemCount;
}
public String getOpenConfig() {
return openConfig;
}
public FightPropData[] getAddProps() {
return addProps;
}
public float[] getParamList() {
return paramList;
}
@Override
public void onLoad() {
ArrayList<FightPropData> parsed = new ArrayList<FightPropData>(getAddProps().length);
ArrayList<FightPropData> parsed = new ArrayList<>(getAddProps().length);
for (FightPropData prop : getAddProps()) {
if (prop.getPropType() != null || prop.getValue() == 0f) {
prop.onLoad();

View File

@ -1,25 +1,15 @@
package emu.grasscutter.data.excels.codex;
import emu.grasscutter.data.*;
import lombok.Getter;
@Getter
@ResourceType(name = {"MaterialCodexExcelConfigData.json"})
public class CodexMaterialData extends GameResource {
private int Id;
private int materialId;
private int sortOrder;
public int getSortOrder() {
return sortOrder;
}
public int getMaterialId() {
return materialId;
}
public int getId() {
return Id;
}
@Override
public void onLoad() {
GameData.getCodexMaterialDataIdMap().put(this.getMaterialId(), this);

View File

@ -1,31 +1,16 @@
package emu.grasscutter.data.excels.codex;
import emu.grasscutter.data.*;
import lombok.Getter;
@ResourceType(name = {"QuestCodexExcelConfigData.json"})
public class CodexQuestData extends GameResource {
private int Id;
private int parentQuestId;
private int chapterId;
private int sortOrder;
@Getter private int Id;
@Getter private int parentQuestId;
@Getter private int chapterId;
@Getter private int sortOrder;
private boolean isDisuse;
public int getParentQuestId() {
return parentQuestId;
}
public int getId() {
return Id;
}
public int getChapterId() {
return chapterId;
}
public int getSortOrder() {
return sortOrder;
}
public boolean getIsDisuse() {
return isDisuse;
}

View File

@ -1,30 +1,19 @@
package emu.grasscutter.data.excels.codex;
import emu.grasscutter.data.*;
import lombok.Getter;
@ResourceType(name = {"WeaponCodexExcelConfigData.json"})
public class CodexWeaponData extends GameResource {
private int Id;
private int weaponId;
@Getter private int Id;
@Getter private int weaponId;
private int gadgetId;
private int sortOrder;
public int getSortOrder() {
return sortOrder;
}
public int getWeaponId() {
return weaponId;
}
@Getter private int sortOrder;
public int getGadgetId() {
return weaponId;
}
public int getId() {
return Id;
}
@Override
public void onLoad() {
GameData.getCodexWeaponDataIdMap().put(this.getWeaponId(), this);

View File

@ -9,7 +9,7 @@ import lombok.Getter;
@Getter
@ResourceType(name = "DungeonChallengeConfigData.json")
public class DungeonChallengeConfigData extends GameResource {
private int id;
@Getter private int id;
private ChallengeType challengeType;
private boolean noSuccessHint;
private boolean noFailHint;
@ -42,10 +42,6 @@ public class DungeonChallengeConfigData extends GameResource {
alternate = {"NJBJIKAIENN"})
private AllowAnimationType animationOnSubFail;
public int getId() {
return id;
}
public enum InterruptButtonType {
INTERRUPT_BUTTON_TYPE_NONE,
INTERRUPT_BUTTON_TYPE_HOST,

View File

@ -6,15 +6,17 @@ import emu.grasscutter.game.quest.enums.LogicType;
import java.util.List;
import lombok.*;
@Getter
@ResourceType(name = "DungeonPassExcelConfigData.json")
public class DungeonPassConfigData extends GameResource {
@Getter private int id;
@Getter private LogicType logicType;
@Getter @Setter private List<DungeonPassCondition> conds;
private int id;
private LogicType logicType;
@Setter private List<DungeonPassCondition> conds;
@Getter
public static class DungeonPassCondition {
@Getter private DungeonPassConditionType condType;
@Getter int[] param;
private DungeonPassConditionType condType;
int[] param;
}
@Override

View File

@ -11,32 +11,32 @@ import javax.annotation.*;
import lombok.*;
import lombok.experimental.FieldDefaults;
@ResourceType(name = "QuestExcelConfigData.json")
@Getter
@ResourceType(name = "QuestExcelConfigData.json")
@ToString
public class QuestData extends GameResource {
@Getter private int subId;
@Getter private int mainId;
@Getter private int order;
@Getter private long descTextMapHash;
private int subId;
private int mainId;
private int order;
private long descTextMapHash;
@Getter private boolean finishParent;
@Getter private boolean isRewind;
private boolean finishParent;
private boolean isRewind;
@Getter private LogicType acceptCondComb;
@Getter private LogicType finishCondComb;
@Getter private LogicType failCondComb;
private LogicType acceptCondComb;
private LogicType finishCondComb;
private LogicType failCondComb;
@Getter private List<QuestAcceptCondition> acceptCond;
@Getter private List<QuestContentCondition> finishCond;
@Getter private List<QuestContentCondition> failCond;
@Getter private List<QuestExecParam> beginExec;
@Getter private List<QuestExecParam> finishExec;
@Getter private List<QuestExecParam> failExec;
@Getter private Guide guide;
private List<QuestAcceptCondition> acceptCond;
private List<QuestContentCondition> finishCond;
private List<QuestContentCondition> failCond;
private List<QuestExecParam> beginExec;
private List<QuestExecParam> finishExec;
private List<QuestExecParam> failExec;
private Guide guide;
@Getter private List<Integer> trialAvatarList;
@Getter private List<ItemParamData> gainItems;
private List<Integer> trialAvatarList;
private List<ItemParamData> gainItems;
public static String questConditionKey(
@Nonnull Enum<?> type, int firstParam, @Nullable String paramsStr) {

View File

@ -8,7 +8,7 @@ import lombok.Getter;
@ResourceType(name = "ReliquaryMainPropExcelConfigData.json")
@Getter
public class ReliquaryMainPropData extends GameResource {
@Getter(onMethod_ = @Override)
@Getter(onMethod = @__(@Override))
private int id;
private int propDepotId;

View File

@ -2,12 +2,14 @@ package emu.grasscutter.data.excels.reliquary;
import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.*;
import lombok.Getter;
@ResourceType(name = "ReliquarySetExcelConfigData.json")
public class ReliquarySetData extends GameResource {
private int setId;
private int[] setNeedNum;
@Getter private int[] setNeedNum;
@Getter
@SerializedName(
value = "equipAffixId",
alternate = {"EquipAffixId"})
@ -18,14 +20,6 @@ public class ReliquarySetData extends GameResource {
return setId;
}
public int[] getSetNeedNum() {
return setNeedNum;
}
public int getEquipAffixId() {
return equipAffixId;
}
@Override
public void onLoad() {}
}

View File

@ -9,7 +9,7 @@ import lombok.Getter;
@ResourceType(name = "SceneExcelConfigData.json")
@Getter
public final class SceneData extends GameResource {
@Getter(onMethod_ = @Override)
@Getter(onMethod = @__(@Override))
private int id;
@SerializedName("type")

View File

@ -8,7 +8,7 @@ import lombok.Getter;
@ResourceType(name = "SceneTagConfigData.json")
@Getter
public final class SceneTagData extends GameResource {
@Getter(onMethod_ = @Override)
@Getter(onMethod = @__(@Override))
private int id;
@SerializedName("DJCOAOBDIHP")

View File

@ -30,8 +30,8 @@ public class TowerLevelData extends GameResource {
// Just packaging condition parameters for convenience.
@Getter
public class TowerCondTimeParams {
private int param1;
private int minimumTimeInSeconds;
private final int param1;
private final int minimumTimeInSeconds;
public TowerCondTimeParams(int param1, int minimumTimeInSeconds) {
this.param1 = param1;
@ -41,9 +41,9 @@ public class TowerLevelData extends GameResource {
@Getter
public class TowerCondHpParams {
private int sceneId;
private int configId;
private int minimumHpPercentage;
private final int sceneId;
private final int configId;
private final int minimumHpPercentage;
public TowerCondHpParams(int sceneId, int configId, int minimumHpPercentage) {
this.sceneId = sceneId;

View File

@ -2,7 +2,9 @@ package emu.grasscutter.data.excels.tower;
import emu.grasscutter.data.*;
import java.util.List;
import lombok.Getter;
@Getter
@ResourceType(name = "TowerScheduleExcelConfigData.json")
public class TowerScheduleData extends GameResource {
private int scheduleId;
@ -19,30 +21,11 @@ public class TowerScheduleData extends GameResource {
public void onLoad() {
super.onLoad();
this.schedules =
this.schedules.stream().filter(item -> item.getFloorList().size() > 0).toList();
}
public int getScheduleId() {
return scheduleId;
}
public List<Integer> getEntranceFloorId() {
return entranceFloorId;
}
public List<ScheduleDetail> getSchedules() {
return schedules;
}
public int getMonthlyLevelConfigId() {
return monthlyLevelConfigId;
this.schedules.stream().filter(item -> !item.getFloorList().isEmpty()).toList();
}
@Getter
public static class ScheduleDetail {
private List<Integer> floorList;
public List<Integer> getFloorList() {
return floorList;
}
}
}

View File

@ -10,7 +10,7 @@ import lombok.experimental.FieldDefaults;
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TrialAvatarActivityDataData extends GameResource {
@Getter(onMethod_ = @Override)
@Getter(onMethod = @__({@Override}))
private int id;
private int trialAvatarIndexId;

View File

@ -1,7 +1,9 @@
package emu.grasscutter.data.excels.weapon;
import emu.grasscutter.data.*;
import lombok.Getter;
@Getter
@ResourceType(name = "WeaponLevelExcelConfigData.json")
public class WeaponLevelData extends GameResource {
private int level;
@ -11,12 +13,4 @@ public class WeaponLevelData extends GameResource {
public int getId() {
return this.level;
}
public int getLevel() {
return level;
}
public int[] getRequiredExps() {
return requiredExps;
}
}

View File

@ -3,7 +3,9 @@ package emu.grasscutter.data.excels.weapon;
import emu.grasscutter.data.*;
import emu.grasscutter.data.common.*;
import java.util.ArrayList;
import lombok.Getter;
@Getter
@ResourceType(name = "WeaponPromoteExcelConfigData.json")
public class WeaponPromoteData extends GameResource {
@ -20,34 +22,6 @@ public class WeaponPromoteData extends GameResource {
return (weaponPromoteId << 8) + promoteLevel;
}
public int getWeaponPromoteId() {
return weaponPromoteId;
}
public int getPromoteLevel() {
return promoteLevel;
}
public ItemParamData[] getCostItems() {
return costItems;
}
public int getCoinCost() {
return coinCost;
}
public FightPropData[] getAddProps() {
return addProps;
}
public int getUnlockMaxLevel() {
return unlockMaxLevel;
}
public int getRequiredPlayerLevel() {
return requiredPlayerLevel;
}
@Override
public void onLoad() {
// Trim item params

View File

@ -4,19 +4,20 @@ import emu.grasscutter.data.*;
import emu.grasscutter.game.props.ClimateType;
import lombok.Getter;
@Getter
@ResourceType(name = "WeatherExcelConfigData.json")
public class WeatherData extends GameResource {
@Getter private int areaID;
@Getter private int weatherAreaId;
@Getter private String maxHeightStr;
@Getter private int gadgetID;
@Getter private boolean isDefaultValid;
@Getter private String templateName;
@Getter private int priority;
@Getter private String profileName;
@Getter private ClimateType defaultClimate;
@Getter private boolean isUseDefault;
@Getter private int sceneID;
private int areaID;
private int weatherAreaId;
private String maxHeightStr;
private int gadgetID;
private boolean isDefaultValid;
private String templateName;
private int priority;
private String profileName;
private ClimateType defaultClimate;
private boolean isUseDefault;
private int sceneID;
@Override
public int getId() {

View File

@ -1,21 +1,18 @@
package emu.grasscutter.data.excels.world;
import emu.grasscutter.data.*;
import lombok.Getter;
@ResourceType(name = "WorldLevelExcelConfigData.json")
public class WorldLevelData extends GameResource {
private int level;
private int monsterLevel;
@Getter private int monsterLevel;
@Override
public int getId() {
return this.level;
}
public int getMonsterLevel() {
return monsterLevel;
}
@Override
public void onLoad() {}
}

View File

@ -6,12 +6,18 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.world.*;
import emu.grasscutter.scripts.SceneIndexManager;
import java.util.*;
import lombok.Getter;
public class Grid {
public transient RTree<Map.Entry<GridPosition, Set<Integer>>, Geometry> gridOptimized = null;
private transient Set<Integer> nearbyGroups = new HashSet<>(100);
private final transient Set<Integer> nearbyGroups = new HashSet<>(100);
public Map<GridPosition, Set<Integer>> grid = new LinkedHashMap<>();
/**
* -- GETTER --
*
* @return The correctly loaded grid map.
*/
@Getter public Map<GridPosition, Set<Integer>> grid = new LinkedHashMap<>();
/** Creates an optimized cache of the grid. */
private void optimize() {
@ -23,13 +29,6 @@ public class Grid {
}
}
/**
* @return The correctly loaded grid map.
*/
public Map<GridPosition, Set<Integer>> getGrid() {
return this.grid;
}
public Set<Integer> getNearbyGroups(int vision_level, Position position) {
this.optimize(); // Check to see if the grid is optimized.

View File

@ -550,7 +550,7 @@ public final class DatabaseHelper {
.first();
} catch (IllegalArgumentException e) {
Grasscutter.getLogger()
.debug("Error occurred while getting uid " + uid + "'s achievement data", e);
.debug("Error occurred while getting uid {}'s achievement data", uid, e);
DatabaseManager.getGameDatabase().getCollection("achievements").deleteMany(eq("uid", uid));
return null;
}

View File

@ -11,15 +11,12 @@ import dev.morphia.query.experimental.filters.Filters;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerRunMode;
import emu.grasscutter.game.Account;
import lombok.Getter;
public final class DatabaseManager {
private static Datastore gameDatastore;
@Getter private static Datastore gameDatastore;
private static Datastore dispatchDatastore;
public static Datastore getGameDatastore() {
return gameDatastore;
}
public static Datastore getAccountDatastore() {
if (Grasscutter.getRunMode() == ServerRunMode.HYBRID) return gameDatastore;
else return dispatchDatastore;

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