180 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
76fd5b2e9c Update README_ja-JP.md (#2516) 2024-06-05 21:14:11 -04:00
4022267888 Configuration Update - Shown Email (#2509)
* This version will allow the private server owner to show a different email then "@grasscutter.io" if they want.

* Update src/main/java/emu/grasscutter/config/ConfigContainer.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

* Update src/main/java/emu/grasscutter/game/Account.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

* Update src/main/java/emu/grasscutter/game/Account.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2024-05-13 21:58:46 -04:00
f1f5b54939 (fix:docker) Fix uploading to container registry 2024-03-16 23:09:40 -07:00
f871f261e1 Add Docker Support (#2486)
* chore(docker): add build workflow

* chore(docker): update gradle image

* chore(docker): this really shouldnt be running on raspberry pi's right now.

* chore(docker): not sure why we need unzip here

* chore(docker): attempt to add nodejs to allow the handbook to build

* chore(docker): whoops, needs to be done during build

* chore(docker): i dont know if this is going to work

* chore(docker): replace my username with repo org as I am no longer testing this

* chore(docker): version will change in the future, so fix it now.
2024-03-17 01:57:39 -04:00
eeaccf32c4 add some client download link and fix readme (#2475)
* Update README.md

* Update README_zh-CN.md

* Update README_hn-IN.md
2024-03-17 01:14:10 -04:00
6e1913aacb Add documentation on 404 error page. (#2463)
* Update HttpServer.java

* Update HttpServer.java

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2024-01-18 23:30:03 -05:00
9e17e4aacb Update client link (#2470) 2024-01-18 23:15:13 -05:00
770a793c69 Format code [skip actions] 2023-12-14 05:36:30 +00:00
c4402cc287 Fix some more dungeons (#2449)
* Monds weapon mats domain: Fix time between kill not refreshing
* Inaz husk domain: Fix broken domain challenge
    * `EVENT_ANY_MONSTER_LIVE` is likely sent on tick, not on create. See scene40801_group240801001.lua:
        1. `condition_EVENT_ANY_MONSTER_LIVE_1023` checks for mob 1008 to spawn AND for variable `challenge` to be 1
        2. Mob 1008 spawns during `action_EVENT_SELECT_OPTION_1003`, at `ScriptLib.AddExtraGroupSuite(context, 240801001, 2)`
        3. This spawn triggers `EVENT_ANY_MONSTER_LIVE` for mob 1008 but still fails the condition because `challenge` is still 0.
        4. `challenge` is set to 1 at the end of `action_EVENT_SELECT_OPTION_1003`. By now, `EVENT_ANY_MONSTER_LIVE` for mob 1008 no longer fires, causing the domain challenge to fail to start.
2023-12-14 00:34:50 -05:00
5ebad71e9d Bump to version 1.7.4 2023-11-30 23:41:55 -05:00
564b609028 Update README_ja-JP.md (#2438)
* Update README_ja-JP.md

* fix sentences correctly
2023-11-19 19:34:14 -05:00
cdb0dc560a Format code [skip actions] 2023-11-17 04:58:02 +00:00
d8c3da8fcd Handle mob summon and limbo state (#2432)
Mob summon: Something like Monster_Apparatus_Perpetual can summon helper mobs. Ensure these helpers actually get summoned and, on their defeat, possibly change the summoner's mob state. Like, temporarily enter weak state.
* Take summon tags from BinOutput/Monster/ConfigMonster_*.json and put them in SceneMonsterInfo
* Handle Summon action in ability modifiers from BinOutput/Ability/Temp/MonsterAbilities/ConfigAbility_Monster_*.json
* On summoner's kill, also kill the summoned mobs

Limbo state: Something like Monster_Invoker_Herald_Water should be invulnerable at a certain HP threshold. Like, shouldn't die when creating their elemental shield. Or, Monster_Apparatus_Perpetual's helper mobs shouldn't die before their summoner.
* Look through ConfigAbility (AbilityData in GC) like Invoker_Herald_Water_StateControl. If any AbilityModifier within specifies state Limbo and properties.Actor_HpThresholdRatio, account for this threshold in GameEntity::damage.
* Don't let the entity die while in limbo. They will be killed by other events.
2023-11-16 23:56:37 -05:00
13c40b53a7 Format code [skip actions] 2023-11-10 02:57:50 +00:00
f1c1a84683 fix: NPE related to teapot when player logs in. (#2429)
* fix: NPE related to home when player logs in.

* fix: NPE related to home when player logs in.

* forgot to save player after fixing module id
2023-11-09 21:56:21 -05:00
2bcbd41026 Format code [skip actions] 2023-11-09 02:16:38 +00:00
adf8031684 Fix a typo from "culivation" to "cultivation" in readme EN, zh-CN, zh-TW (#2431)
* fix a singular typo in readme.md

fixed "culivation" to cultivation

* Update README_zh-CN.md

culivation to cultivation

* Update zh-TW to fix "culivation"

Cultivation from culivaton
2023-11-08 21:15:57 -05:00
0bbeaf254b Fix tower mob level and hp scaling (#2430) 2023-11-08 21:15:10 -05:00
1fac319eb2 Format code [skip actions] 2023-11-05 19:58:28 +00:00
d224178a64 Only deduct energy when elemental burst actually fires (#2424) 2023-11-05 14:57:17 -05:00
d461ee2eb3 Format code [skip actions] 2023-11-03 02:02:24 +00:00
24874e7fba Implement abyss defense objective (#2422) 2023-11-02 22:00:05 -04:00
205b79dc02 Merge remote-tracking branch 'origin/development' into development 2023-10-31 22:36:22 -04:00
0e033e3f77 Bump to version 1.7.3 2023-10-31 22:23:45 -04:00
583a41ab2c Format code [skip actions] 2023-11-01 01:54:08 +00:00
cf6fb275be Add events to support scene group substitution (#2413)
* Add events to support scene group substitution

* make event members private with getter/setter

* delete stray unused var
2023-10-31 21:52:01 -04:00
269f7b4fbf Fix typo in start.cmd (#2415)
enviroment -> environment
2023-10-31 19:50:31 -04:00
9b4ce34f4a Format code [skip actions] 2023-10-26 02:29:17 +00:00
f86259a430 Fix some revives; improve dungeon exit flow (#2409) 2023-10-25 22:27:48 -04:00
837e30e04b Format code [skip actions] 2023-10-19 13:19:46 +00:00
f5703e5964 Fix mirror tower stages; fix tower time challenge and star scoring (#2406) 2023-10-19 09:18:12 -04:00
bc8e7c21ce Format code [skip actions] 2023-10-17 05:42:17 +00:00
b7a9d28f02 Fix reset tag without notification (#2405) 2023-10-17 01:41:24 -04:00
770cd62370 Fix daily dungeon flow (#2398)
* Fix dungeon entry, daily changes, replay flow; fix Mond's weapon mats domain unlock

* add note to DungeonEntryToBeExploreNotify
2023-10-17 01:41:04 -04:00
6745d1126e Format code [skip actions] 2023-10-14 16:11:33 +00:00
0803618bf5 Format code [skip actions] 2023-10-14 16:10:31 +00:00
cfc8a4866f Add reset scene tag subcommand (#2403)
* Add reset scene tag subcommand

* Fix Control Flow
2023-10-14 12:10:16 -04:00
fd75ba7b9b Fix triggered Monster Tide spawn; fix Tower dungeon handoff (#2397)
* Abyss: Fix monster tide trigger; fix dungeon handoff

* back out unrelated changes
2023-10-14 12:08:49 -04:00
d32a75e980 Fix setPrevScene bug (#2396) 2023-10-07 00:40:36 -04:00
9a198bd231 Alphabetize and Format ScriptLib.java (#2395)
I deeply apologize to anyone who is trying to find the history of the code from before today.
2023-10-07 00:40:15 -04:00
453dc9717d Format code [skip actions] 2023-10-02 14:58:22 +00:00
582d7af9c4 Send QUEST_COND_STATE_NOT_EQUAL and QUEST_COND_STATE_EQUAL on login (#2394) 2023-10-02 10:56:09 -04:00
cab3bfb5a7 Fix bug in quest cond state not equal (#2393)
* Fix bug in ConditionStateNotEqual.java

* Do the same fix for ConditionStateEqual.java
2023-10-02 03:25:35 -04:00
cf574e99cb Format code [skip actions] 2023-10-01 05:41:41 +00:00
3094facb88 Bump to version 1.7.2 2023-09-30 23:16:35 -04:00
6e309b6fee Merge remote-tracking branch 'origin/development' into development 2023-09-30 23:15:50 -04:00
b5e35f5409 Add legacy documentation on Hide and Seek 2023-09-30 18:10:10 -04:00
a3fd10c3be Fix NullPointerException when refilling an avatar with no skill depot 2023-09-30 18:09:40 -04:00
b6e7d69949 Send QUEST_COND_NONE on every login (#2386)
For players that enabled questing late
2023-09-25 19:30:33 -04:00
5faf39d359 Format code [skip actions] 2023-09-23 17:45:57 +00:00
0dd95450b1 Bare-bones Hangouts implementation (#2384) 2023-09-23 13:44:31 -04:00
0f0e7aca68 use pretty_host in domain filtering (#2382) 2023-09-22 23:33:01 -04:00
5ee4812ac5 fix: login too slow (#2380) 2023-09-20 21:23:08 -04:00
ec2bfffdd1 Format code [skip actions] 2023-09-18 01:03:10 +00:00
7f5059cb8f Format code [skip actions] 2023-09-18 01:03:02 +00:00
43db7eba8f tp to move directly in the same scene (#2375) 2023-09-17 21:01:21 -04:00
ff6a51db30 Update position parameters to support rotation-based offsets (#2374) 2023-09-17 21:00:58 -04:00
047feaf4aa Format code [skip actions] 2023-09-17 02:57:50 +00:00
88315ec712 Format code [skip actions] 2023-09-17 02:57:38 +00:00
fdad4218e7 Fix freeze on startup (#2368)
* DON'T load resources in static init!!!

* Update src/main/java/emu/grasscutter/Grasscutter.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

* Update src/main/java/emu/grasscutter/tools/Tools.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2023-09-16 22:55:46 -04:00
5f5e6c38b1 Add rotation to /spawn (#2372) 2023-09-16 22:55:25 -04:00
92bd09eeed Format code [skip actions] 2023-09-16 23:00:20 +00:00
30f7580184 Merge remote-tracking branch 'origin/development' into development 2023-09-16 18:59:02 -04:00
65eaaa96f2 Apply changes from #2310 2023-09-16 18:58:36 -04:00
70a961e167 Format code [skip actions] 2023-09-16 22:44:16 +00:00
dd78addc29 Fix ability modifier serialization 2023-09-16 18:36:16 -04:00
43467ebc85 Factor fight properties into healing calculation 2023-09-16 18:32:01 -04:00
1f15d6219b Format code [skip actions] 2023-09-16 21:40:49 +00:00
fb0c2dbc84 Merge pull request #2341
* enableRandomEncryptSeed

* update config version

* Merge branch 'Grasscutters:development' into random-seed

* make the codes more beautiful

* move KahnsSort to algorithms

* rename variables

* Merge branch 'development' into random-seed
2023-09-16 14:38:39 -07:00
b8f7aea168 Format code [skip actions] 2023-09-16 21:33:36 +00:00
cf8092e8ba Update languages [skip actions] 2023-09-16 21:32:21 +00:00
0e44d18ae9 Better SceneTags (#2361)
* Add scene tag handling

* Move warns to debug

* Move to PlayerProgressManager

* Add success message

* Inline check

* Improve per-scene handling

* Update src/main/java/emu/grasscutter/command/commands/SetSceneTagCommand.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

* Update src/main/java/emu/grasscutter/command/commands/SetSceneTagCommand.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

* Fix types

* Small fix

* Update ScriptLib.java

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2023-09-16 17:31:59 -04:00
5bd8f532c1 i forgot to add ` 2023-09-16 17:23:54 -04:00
ad62b6b11d Format code [skip actions] 2023-09-16 00:53:28 +00:00
c9a43a5e98 Format code [skip actions] 2023-09-16 00:52:37 +00:00
5458d36102 fix: HomeModuleManager isnt ticked unless player changes module (#2365) 2023-09-15 20:51:16 -04:00
c4dbb6851b Implement passJumpDungeon. Make dungeons kick you out to the correct scene (#2366) 2023-09-15 20:50:56 -04:00
2643c6b3b7 Format code [skip actions] 2023-09-15 00:45:41 +00:00
84e1371499 Fixes for alchemy dude's quest part 2 (#2362)
* Make platforms able to reset

platforms apparently are able to run again once reaching the last point. As well, canceling a timer seems to return a 0, not a 1

* Fix Seelies

Added HandlerClientScriptEventNotify (shoutouts to Hartie!) and cleaned up the platform stuff in ScriptLib.

There is a problem with HandlerClientScriptEventNotify where the client seems to only pass 0 into param1 instead of the configId. I coded in a workaround, but someone with greater access to things should check up on what is going on
2023-09-14 20:44:30 -04:00
f955bb1e16 Little update to item giving handling (#2363)
* Little update to HandlerItemGivingReq.java

GIVING_METHOD_GROUP is used in cooking girl's quest

* Send the giving packet at the start of relogs, even if encountered before.

* Make item checking not exact

You can have more items in your inventory than what you are submitting.
2023-09-14 20:44:08 -04:00
2b64814534 fix: home worlds are ticked twice (#2360) 2023-09-14 01:22:29 -04:00
ea5ee075a7 Merge remote-tracking branch 'origin/development' into development 2023-09-13 21:03:44 -04:00
6108a3bb37 Handbook documentation & build flow fixes 2023-09-13 21:03:32 -04:00
98a83b649e Add more precise instructions for the handbook (#2359)
* Add more precise instructions for the handbook

* Reformat Building section
2023-09-13 21:02:20 -04:00
4f62e484ad Update ru-RU.json (#2356)
translation & typo
2023-09-12 11:56:31 -04:00
5fd31aece8 Fix home nulls (#2355)
* Add null checking

* Sanity check for moduleManager
2023-09-12 01:07:17 -04:00
8de281d4da Format code [skip actions] 2023-09-10 23:21:44 +00:00
fbe2b138ee Fixes for alchemy dude's quest (#2352)
* Add drops for gadgets

Gadgets only have drop_id when they are not chests (chest_drop_id). When drop_id is not set (0), handleChestDrop quickly exits

* Implement QUEST_COND_ITEM_GIVING_FINISHED

Took the oppertunity to Rename ContentFinishGivingItem to ItemGiving

* Store accept conditions like fail and finish content are

Took the oppertunity to clean up some old code as well

conditions are stored in QuestManager

* Update src/main/java/emu/grasscutter/game/quest/QuestManager.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

* Update ConditionItemGivingFinished.java

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2023-09-10 19:20:28 -04:00
47c96fd964 Regular ScriptLib update! (#2349)
* Regular ScriptLib update!

* Move RefreshGroup down to debug

* Update SetGadgetEnableInteract
2023-09-09 20:49:22 -04:00
04370f1a21 Update CN README to game REL 4.0 (#2350) 2023-09-09 20:48:32 -04:00
7845c54570 Format code [skip actions] 2023-09-09 03:07:29 +00:00
818b638bed Added Hindi Language Support (#2347)
* Added Hindi Language Support 

Please review the code

* Update README_HE.md

* Update README_NL.md

* Update README_es-ES.md

* Update README_fil-PH.md

* Update README_fr-FR.md

* Update README_id-ID.md

* Update README_it-IT.md

* Update README_ja-JP.md

* Update README_ko-KR.md

* Update README_pl-PL.md

* Update README_ru-RU.md

* Update README_vi-VN.md

* Update README_zh-CN.md

* Update README_zh-TW.md
2023-09-08 23:07:18 -04:00
a9402f487f Implement RegionShape.POLYGON and RegionShape.CYLINDER (#2348)
Also took the opportunity to sort them in order and use multiplication instead of pow.
2023-09-08 23:06:14 -04:00
cdcdf924bd Format code [skip actions] 2023-09-08 03:35:28 +00:00
fc42f665a7 feat: implement teapot suite (#2344)
* feat: implement teapot suite

* fix: home animals, check respawn, etc

* fix: NPE and cancel summon events

* fix: forgot to send eventId also
2023-09-07 23:34:03 -04:00
83602f78ae Update readme to 4.0 from 3.7 (#2343) 2023-09-07 23:33:13 -04:00
8db1f597ce Format code [skip actions] 2023-09-02 23:51:35 +00:00
c08ab19d84 Various removals of '&' for Javadoc to be happy 2023-09-02 19:49:38 -04:00
34589d0128 Merge remote-tracking branch 'origin/development' into development 2023-09-02 19:48:39 -04:00
70ee3ed1a6 Remove protocol definitions from Javadoc generation 2023-09-02 19:31:58 -04:00
88d7be86da Format code [skip actions] 2023-09-02 23:06:00 +00:00
d6abb2288d Bump version to v1.7.1 2023-09-02 19:05:34 -04:00
416ef56101 Bump down the plugin API version
nothing major was *removed*, meaning all existing v2 plugins should still work
2023-09-02 19:05:30 -04:00
ed0e89074b Merge remote-tracking branch 'origin/development' into development 2023-09-02 19:04:09 -04:00
1894296ed4 fix: home transfer (#2327)
* fix: home transfer

* Update HomeSceneItem.java
2023-09-02 19:04:02 -04:00
69a223949b Merge remote-tracking branch 'origin/development' into development 2023-09-02 19:02:41 -04:00
f8fb6732de Format code [skip actions] 2023-09-02 15:55:11 +00:00
ed97201473 fix: arrangement of main house is duplicated even if player changes module (#2325)
* fix: arrangement of main house is duplicated even if player change module

* removeIf

* Update src/main/java/emu/grasscutter/game/home/GameHome.java

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2023-09-02 11:52:56 -04:00
decf494234 Format code [skip actions] 2023-09-02 05:49:00 +00:00
9c25060c78 Format code [skip actions] 2023-09-02 05:48:12 +00:00
a49f37edb3 feat: finish home avatar talk (#2328) 2023-09-02 01:47:06 -04:00
97138d8c84 feat: implement home animals (#2329) 2023-09-02 01:46:58 -04:00
314bccb7a2 Add command description for debug 2023-09-01 20:50:37 -04:00
c1045103ed Format code [skip actions] 2023-09-02 00:37:43 +00:00
1831d5c81f SerializedName MonsterSpecialName (#2331)
* SerializedName MonsterSpecialName

* uh add space back

* remove space

---------

Co-authored-by: Magix <27646710+KingRainbow44@users.noreply.github.com>
2023-09-01 20:35:54 -04:00
717a358636 Format code [skip actions] 2023-09-02 00:33:12 +00:00
0db69882a3 fix: sync home avatar costume (#2326) 2023-09-01 20:31:55 -04:00
12da46b5ee Re-order troubleshooting info 2023-09-01 20:29:25 -04:00
850 changed files with 9653 additions and 6831 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 runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v3 uses: actions/setup-java@v4
with: with:
distribution: temurin distribution: temurin
java-version: '17' java-version: '17'
@ -44,7 +44,7 @@ jobs:
- name: Run Gradle - name: Run Gradle
run: ./gradlew -PskipHandbook=1 && ./gradlew jar -PskipHandbook=1 run: ./gradlew -PskipHandbook=1 && ./gradlew jar -PskipHandbook=1
- name: Upload build - name: Upload build
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: Grasscutter name: Grasscutter
path: grasscutter-*.jar path: grasscutter-*.jar

51
.github/workflows/build_container.yml vendored Normal file
View File

@ -0,0 +1,51 @@
name: Build Docker Container
on:
push:
release:
types: [published]
workflow_dispatch: ~
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout Project
uses: actions/checkout@v4
- name: Generate Docker Meta
uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3.1.0
- name: Login to GitHub Container Registry
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Docker image
uses: docker/build-push-action@v5.2.0
with:
context: .
push: true
platforms: linux/amd64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

1
.gitignore vendored
View File

@ -64,6 +64,7 @@ tmp/
/*.jar /*.jar
/*.sh /*.sh
!entrypoint.sh
GM Handbook*.txt GM Handbook*.txt
handbook.html handbook.html

38
Dockerfile Normal file
View File

@ -0,0 +1,38 @@
# Builder
FROM gradle:jdk17-alpine as builder
RUN apk add --update nodejs npm
WORKDIR /app
COPY ./ /app/
RUN gradle jar --no-daemon
# Fetch Data
FROM bitnami/git:2.43.0-debian-11-r1 as data
ARG DATA_REPOSITORY=https://gitlab.com/YuukiPS/GC-Resources.git
ARG DATA_BRANCH=4.0
WORKDIR /app
RUN git clone --branch ${DATA_BRANCH} --depth 1 ${DATA_REPOSITORY}
# Result Container
FROM amazoncorretto:17-alpine
WORKDIR /app
# Copy built assets
COPY --from=builder /app/grasscutter-*.jar /app/grasscutter.jar
COPY --from=builder /app/keystore.p12 /app/keystore.p12
# Copy the resources
COPY --from=data /app/GC-Resources/Resources /app/resources/
# Copy startup files
COPY ./entrypoint.sh /app/
CMD [ "sh", "/app/entrypoint.sh" ]
EXPOSE 80 443 8888 22102

View File

@ -24,12 +24,14 @@
### Quick Start (automatic) ### Quick Start (automatic)
- Get Java 17: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html - Get [Java 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
- Get [MongoDB Community Server](https://www.mongodb.com/try/download/community) - Get [MongoDB Community Server](https://www.mongodb.com/try/download/community)
- Get game version REL3.7 (3.7 client can be found here if you don't have it): https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md - 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)
- Download the [latest Cultivation version](https://github.com/Grasscutters/Cultivation/releases/latest). Use the `.msi` installer. - Download the [latest Cultivation version](https://github.com/Grasscutters/Cultivation/releases/latest). Use the `.msi` installer.
- After opening Culivation (as admin), press the download button in the upper right corner. - After opening Cultivation (as admin), press the download button in the upper right corner.
- Click `Download All-in-One` - Click `Download All-in-One`
- Click the gear in the upper right corner - Click the gear in the upper right corner
- Set the game Install path to where your game is located. - Set the game Install path to where your game is located.
@ -38,7 +40,7 @@
- Click the small button next to launch. - Click the small button next to launch.
- Click the launch button. - Click the launch button.
- Log in with whatever username you want. Password doesn't matter. - Log in with whatever username you want. Password can be anything.
### Building ### Building
@ -46,25 +48,49 @@ Grasscutter uses Gradle to handle dependencies & building.
**Requirements:** **Requirements:**
- [Java SE Development Kits - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) or higher - [Java Development Kit 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) or higher
- [Git](https://git-scm.com/downloads) - [Git](https://git-scm.com/downloads)
- [NodeJS](https://nodejs.org/en/download) (Optional, for building the handbook)
##### Windows ##### Clone
```shell ```shell
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter cd Grasscutter
.\gradlew.bat # Setting up environments
.\gradlew jar # Compile
``` ```
##### Linux (GNU) ##### Compile
**Note**: Handbook generation may fail on some systems. To disable the handbook generation, append `-PskipHandbook=1` to the `gradlew jar` command.
Windows:
```shell
.\gradlew.bat # Setting up environments
.\gradlew jar
```
Linux (GNU):
```bash ```bash
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
chmod +x gradlew chmod +x gradlew
./gradlew jar # Compile ./gradlew jar
```
##### Compiling the Handbook (Manually)
With Gradle:
```shell
./gradlew generateHandbook
```
With NPM:
```shell
cd src/handbook
npm install
npm run build
``` ```
You can find the output jar in the root of the project folder. You can find the output jar in the root of the project folder.

View File

@ -58,7 +58,7 @@ sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
group = 'io.grasscutter' group = 'io.grasscutter'
version = '1.7.0' version = '1.7.4'
java { java {
withJavadocJar() withJavadocJar()
@ -82,7 +82,7 @@ dependencies {
// Line reading libraries. // Line reading libraries.
implementation group: 'org.jline', name: 'jline', version: '3.21.0' 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' implementation group: 'net.java.dev.jna', name: 'jna', version: '5.10.0'
// Java Netty for networking. // Java Netty for networking.
@ -96,7 +96,7 @@ dependencies {
implementation group: 'com.google.protobuf', name: 'protobuf-java', version: '3.19.6' 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 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' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.2'
// Reflections libraries. // Reflections libraries.
@ -130,7 +130,7 @@ dependencies {
// Testing libraries. // Testing libraries.
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.2' 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-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. // HTTP client library for testing.
testImplementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.10.0' testImplementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.10.0'
@ -261,7 +261,7 @@ clean {
protobuf { protobuf {
protoc { protoc {
// The artifact spec for the Protobuf Compiler // 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/" generatedFilesBaseDir = "$projectDir/src/generated/"
@ -311,6 +311,8 @@ javadoc {
// Add this to avoid warning caused by lack of comments in proto generated java files // Add this to avoid warning caused by lack of comments in proto generated java files
options.addStringOption('Xdoclint:none', '-quiet') options.addStringOption('Xdoclint:none', '-quiet')
exclude '**/*.md' exclude '**/*.md'
exclude 'src/handbook/**/*.*'
exclude 'src/generated/**/*.*'
} }
tasks.register('injectGitHash') { tasks.register('injectGitHash') {
@ -384,6 +386,12 @@ tasks.register('generateHandbook') {
return return
} }
// Install dependencies before building.
exec {
workingDir 'src/handbook'
commandLine npm, 'install'
}
// Build the handbook. // Build the handbook.
exec { exec {
workingDir 'src/handbook' workingDir 'src/handbook'

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**תשומת לב בבקשה:** אנחנו מקבלים עזרה בפיתוח התוכנה. לפני שאתם תורמים לפרויקט בבקשה תקראו את [תנאי השימוש](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md). **תשומת לב בבקשה:** אנחנו מקבלים עזרה בפיתוח התוכנה. לפני שאתם תורמים לפרויקט בבקשה תקראו את [תנאי השימוש](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**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. **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.

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Atención:** Siempre damos la bienvenida a contribuidores del proyecto. Antes de añadir tu contribución, por favor lee cuidadosamente nuestro [Código de conducta](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md). **Atención:** Siempre damos la bienvenida a contribuidores del proyecto. Antes de añadir tu contribución, por favor lee cuidadosamente nuestro [Código de conducta](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Atensyon:** Ang mga kontributor ay laging welcome sa proyektong ito. Bago mag-bigay ng kontribusyon, basahin muna ng mabuti ang [Code of Conduct](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md). **Atensyon:** Ang mga kontributor ay laging welcome sa proyektong ito. Bago mag-bigay ng kontribusyon, basahin muna ng mabuti ang [Code of Conduct](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Attention:** De nouveaux contributeurs sont toujours les bienvenus. Avant d'ajouter votre contribution, veuillez lire le [code de conduite](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md). **Attention:** De nouveaux contributeurs sont toujours les bienvenus. Avant d'ajouter votre contribution, veuillez lire le [code de conduite](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).

78
docs/README_hn-IN.md Normal file
View File

@ -0,0 +1,78 @@
![Grasscutter](https://socialify.git.ci/Grasscutters/Grasscutter/image?description=1&forks=1&issues=1&language=1&logo=https%3A%2F%2Fs2.loli.net%2F2022%2F04%2F25%2FxOiJn7lCdcT5Mw1.png&name=1&owner=1&pulls=1&stargazers=1&theme=Light)
<div align="center"><img alt="Documentation" src="https://img.shields.io/badge/Wiki-Grasscutter-blue?style=for-the-badge&link=https://github.com/Grasscutters/Grasscutter/wiki&link=https://github.com/Grasscutters/Grasscutter/wiki"> <img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Grasscutters/Grasscutter?logo=java&style=for-the-badge"> <img alt="GitHub" src="https://img.shields.io/github/license/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/Grasscutters/Grasscutter?style=for-the-badge"> <img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Grasscutters/Grasscutter/build.yml?branch=development&logo=github&style=for-the-badge"></div>
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[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)
**ध्यान:** हम हमेशा परियोजना में योगदानकर्ताओं का स्वागत करते हैं।. अपना योगदान जोड़ने से पहले कृपया हमारा ध्यानपूर्वक पढ़ें [आचार संहिता](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).
## वर्तमान सुविधाएँ
* लॉग इन करना
* युद्ध
* मित्रों की सूची
* टेलीपोर्टेशन
* गाचा प्रणाली
* सह-ऑप * आंशिक रूप से * काम करता है
* कंसोल के माध्यम से राक्षसों को जन्म देना
* इन्वेंट्री सुविधाएँ (आइटम / वर्ण प्राप्त करना, आइटम / वर्णों को अपग्रेड करना, आदि)
## त्वरित सेटअप गाइड
**टिप्पणी**: समर्थन के लिए कृपया हमसे जुड़ें [Discord](https://discord.gg/T5vZU6UyeG).
### त्वरित प्रारंभ (स्वचालित)
- Get Java 17: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
**ध्यान दें:** बस **सर्वर शुरू करने** के लिए, आपको बस **jre** की आवश्यकता है।
- Get [MongoDB Community Server](https://www.mongodb.com/try/download/community)
* प्रॉक्सी: मिटमडंप (अनुशंसित), मिटमप्रॉक्सी, फिडलर क्लासिक, आदि।
- गेम संस्करण REL3.7 प्राप्त करें (यदि आपके पास 3.7 क्लाइंट नहीं है तो उसे यहां पाया जा सकता है):: https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md
- डाउनलोड करें [latest Cultivation version](https://github.com/Grasscutters/Cultivation/releases/latest). उपयोग `.msi` इंस्टालरr.
- कलिवेशन (एडमिन के रूप में) खोलने के बाद, ऊपरी दाएं कोने में डाउनलोड बटन दबाएं।
- `डाउनलोड ऑल-इन-वन` पर क्लिक करें
- ऊपरी दाएं कोने में गियर पर क्लिक करें
- गेम इंस्टॉल पथ को उस स्थान पर सेट करें जहां आपका गेम स्थित है.
- कस्टम जावा पथ को इस पर सेट करें `C:\Program Files\Java\jdk-17\bin\java.exe`
- अन्य सभी सेटिंग्स को डिफ़ॉल्ट पर छोड़ दें
- लॉन्च करने के लिए आगे छोटे बटन पर क्लिक करें.
- लॉन्च बटन पर क्लिक करें.
- आप जो भी उपयोगकर्ता नाम चाहते हैं उसके साथ लॉग इन करें। पासवर्ड कोई मायने नहीं रखता.
### इमारत
ग्रासकटर निर्भरता और निर्माण को संभालने के लिए ग्रैडल का उपयोग करता है।
**आवश्यकताएं:**
- [Java SE Development Kits - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) or higher
- [Git](https://git-scm.com/downloads)
##### विंडोज
```shell
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
.\gradlew.bat # Setting up environments
.\gradlew jar # Compile
```
##### लिनक्स (जीएनयू)
```bash
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
chmod +x gradlew
./gradlew jar # Compile
```
आप आउटपुट जार को प्रोजेक्ट फ़ोल्डर के रूट में पा सकते हैं।.
### समस्या निवारण
सामान्य मुद्दों और समाधानों की सूची और सहायता मांगने के लिए कृपया शामिल हों [our Discord server](https://discord.gg/T5vZU6UyeG) और सपोर्ट चैनल पर जाएं.

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Perhatian:** Kami selalu menyambut kontributor untuk proyek ini. Sebelum menambahkan kontribusi Anda, harap baca [Kode Etik](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) kami. **Perhatian:** Kami selalu menyambut kontributor untuk proyek ini. Sebelum menambahkan kontribusi Anda, harap baca [Kode Etik](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) kami.

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Attenzione:** Diamo sempre il benvenuto ai contributori del progetto. Prima di contribuire, leggi attentamente il nostro [Codice di condotta](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md). **Attenzione:** Diamo sempre il benvenuto ai contributori del progetto. Prima di contribuire, leggi attentamente il nostro [Codice di condotta](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).

View File

@ -3,81 +3,64 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [HI](README_hn-IN.md)
**:** 私たちはプロジェクトへの貢献者をいつでも歓迎します。貢献を追加する前に、我々の [行動規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)をよくお読みください。 **Attention:** 私たちはプロジェクトへのコントリビュータをいつでも歓迎します。コントリビュートする前に、私たちの [行動規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)をよくお読みください。
## 現在機能している ## 現在実装されている機能
* ログイン * ログイン
* 戦闘 * 戦闘
* フレンドリスト * フレンドリスト
* テレポート * テレポート
* 祈願(ガチャ) * 祈願 (ガチャ)
* マルチプレイは一部機能しています * マルチプレイ (一部)
* コンソールを使用してモンスタースポーンさせる * コンソールを通したモンスタースポーン
* インベントリ機能 (アイテム/キャラクターの受け取り、アイテム/キャラクターのアップグレードなど) * インベントリ機能 (アイテム/キャラクターの受け取り、アイテム/キャラクターのアップグレードなど)
## クイックセットアップガイド ## かんたんセットアップガイド
**:** サポートが必要な場合はGrasscutterの[Discord](https://discord.gg/T5vZU6UyeG)に参加してください。 **Note:** サポートが必要な場合はGrasscutterの[Discordサーバー](https://discord.gg/T5vZU6UyeG)に参加してください。
### 動作環境 ### パパっとスタートアップ
* [JAVAのバージョン17以降](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) - [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のクライアントを持っていない場合は右のリンクからダウンロード): [Github](https://github.com/JRSKelvin/GenshinRepository/blob/main/Version%204.0.0.md), [クラウド(123云盘)](https://www.123pan.com/s/HoqUVv-U7SBA.html)
- [最新の Cultivation](https://github.com/Grasscutters/Cultivation/releases/latest)をダウンロードする。`.msi`インストーラを使ってください。
- 管理者権限を付与して Cultivation を実行した後、右上端にあるダウンロードアイコンのボタンを押す。
- `Download All-in-One` をクリックする
- 右上端にある歯車アイコンのボタンをクリックする。
- `Game Install Path` にゲームファイルのパスを指定する。
- `Custom Java Path` に、自分が用意したJavaのパスを指定する。 (例: `C:\Program Files\Java\jdk-17\bin\java.exe`)
- その他の設定には手を付けず次の段階に進む。
- Launch の隣にある小さいボタンを押す。
- Launchボタンを押す
- 好きなユーザ名でログインする。ログインに関する設定がデフォルトの場合、パスワードは何を入れてもいい。
**:** サーバーを動作させるだけならjreのみで十分です。 開発をしたい場合JDKが必要になるかもしれません。
* [MongoDB](https://www.mongodb.com/try/download/community) (バージョン4.0以降を推奨)
* プロキシツール: [mitmproxy](https://mitmproxy.org/) (mitmdump, 推奨)、[Fiddler Classic](https://telerik-fiddler.s3.amazonaws.com/fiddler/FiddlerSetup.exe)、その他。
### 起動方法
**:** もしサーバーをアップデートしたい場合は`config.json`を削除してから再生成してください。
1. `grasscutter.jar`を入手する
- [releases](https://github.com/Grasscutters/Grasscutter/releases/latest) か [action](https://github.com/Grasscutters/Grasscutter/actions) からダウンロードするか、[自分でビルド](#ビルド)してください。
2. `grasscutter.jar` があるディレクトリに `resources` フォルダーを作成し、そこに `BinOutput, ExcelBinOutput, Readables, Scripts, Subtitle, TextMap` を移動してください *(`resources` フォルダの中身の入手方法については [wiki](https://github.com/Grasscutters/Grasscutter/wiki) を参照してください.)*
3. コマンドプロンプトに`java -jar grasscutter.jar`を入力しGrasscutterを起動してください。**このときMongoDBも実行する必要があります。**
### クライアントとの接続
½. [このコマンド](https://github.com/Grasscutters/Grasscutter/wiki/Commands#commands-for-server-admins)をサーバーコンソールから使用してアカウントを作成してください。
1. 通信内容をリダイレクトする: (どちらか一つを選択してください)
- mitmdump: `mitmdump -s proxy.py -k`
- CA証明書を信頼する:
- **:** CA証明書は`%USERPROFILE%\.mitmproxy`に保存されています。ダブルクリックして[インストール](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を起動し(Tools -> Options -> HTTPS)から`Decrypt https traffic`をオンにしてください。 (Tools -> Options -> Connections) に有るポート番号の設定を`8888`以外に設定してください。その後この[スクリプト](https://github.com/Grasscutters/Grasscutter/wiki/Resources#fiddler-classic-jscript)をFiddlerScriptタブにコピペしてロードします。
- [ホストファイル](https://github.com/Grasscutters/Grasscutter/wiki/Resources#hosts-file)
2. ネットワークプロキシを `127.0.0.1:(自分で設定したポート番号)` に設定してください。
- mitmproxyを使用した場合プロキシの設定と証明書のインストールが終わった後、http://mitm.it/ でトラフィックがmitmproxyを通過しているか確認しましょう。
**`start.cmd`でmitmdumpとサーバーをまとめて起動することが出来ます。ただ、事前に`start_config.cmd`でJAVAのパスを指定している必要があります。**
### ビルド ### ビルド
GrasscutterはGradleを使用して依存関係とビルド処理しています。 Grasscutterは依存関係とビルド処理にGradleを使用しています。
**要件:** **必要要件:**
- [Java SE Development Kits - 17以降](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) - [Java SE Development Kit 17以降](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
- [Git](https://git-scm.com/downloads) - [Git](https://git-scm.com/downloads)
- [NodeJS](https://nodejs.org/en/download) (任意、ハンドブックの生成に必要)
##### Windows ##### Clone
```shell
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
cd Grasscutter
```
##### Compile
**Note:** 環境によってはハンドブックの生成が失敗する場合があります。ハンドブックの生成をさせない場合は `gradlew jar` コマンドに `-PskipHandbook=1` を付け加えてください。
Windows:
```shell ```shell
git clone https://github.com/Grasscutters/Grasscutter.git git clone https://github.com/Grasscutters/Grasscutter.git
@ -86,7 +69,7 @@ cd Grasscutter
.\gradlew jar # コンパイル .\gradlew jar # コンパイル
``` ```
##### Linux Linux:
```bash ```bash
git clone https://github.com/Grasscutters/Grasscutter.git git clone https://github.com/Grasscutters/Grasscutter.git
@ -95,13 +78,23 @@ chmod +x gradlew
./gradlew jar # コンパイル ./gradlew jar # コンパイル
``` ```
生成されたjarファイルはプロジェクトフォルダのルートに有ります。 ##### 手動によるハンドブックの生成
### コマンドリストは[wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)へ移動しました。 Gradleを使用する場合:
```shell
./gradlew generateHandbook
```
# トラブルシューティング NPMを使用する場合:
```shell
cd src/handbook
npm install
npm run build
```
* コンパイルが失敗した場合JDKがインストールされているか確認してください。(JDKのバージョンが17以降であることと、環境変数でJDKのパスが設定されている必要があります)
* クライアントが接続できない・ログインできない・エラーコード4206・またその他場合、ほとんどは、プロキシデーモンの設定が問題です。Fiddlerを使っている場合はデフォルトポートを8888以外の別のポートに変更してみてください 生成されたjarファイルはプロジェクトのルートフォルダにあります
Fiddlerを使用している場合はポートが8888以外に設定されていることを確認してください。
* 起動シーケンス(順番): MongoDB > Grasscutter > プロキシツール (mitmdumpかfiddler、その他) > ゲーム ### トラブルシューティング
よく散見されるトラブルとそれに対する解決策のまとめリストや、質問し誰かの助けを得たい場合は、Grasscutterの[Discordサーバー](https://discord.gg/T5vZU6UyeG)に参加し、サポートチャンネルを参照してください。

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**주의 :** 우리는 항상 프로젝트에 기여하는 사람들을 환영합니다. 기여를 하기 전, [행동 지침](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)을 주의 깊게 읽어주세요. **주의 :** 우리는 항상 프로젝트에 기여하는 사람들을 환영합니다. 기여를 하기 전, [행동 지침](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)을 주의 깊게 읽어주세요.

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Uwaga:** Zawsze jesteśmy otwarci na wasz wkład w projekt. Przed zaproponowaniem zmian przeczytaj [zasady postępowania (ENG)](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md). **Uwaga:** Zawsze jesteśmy otwarci na wasz wkład w projekt. Przed zaproponowaniem zmian przeczytaj [zasady postępowania (ENG)](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Внимание:** Мы всегда рады новому вкладу в проект. Однако, перед тем, как сделать свой вклад, пожалуйста, прочтите наш [кодекс делового поведения](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md). **Внимание:** Мы всегда рады новому вкладу в проект. Однако, перед тем, как сделать свой вклад, пожалуйста, прочтите наш [кодекс делового поведения](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md).

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**Chú ý:** Chúng tôi luôn chào đón những người đóng góp cho dự án. Trước khi đóng góp, xin vui lòng đọc kỹ ["các quy tắc" (Code of Conduct)](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) của chúng tôi . **Chú ý:** Chúng tôi luôn chào đón những người đóng góp cho dự án. Trước khi đóng góp, xin vui lòng đọc kỹ ["các quy tắc" (Code of Conduct)](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md) của chúng tôi .

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**注意:** 我们始终欢迎项目的贡献者。但在做贡献之前,请仔细阅读我们的[代码规范](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。 **注意:** 我们始终欢迎项目的贡献者。但在做贡献之前,请仔细阅读我们的[代码规范](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。
@ -26,10 +26,12 @@
- 获取Java 17https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html - 获取Java 17https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
- 获取[MongoDB社区版](https://www.mongodb.com/try/download/community) - 获取[MongoDB社区版](https://www.mongodb.com/try/download/community)
- 获取游戏3.7正式版 (如果你没有3.7的客户端,可以在这里找到):https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md) - 获取游戏4.0正式版 (如果你没有4.0的客户端,可以在这里找到):
[123pan share](https://www.123pan.com/s/HoqUVv-U7SBA.html)
[github](https://github.com/JRSKelvin/GenshinRepository/blob/main/Version%204.0.0.md)
- 下载[最新的Cultivation版本](https://github.com/Grasscutters/Cultivation/releases/latest)(使用以“.msi”为后缀的安装包 - 下载[最新的Cultivation版本](https://github.com/Grasscutters/Cultivation/releases/latest)(使用以“.msi”为后缀的安装包
- 以管理员身份打开Culivation按右上角的下载按钮。 - 以管理员身份打开Cultivation按右上角的下载按钮。
- 点击“下载 Grasscutter 一体化” - 点击“下载 Grasscutter 一体化”
- 点击右上角的齿轮 - 点击右上角的齿轮
- 将游戏安装路径设置为你游戏所在的位置。 - 将游戏安装路径设置为你游戏所在的位置。

View File

@ -3,7 +3,7 @@
<div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div> <div align="center"><a href="https://discord.gg/T5vZU6UyeG"><img alt="Discord - Grasscutter" src="https://img.shields.io/discord/965284035985305680?label=Discord&logo=discord&style=for-the-badge"></a></div>
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) [EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md) | [हिंदी](README_hn-IN.md)
**請注意:** 歡迎成為本專案的貢獻者。在提交 PR 之前, 請仔細閱讀[程式碼規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。 **請注意:** 歡迎成為本專案的貢獻者。在提交 PR 之前, 請仔細閱讀[程式碼規範](https://github.com/Grasscutters/Grasscutter/blob/stable/CONTRIBUTING.md)。
@ -29,7 +29,7 @@
- 下載遊戲版本 REL3.7(如果你沒有的話,可以在[這裡](https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md)找到 3.7 客戶端) - 下載遊戲版本 REL3.7(如果你沒有的話,可以在[這裡](https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md)找到 3.7 客戶端)
- 下載 [最新的 Cultivation 版本](https://github.com/Grasscutters/Cultivation/releases/latest)。使用 `.msi` 安裝程式。 - 下載 [最新的 Cultivation 版本](https://github.com/Grasscutters/Cultivation/releases/latest)。使用 `.msi` 安裝程式。
- 以管理員身分打開 Culivation按右上角的下載按鈕。 - 以管理員身分打開 Cultivation按右上角的下載按鈕。
- 點擊 `Download All-in-One` - 點擊 `Download All-in-One`
- 點擊右上角的齒輪 - 點擊右上角的齒輪
- 將遊戲安裝路徑設置為你的遊戲所在的位置。 - 將遊戲安裝路徑設置為你的遊戲所在的位置。

View File

@ -0,0 +1,188 @@
# Hide and Seek!
Documentation on how the **Hide and Seek** game works.\
Externally dubbed: `Windtrace`.
# Map IDs
TODO: Document the map IDs of Windtrace.
TODO: Investigate `ServerGlobalValueChangeNotify`
# Asking Players to Play in a Co-Op Game
1. The client will send `DraftOwnerStartInviteReq`
2. The server will send `DraftOwnerInviteNotify` to all clients.
3. The server will send `DraftOwnerStartInviteRsp`
# Matching in a Co-Op Game
1. World owner talks to Gygax and begins a Windtrace game.
2. The packet `DraftOwnerInviteNotify` is sent to clients.
3. Clients will respond with `DraftGuestReplyInviteReq` (client-side)
4. The server will respond with `DraftGuestReplyInviteRsp`
5. The server will respond with `DraftInviteResultNotify`
# Starting Windtrace
1. If `DraftInviteResultNotify` is a success, the server will send a series of packets.
1. A series of `SceneEntityAppearNotify` packets.
2. `NpcTalkStateNotify`
3. `PlayerEnterSceneNotify`
4. `MultistagePlayInfoNotify`
2. The players are then teleported to the Windtrace map in their locations.
3. Server will send packets to clients. (this is server boilerplate)
4. The server sends another `MultistagePlayInfoNotify` to clients.
# Changing Avatars - Others
1. The server will send a `AvatarEquipChangeNotify` packet to clients.
2. The server will send a `SceneTeamUpdateNotify` packet to clients.
3. The server will send a `HideAndSeekPlayerSetAvatarNotify` packet to clients.
# Getting Ready
1. The client will send `HideAndSeekSetReadyReq` to the server.
2. The server will reply with `HideAndSeekPlayerReadyNotify` to clients.
3. The server will send `MultistagePlayInfoNotify` to clients.
4. The server will reply with `HideAndSeekSetReadyRsp` to the client.
5. If all players are ready, the server will move on to start Windtrace.
# Starting Windtrace
1. When all players are ready, the server will send a series of packets to players.
1. `GalleryStartNotify`
2. `SceneGalleryInfoNotify`
3. `MultistagePlayInfoNotify`
4. `MultistagePlayStageEndNotify`
5. This will only get sent at the `1.` countdown.
### Notes:
- `GuestReplyInviteRsp` is sent **after** `DraftInviteResultNotify`.
## `DraftOwnerInviteNotify`
- `invite_deadline_time` - This is the time when the invite expires.
- `draft_id` - The value is always `3001` for Windtrace.
## `DraftOwnerStartInviteReq`
- `draft_id` - The value is always `3001` for Windtrace.
## `DraftOwnerStartInviteRsp`
- `draft_id` - The value is always `3001` for Windtrace.
- `invite_fail_info_list` - A list of players who weren't invited.
- `retcode` - The response code.
- `wrong_uid` - Always `0`. (undocumented)
## `DraftGuestReplyInviteReq`
- `draft_id` - The value is always `3001` for Windtrace.
- `is_agree` - A boolean value for whether the client accepts the invite.
## `DraftGuestReplyInviteRsp`
- `draft_id` - The value is always `3001` for Windtrace.
- `retcode` - Response code for the request.
- `is_agree` - A boolean value for whether the server acknowledges the client's invite acceptation.
## `DraftInviteResultNotify`
- `draft_id` - The value is always `3001` for Windtrace.
- `is_all_agree` - A boolean value for whether all clients accepted the invite.
## `NpcTalkStateNotify`
- `is_ban` - This value is always true when entering Windtrace.
## `PlayerEnterSceneNotify`
- `pos` - This is where the player will be teleported to.
- This value depends on if the player is a hunter or a runner.
- This value is set by the server and must be hardcoded/read from a JSON file.
## `MultistagePlayStageEndNotify`
- `play_index` - Value picked by the server. (use 1)
- `group_id` - This value is always `133002121` for Windtrace.
## `MultistagePlayInfoNotify` - Initial + PostEnterSceneReq
- Image Reference: ![img.png](images/multistageplayinfo.png)
- `info` - MultistagePlayInfo data.
- `group_id` - The value is always `133002121` for Windtrace.
- `play_index` - Value picked by the server. (use 1)
- `hide_and_seek_info` - Information about Windtrace.
- `hider_uid_list` - A list of UIDs (ints) of the hiders.
- `hunter_uid` - The UID (int) of the hunter.
- `map_id` - The ID of the Windtrace map.
- `stage_type` - Windtrace state.
- This will be `HIDE_AND_SEEK_STAGE_TYPE_PREPARE`.
- `battle_info_map` - Contains a dictionary of UID -> `HideAndSeekPlayerBattleInfo` objects.
- `skill_list` - Array of 3 values of skill IDs chosen by the player.
- `avatar_id` - The ID of the avatar the player wants to use.
- `is_ready` - The player's in-game ready state.
- `costume_id` - The costume the player's avatar is wearing.
## `MultistagePlayInfoNotify` - Picking Avatars
- Image Reference: ![img.png](images/pickavatar.png)
- **Note:** This packet matches the initial structure and data.
- `info.hide_and_seek_info.stage_type` - This will be `HIDE_AND_SEEK_STAGE_TYPE_PICK`.
## `MultistagePlayInfoNotify` - Starting Windtrace
- Image Reference: ![img.png](images/startwindtrace.png)
- **Note:** This packet matches the initial structure and data.
- `info.hide_and_seek_info.stage_type` - This will be `HIDE_AND_SEEK_STAGE_TYPE_HIDE`.
## `MultistagePlayInfoNotify` - Seeking Time
- Image Reference: ![img.png](images/seektime.png)
- **Note:** This packet matches the initial structure and data.
- `info.hide_and_seek_info.stage_type` - This will be `HIDE_AND_SEEK_STAGE_TYPE_SEEK`.
## `MultistagePlayInfoNotify` - Finish Windtrace
- Image Reference: ![img.png](images/seektime.png)
- **Note:** This packet matches the initial structure and data.
- `info.hide_and_seek_info.stage_type` - This will be `HIDE_AND_SEEK_STAGE_TYPE_SETTLE`.
## `HideAndSeekPlayerSetAvatarNotify`
- `avatar_id` - The ID of the new avatar the player wants to use.
- `uid` - The UID of the player who changed their avatar.
- `costume_id` - The costume the player's avatar is wearing.
## `HideAndSeekSetReadyRsp`
- `retcode` - Response code for the request.
## `HideAndSeekPlayerReadyNotify`
- `uid_list` - A list of UIDs (ints) of the players who are ready.
## `GalleryStartNotify`
- `gallery_id` - TODO: Check if this value is always `7056` for Windtrace.
- `start_time` - This value is always `2444` for Windtrace.
- This value is `200` when displaying game end statistics.
- `owner_uid` - The UID of the player who started the Windtrace game.
- `player_count` - The number of players in the Windtrace game.
- `end_time` - This value is always the same as `start_time`.
## `SceneGalleryInfoNotify` - Starting Windtrace
- `gallery_info` - SceneGalleryInfo data.
- `end_time` - This value is always the same as `start_time`.
- `start_time` - This value is always `2444` for Windtrace.
- This value is `200` when displaying game end statistics.
- `gallery_id` - This value is always the same as `gallery_id` from `GalleryStartNotify`.
- `stage` - The current stage of the gallery.
- This will be `GALLERY_STAGE_TYPE_START`.
- `owner_uid` - The UID of the player who started the Windtrace game.
- `hide_and_seek_info` - SceneGalleryHideAndSeekInfo
- `visible_uid_list` - List of UIDs (ints) of the players who were left alive.
- `caught_uid_list` - List of UIDs (ints) of the players who have been caught.
- `player_count` - The amount of players in the Windtrace game.
- `pre_start_end_time` - This value is always `0` for Windtrace.
## `HideAndSeekSettleNotify`
- `reason` - The reason for the game ending.
- `winner_list` - A list of UIDs (ints) of the players who won the game.
- `settle_info_list` - HideAndSeekSettleInfo data.
- This is a list of players who participated in the game.
## `HideAndSeekSettleInfo`
- `card_list` - A collection of `ExhibitionDisplayInfo`
- If unknown: hardcode the specified values. ![img.png](images/defaultexhibitioninfo.png)
- These values are repeated during testing.
- `uid` - The UID of the player who participated in the game.
- `nickname` - The player's nickname.
- `head_image` - This value is always `0`.
- `online_id` - This value is always blank.
- `profile_picture` - `ProfilePicture` object.
- `play_index` - Value picked by the server. (use 1)
- `stage_type` - The stage type. (inconclusive; TODO)
- `cost_time` - The amount of time the player took to complete the game.
- `score_list` - A list of player scores.
## `ExhibitionDisplayInfo`
- `id` - The ID of the reward.
- `param` - The amount of the reward given.
- `detail_param` - This value is *mostly* 0.
- This value **matches** param when the reward is of the amount of time spent playing. (participation reward)

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

3
entrypoint.sh Normal file
View File

@ -0,0 +1,3 @@
#/bin/sh
java -jar /app/grasscutter.jar

View File

@ -68,7 +68,7 @@ class MlgmXyysd_Animation_Company_Proxy:
] ]
def request(self, flow: http.HTTPFlow) -> None: def request(self, flow: http.HTTPFlow) -> None:
if flow.request.host in self.LIST_DOMAINS: if flow.request.pretty_host in self.LIST_DOMAINS:
if USE_SSL: if USE_SSL:
flow.request.scheme = "https" flow.request.scheme = "https"
else: else:

View File

@ -36,21 +36,21 @@ public final class HomePlantSubFieldDataOuterClass {
int getEntityIdList(int index); int getEntityIdList(int index);
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @return The enum numeric value on the wire for cAKDDMKAIMD. * @return The enum numeric value on the wire for status.
*/ */
int getCAKDDMKAIMDValue(); int getStatusValue();
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @return The cAKDDMKAIMD. * @return The status.
*/ */
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getCAKDDMKAIMD(); emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getStatus();
/** /**
* <code>uint32 JHFNDBIHLNB = 8;</code> * <code>uint32 seed_id = 8;</code>
* @return The jHFNDBIHLNB. * @return The seedId.
*/ */
int getJHFNDBIHLNB(); int getSeedId();
/** /**
* <code>fixed32 end_time = 14;</code> * <code>fixed32 end_time = 14;</code>
@ -59,10 +59,10 @@ public final class HomePlantSubFieldDataOuterClass {
int getEndTime(); int getEndTime();
/** /**
* <code>uint32 KHFGOPCOAGM = 3;</code> * <code>uint32 gather_point_type = 3;</code>
* @return The kHFGOPCOAGM. * @return The gatherPointType.
*/ */
int getKHFGOPCOAGM(); int getGatherPointType();
} }
/** /**
* <pre> * <pre>
@ -82,7 +82,7 @@ public final class HomePlantSubFieldDataOuterClass {
} }
private HomePlantSubFieldData() { private HomePlantSubFieldData() {
entityIdList_ = emptyIntList(); entityIdList_ = emptyIntList();
cAKDDMKAIMD_ = 0; status_ = 0;
} }
@java.lang.Override @java.lang.Override
@ -118,7 +118,7 @@ public final class HomePlantSubFieldDataOuterClass {
break; break;
case 24: { case 24: {
kHFGOPCOAGM_ = input.readUInt32(); gatherPointType_ = input.readUInt32();
break; break;
} }
case 48: { case 48: {
@ -145,12 +145,12 @@ public final class HomePlantSubFieldDataOuterClass {
case 56: { case 56: {
int rawValue = input.readEnum(); int rawValue = input.readEnum();
cAKDDMKAIMD_ = rawValue; status_ = rawValue;
break; break;
} }
case 64: { case 64: {
jHFNDBIHLNB_ = input.readUInt32(); seedId_ = input.readUInt32();
break; break;
} }
case 117: { case 117: {
@ -221,34 +221,34 @@ public final class HomePlantSubFieldDataOuterClass {
} }
private int entityIdListMemoizedSerializedSize = -1; private int entityIdListMemoizedSerializedSize = -1;
public static final int CAKDDMKAIMD_FIELD_NUMBER = 7; public static final int STATUS_FIELD_NUMBER = 7;
private int cAKDDMKAIMD_; private int status_;
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @return The enum numeric value on the wire for cAKDDMKAIMD. * @return The enum numeric value on the wire for status.
*/ */
@java.lang.Override public int getCAKDDMKAIMDValue() { @java.lang.Override public int getStatusValue() {
return cAKDDMKAIMD_; return status_;
} }
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @return The cAKDDMKAIMD. * @return The status.
*/ */
@java.lang.Override public emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getCAKDDMKAIMD() { @java.lang.Override public emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getStatus() {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus result = emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.valueOf(cAKDDMKAIMD_); emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus result = emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.valueOf(status_);
return result == null ? emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.UNRECOGNIZED : result; return result == null ? emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.UNRECOGNIZED : result;
} }
public static final int JHFNDBIHLNB_FIELD_NUMBER = 8; public static final int SEED_ID_FIELD_NUMBER = 8;
private int jHFNDBIHLNB_; private int seedId_;
/** /**
* <code>uint32 JHFNDBIHLNB = 8;</code> * <code>uint32 seed_id = 8;</code>
* @return The jHFNDBIHLNB. * @return The seedId.
*/ */
@java.lang.Override @java.lang.Override
public int getJHFNDBIHLNB() { public int getSeedId() {
return jHFNDBIHLNB_; return seedId_;
} }
public static final int END_TIME_FIELD_NUMBER = 14; public static final int END_TIME_FIELD_NUMBER = 14;
@ -262,15 +262,15 @@ public final class HomePlantSubFieldDataOuterClass {
return endTime_; return endTime_;
} }
public static final int KHFGOPCOAGM_FIELD_NUMBER = 3; public static final int GATHER_POINT_TYPE_FIELD_NUMBER = 3;
private int kHFGOPCOAGM_; private int gatherPointType_;
/** /**
* <code>uint32 KHFGOPCOAGM = 3;</code> * <code>uint32 gather_point_type = 3;</code>
* @return The kHFGOPCOAGM. * @return The gatherPointType.
*/ */
@java.lang.Override @java.lang.Override
public int getKHFGOPCOAGM() { public int getGatherPointType() {
return kHFGOPCOAGM_; return gatherPointType_;
} }
private byte memoizedIsInitialized = -1; private byte memoizedIsInitialized = -1;
@ -288,8 +288,8 @@ public final class HomePlantSubFieldDataOuterClass {
public void writeTo(com.google.protobuf.CodedOutputStream output) public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException { throws java.io.IOException {
getSerializedSize(); getSerializedSize();
if (kHFGOPCOAGM_ != 0) { if (gatherPointType_ != 0) {
output.writeUInt32(3, kHFGOPCOAGM_); output.writeUInt32(3, gatherPointType_);
} }
if (getEntityIdListList().size() > 0) { if (getEntityIdListList().size() > 0) {
output.writeUInt32NoTag(50); output.writeUInt32NoTag(50);
@ -298,11 +298,11 @@ public final class HomePlantSubFieldDataOuterClass {
for (int i = 0; i < entityIdList_.size(); i++) { for (int i = 0; i < entityIdList_.size(); i++) {
output.writeUInt32NoTag(entityIdList_.getInt(i)); output.writeUInt32NoTag(entityIdList_.getInt(i));
} }
if (cAKDDMKAIMD_ != emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.HOME_FIELD_STATUE_NONE.getNumber()) { if (status_ != emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.HOME_FIELD_STATUE_NONE.getNumber()) {
output.writeEnum(7, cAKDDMKAIMD_); output.writeEnum(7, status_);
} }
if (jHFNDBIHLNB_ != 0) { if (seedId_ != 0) {
output.writeUInt32(8, jHFNDBIHLNB_); output.writeUInt32(8, seedId_);
} }
if (endTime_ != 0) { if (endTime_ != 0) {
output.writeFixed32(14, endTime_); output.writeFixed32(14, endTime_);
@ -316,9 +316,9 @@ public final class HomePlantSubFieldDataOuterClass {
if (size != -1) return size; if (size != -1) return size;
size = 0; size = 0;
if (kHFGOPCOAGM_ != 0) { if (gatherPointType_ != 0) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(3, kHFGOPCOAGM_); .computeUInt32Size(3, gatherPointType_);
} }
{ {
int dataSize = 0; int dataSize = 0;
@ -334,13 +334,13 @@ public final class HomePlantSubFieldDataOuterClass {
} }
entityIdListMemoizedSerializedSize = dataSize; entityIdListMemoizedSerializedSize = dataSize;
} }
if (cAKDDMKAIMD_ != emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.HOME_FIELD_STATUE_NONE.getNumber()) { if (status_ != emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.HOME_FIELD_STATUE_NONE.getNumber()) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeEnumSize(7, cAKDDMKAIMD_); .computeEnumSize(7, status_);
} }
if (jHFNDBIHLNB_ != 0) { if (seedId_ != 0) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeUInt32Size(8, jHFNDBIHLNB_); .computeUInt32Size(8, seedId_);
} }
if (endTime_ != 0) { if (endTime_ != 0) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
@ -363,13 +363,13 @@ public final class HomePlantSubFieldDataOuterClass {
if (!getEntityIdListList() if (!getEntityIdListList()
.equals(other.getEntityIdListList())) return false; .equals(other.getEntityIdListList())) return false;
if (cAKDDMKAIMD_ != other.cAKDDMKAIMD_) return false; if (status_ != other.status_) return false;
if (getJHFNDBIHLNB() if (getSeedId()
!= other.getJHFNDBIHLNB()) return false; != other.getSeedId()) return false;
if (getEndTime() if (getEndTime()
!= other.getEndTime()) return false; != other.getEndTime()) return false;
if (getKHFGOPCOAGM() if (getGatherPointType()
!= other.getKHFGOPCOAGM()) return false; != other.getGatherPointType()) return false;
if (!unknownFields.equals(other.unknownFields)) return false; if (!unknownFields.equals(other.unknownFields)) return false;
return true; return true;
} }
@ -385,14 +385,14 @@ public final class HomePlantSubFieldDataOuterClass {
hash = (37 * hash) + ENTITY_ID_LIST_FIELD_NUMBER; hash = (37 * hash) + ENTITY_ID_LIST_FIELD_NUMBER;
hash = (53 * hash) + getEntityIdListList().hashCode(); hash = (53 * hash) + getEntityIdListList().hashCode();
} }
hash = (37 * hash) + CAKDDMKAIMD_FIELD_NUMBER; hash = (37 * hash) + STATUS_FIELD_NUMBER;
hash = (53 * hash) + cAKDDMKAIMD_; hash = (53 * hash) + status_;
hash = (37 * hash) + JHFNDBIHLNB_FIELD_NUMBER; hash = (37 * hash) + SEED_ID_FIELD_NUMBER;
hash = (53 * hash) + getJHFNDBIHLNB(); hash = (53 * hash) + getSeedId();
hash = (37 * hash) + END_TIME_FIELD_NUMBER; hash = (37 * hash) + END_TIME_FIELD_NUMBER;
hash = (53 * hash) + getEndTime(); hash = (53 * hash) + getEndTime();
hash = (37 * hash) + KHFGOPCOAGM_FIELD_NUMBER; hash = (37 * hash) + GATHER_POINT_TYPE_FIELD_NUMBER;
hash = (53 * hash) + getKHFGOPCOAGM(); hash = (53 * hash) + getGatherPointType();
hash = (29 * hash) + unknownFields.hashCode(); hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash; memoizedHashCode = hash;
return hash; return hash;
@ -532,13 +532,13 @@ public final class HomePlantSubFieldDataOuterClass {
super.clear(); super.clear();
entityIdList_ = emptyIntList(); entityIdList_ = emptyIntList();
bitField0_ = (bitField0_ & ~0x00000001); bitField0_ = (bitField0_ & ~0x00000001);
cAKDDMKAIMD_ = 0; status_ = 0;
jHFNDBIHLNB_ = 0; seedId_ = 0;
endTime_ = 0; endTime_ = 0;
kHFGOPCOAGM_ = 0; gatherPointType_ = 0;
return this; return this;
} }
@ -572,10 +572,10 @@ public final class HomePlantSubFieldDataOuterClass {
bitField0_ = (bitField0_ & ~0x00000001); bitField0_ = (bitField0_ & ~0x00000001);
} }
result.entityIdList_ = entityIdList_; result.entityIdList_ = entityIdList_;
result.cAKDDMKAIMD_ = cAKDDMKAIMD_; result.status_ = status_;
result.jHFNDBIHLNB_ = jHFNDBIHLNB_; result.seedId_ = seedId_;
result.endTime_ = endTime_; result.endTime_ = endTime_;
result.kHFGOPCOAGM_ = kHFGOPCOAGM_; result.gatherPointType_ = gatherPointType_;
onBuilt(); onBuilt();
return result; return result;
} }
@ -634,17 +634,17 @@ public final class HomePlantSubFieldDataOuterClass {
} }
onChanged(); onChanged();
} }
if (other.cAKDDMKAIMD_ != 0) { if (other.status_ != 0) {
setCAKDDMKAIMDValue(other.getCAKDDMKAIMDValue()); setStatusValue(other.getStatusValue());
} }
if (other.getJHFNDBIHLNB() != 0) { if (other.getSeedId() != 0) {
setJHFNDBIHLNB(other.getJHFNDBIHLNB()); setSeedId(other.getSeedId());
} }
if (other.getEndTime() != 0) { if (other.getEndTime() != 0) {
setEndTime(other.getEndTime()); setEndTime(other.getEndTime());
} }
if (other.getKHFGOPCOAGM() != 0) { if (other.getGatherPointType() != 0) {
setKHFGOPCOAGM(other.getKHFGOPCOAGM()); setGatherPointType(other.getGatherPointType());
} }
this.mergeUnknownFields(other.unknownFields); this.mergeUnknownFields(other.unknownFields);
onChanged(); onChanged();
@ -755,87 +755,87 @@ public final class HomePlantSubFieldDataOuterClass {
return this; return this;
} }
private int cAKDDMKAIMD_ = 0; private int status_ = 0;
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @return The enum numeric value on the wire for cAKDDMKAIMD. * @return The enum numeric value on the wire for status.
*/ */
@java.lang.Override public int getCAKDDMKAIMDValue() { @java.lang.Override public int getStatusValue() {
return cAKDDMKAIMD_; return status_;
} }
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @param value The enum numeric value on the wire for cAKDDMKAIMD to set. * @param value The enum numeric value on the wire for status to set.
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder setCAKDDMKAIMDValue(int value) { public Builder setStatusValue(int value) {
cAKDDMKAIMD_ = value; status_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @return The cAKDDMKAIMD. * @return The status.
*/ */
@java.lang.Override @java.lang.Override
public emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getCAKDDMKAIMD() { public emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus getStatus() {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus result = emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.valueOf(cAKDDMKAIMD_); emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus result = emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.valueOf(status_);
return result == null ? emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.UNRECOGNIZED : result; return result == null ? emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus.UNRECOGNIZED : result;
} }
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @param value The cAKDDMKAIMD to set. * @param value The status to set.
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder setCAKDDMKAIMD(emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus value) { public Builder setStatus(emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.HomePlantFieldStatus value) {
if (value == null) { if (value == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
cAKDDMKAIMD_ = value.getNumber(); status_ = value.getNumber();
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>.HomePlantFieldStatus CAKDDMKAIMD = 7;</code> * <code>.HomePlantFieldStatus status = 7;</code>
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder clearCAKDDMKAIMD() { public Builder clearStatus() {
cAKDDMKAIMD_ = 0; status_ = 0;
onChanged(); onChanged();
return this; return this;
} }
private int jHFNDBIHLNB_ ; private int seedId_ ;
/** /**
* <code>uint32 JHFNDBIHLNB = 8;</code> * <code>uint32 seed_id = 8;</code>
* @return The jHFNDBIHLNB. * @return The seedId.
*/ */
@java.lang.Override @java.lang.Override
public int getJHFNDBIHLNB() { public int getSeedId() {
return jHFNDBIHLNB_; return seedId_;
} }
/** /**
* <code>uint32 JHFNDBIHLNB = 8;</code> * <code>uint32 seed_id = 8;</code>
* @param value The jHFNDBIHLNB to set. * @param value The seedId to set.
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder setJHFNDBIHLNB(int value) { public Builder setSeedId(int value) {
jHFNDBIHLNB_ = value; seedId_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>uint32 JHFNDBIHLNB = 8;</code> * <code>uint32 seed_id = 8;</code>
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder clearJHFNDBIHLNB() { public Builder clearSeedId() {
jHFNDBIHLNB_ = 0; seedId_ = 0;
onChanged(); onChanged();
return this; return this;
} }
@ -871,33 +871,33 @@ public final class HomePlantSubFieldDataOuterClass {
return this; return this;
} }
private int kHFGOPCOAGM_ ; private int gatherPointType_ ;
/** /**
* <code>uint32 KHFGOPCOAGM = 3;</code> * <code>uint32 gather_point_type = 3;</code>
* @return The kHFGOPCOAGM. * @return The gatherPointType.
*/ */
@java.lang.Override @java.lang.Override
public int getKHFGOPCOAGM() { public int getGatherPointType() {
return kHFGOPCOAGM_; return gatherPointType_;
} }
/** /**
* <code>uint32 KHFGOPCOAGM = 3;</code> * <code>uint32 gather_point_type = 3;</code>
* @param value The kHFGOPCOAGM to set. * @param value The gatherPointType to set.
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder setKHFGOPCOAGM(int value) { public Builder setGatherPointType(int value) {
kHFGOPCOAGM_ = value; gatherPointType_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>uint32 KHFGOPCOAGM = 3;</code> * <code>uint32 gather_point_type = 3;</code>
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder clearKHFGOPCOAGM() { public Builder clearGatherPointType() {
kHFGOPCOAGM_ = 0; gatherPointType_ = 0;
onChanged(); onChanged();
return this; return this;
} }
@ -969,12 +969,12 @@ public final class HomePlantSubFieldDataOuterClass {
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n\033HomePlantSubFieldData.proto\032\032HomePlant" + "\n\033HomePlantSubFieldData.proto\032\032HomePlant" +
"FieldStatus.proto\"\227\001\n\025HomePlantSubFieldD" + "FieldStatus.proto\"\224\001\n\025HomePlantSubFieldD" +
"ata\022\026\n\016entity_id_list\030\006 \003(\r\022*\n\013CAKDDMKAI" + "ata\022\026\n\016entity_id_list\030\006 \003(\r\022%\n\006status\030\007 " +
"MD\030\007 \001(\0162\025.HomePlantFieldStatus\022\023\n\013JHFND" + "\001(\0162\025.HomePlantFieldStatus\022\017\n\007seed_id\030\010 " +
"BIHLNB\030\010 \001(\r\022\020\n\010end_time\030\016 \001(\007\022\023\n\013KHFGOP" + "\001(\r\022\020\n\010end_time\030\016 \001(\007\022\031\n\021gather_point_ty" +
"COAGM\030\003 \001(\rB\033\n\031emu.grasscutter.net.proto" + "pe\030\003 \001(\rB\033\n\031emu.grasscutter.net.protob\006p" +
"b\006proto3" "roto3"
}; };
descriptor = com.google.protobuf.Descriptors.FileDescriptor descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData, .internalBuildGeneratedFileFrom(descriptorData,
@ -986,7 +986,7 @@ public final class HomePlantSubFieldDataOuterClass {
internal_static_HomePlantSubFieldData_fieldAccessorTable = new internal_static_HomePlantSubFieldData_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_HomePlantSubFieldData_descriptor, internal_static_HomePlantSubFieldData_descriptor,
new java.lang.String[] { "EntityIdList", "CAKDDMKAIMD", "JHFNDBIHLNB", "EndTime", "KHFGOPCOAGM", }); new java.lang.String[] { "EntityIdList", "Status", "SeedId", "EndTime", "GatherPointType", });
emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.getDescriptor(); emu.grasscutter.net.proto.HomePlantFieldStatusOuterClass.getDescriptor();
} }

View File

@ -25,10 +25,10 @@ public final class HomeTransferReqOuterClass {
int getGuid(); int getGuid();
/** /**
* <code>bool JFEOCNJLCLG = 5;</code> * <code>bool is_transfer_to_main_house_point = 5;</code>
* @return The jFEOCNJLCLG. * @return The isTransferToMainHousePoint.
*/ */
boolean getJFEOCNJLCLG(); boolean getIsTransferToMainHousePoint();
/** /**
* <code>bool is_transfer_to_safe_point = 3;</code> * <code>bool is_transfer_to_safe_point = 3;</code>
@ -93,7 +93,7 @@ public final class HomeTransferReqOuterClass {
} }
case 40: { case 40: {
jFEOCNJLCLG_ = input.readBool(); isTransferToMainHousePoint_ = input.readBool();
break; break;
} }
case 96: { case 96: {
@ -144,15 +144,15 @@ public final class HomeTransferReqOuterClass {
return guid_; return guid_;
} }
public static final int JFEOCNJLCLG_FIELD_NUMBER = 5; public static final int IS_TRANSFER_TO_MAIN_HOUSE_POINT_FIELD_NUMBER = 5;
private boolean jFEOCNJLCLG_; private boolean isTransferToMainHousePoint_;
/** /**
* <code>bool JFEOCNJLCLG = 5;</code> * <code>bool is_transfer_to_main_house_point = 5;</code>
* @return The jFEOCNJLCLG. * @return The isTransferToMainHousePoint.
*/ */
@java.lang.Override @java.lang.Override
public boolean getJFEOCNJLCLG() { public boolean getIsTransferToMainHousePoint() {
return jFEOCNJLCLG_; return isTransferToMainHousePoint_;
} }
public static final int IS_TRANSFER_TO_SAFE_POINT_FIELD_NUMBER = 3; public static final int IS_TRANSFER_TO_SAFE_POINT_FIELD_NUMBER = 3;
@ -183,8 +183,8 @@ public final class HomeTransferReqOuterClass {
if (isTransferToSafePoint_ != false) { if (isTransferToSafePoint_ != false) {
output.writeBool(3, isTransferToSafePoint_); output.writeBool(3, isTransferToSafePoint_);
} }
if (jFEOCNJLCLG_ != false) { if (isTransferToMainHousePoint_ != false) {
output.writeBool(5, jFEOCNJLCLG_); output.writeBool(5, isTransferToMainHousePoint_);
} }
if (guid_ != 0) { if (guid_ != 0) {
output.writeUInt32(12, guid_); output.writeUInt32(12, guid_);
@ -202,9 +202,9 @@ public final class HomeTransferReqOuterClass {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeBoolSize(3, isTransferToSafePoint_); .computeBoolSize(3, isTransferToSafePoint_);
} }
if (jFEOCNJLCLG_ != false) { if (isTransferToMainHousePoint_ != false) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeBoolSize(5, jFEOCNJLCLG_); .computeBoolSize(5, isTransferToMainHousePoint_);
} }
if (guid_ != 0) { if (guid_ != 0) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
@ -227,8 +227,8 @@ public final class HomeTransferReqOuterClass {
if (getGuid() if (getGuid()
!= other.getGuid()) return false; != other.getGuid()) return false;
if (getJFEOCNJLCLG() if (getIsTransferToMainHousePoint()
!= other.getJFEOCNJLCLG()) return false; != other.getIsTransferToMainHousePoint()) return false;
if (getIsTransferToSafePoint() if (getIsTransferToSafePoint()
!= other.getIsTransferToSafePoint()) return false; != other.getIsTransferToSafePoint()) return false;
if (!unknownFields.equals(other.unknownFields)) return false; if (!unknownFields.equals(other.unknownFields)) return false;
@ -244,9 +244,9 @@ public final class HomeTransferReqOuterClass {
hash = (19 * hash) + getDescriptor().hashCode(); hash = (19 * hash) + getDescriptor().hashCode();
hash = (37 * hash) + GUID_FIELD_NUMBER; hash = (37 * hash) + GUID_FIELD_NUMBER;
hash = (53 * hash) + getGuid(); hash = (53 * hash) + getGuid();
hash = (37 * hash) + JFEOCNJLCLG_FIELD_NUMBER; hash = (37 * hash) + IS_TRANSFER_TO_MAIN_HOUSE_POINT_FIELD_NUMBER;
hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
getJFEOCNJLCLG()); getIsTransferToMainHousePoint());
hash = (37 * hash) + IS_TRANSFER_TO_SAFE_POINT_FIELD_NUMBER; hash = (37 * hash) + IS_TRANSFER_TO_SAFE_POINT_FIELD_NUMBER;
hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
getIsTransferToSafePoint()); getIsTransferToSafePoint());
@ -390,7 +390,7 @@ public final class HomeTransferReqOuterClass {
super.clear(); super.clear();
guid_ = 0; guid_ = 0;
jFEOCNJLCLG_ = false; isTransferToMainHousePoint_ = false;
isTransferToSafePoint_ = false; isTransferToSafePoint_ = false;
@ -421,7 +421,7 @@ public final class HomeTransferReqOuterClass {
public emu.grasscutter.net.proto.HomeTransferReqOuterClass.HomeTransferReq buildPartial() { public emu.grasscutter.net.proto.HomeTransferReqOuterClass.HomeTransferReq buildPartial() {
emu.grasscutter.net.proto.HomeTransferReqOuterClass.HomeTransferReq result = new emu.grasscutter.net.proto.HomeTransferReqOuterClass.HomeTransferReq(this); emu.grasscutter.net.proto.HomeTransferReqOuterClass.HomeTransferReq result = new emu.grasscutter.net.proto.HomeTransferReqOuterClass.HomeTransferReq(this);
result.guid_ = guid_; result.guid_ = guid_;
result.jFEOCNJLCLG_ = jFEOCNJLCLG_; result.isTransferToMainHousePoint_ = isTransferToMainHousePoint_;
result.isTransferToSafePoint_ = isTransferToSafePoint_; result.isTransferToSafePoint_ = isTransferToSafePoint_;
onBuilt(); onBuilt();
return result; return result;
@ -474,8 +474,8 @@ public final class HomeTransferReqOuterClass {
if (other.getGuid() != 0) { if (other.getGuid() != 0) {
setGuid(other.getGuid()); setGuid(other.getGuid());
} }
if (other.getJFEOCNJLCLG() != false) { if (other.getIsTransferToMainHousePoint() != false) {
setJFEOCNJLCLG(other.getJFEOCNJLCLG()); setIsTransferToMainHousePoint(other.getIsTransferToMainHousePoint());
} }
if (other.getIsTransferToSafePoint() != false) { if (other.getIsTransferToSafePoint() != false) {
setIsTransferToSafePoint(other.getIsTransferToSafePoint()); setIsTransferToSafePoint(other.getIsTransferToSafePoint());
@ -540,33 +540,33 @@ public final class HomeTransferReqOuterClass {
return this; return this;
} }
private boolean jFEOCNJLCLG_ ; private boolean isTransferToMainHousePoint_ ;
/** /**
* <code>bool JFEOCNJLCLG = 5;</code> * <code>bool is_transfer_to_main_house_point = 5;</code>
* @return The jFEOCNJLCLG. * @return The isTransferToMainHousePoint.
*/ */
@java.lang.Override @java.lang.Override
public boolean getJFEOCNJLCLG() { public boolean getIsTransferToMainHousePoint() {
return jFEOCNJLCLG_; return isTransferToMainHousePoint_;
} }
/** /**
* <code>bool JFEOCNJLCLG = 5;</code> * <code>bool is_transfer_to_main_house_point = 5;</code>
* @param value The jFEOCNJLCLG to set. * @param value The isTransferToMainHousePoint to set.
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder setJFEOCNJLCLG(boolean value) { public Builder setIsTransferToMainHousePoint(boolean value) {
jFEOCNJLCLG_ = value; isTransferToMainHousePoint_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>bool JFEOCNJLCLG = 5;</code> * <code>bool is_transfer_to_main_house_point = 5;</code>
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder clearJFEOCNJLCLG() { public Builder clearIsTransferToMainHousePoint() {
jFEOCNJLCLG_ = false; isTransferToMainHousePoint_ = false;
onChanged(); onChanged();
return this; return this;
} }
@ -668,10 +668,11 @@ public final class HomeTransferReqOuterClass {
descriptor; descriptor;
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n\025HomeTransferReq.proto\"W\n\017HomeTransferR" + "\n\025HomeTransferReq.proto\"k\n\017HomeTransferR" +
"eq\022\014\n\004guid\030\014 \001(\r\022\023\n\013JFEOCNJLCLG\030\005 \001(\010\022!\n" + "eq\022\014\n\004guid\030\014 \001(\r\022\'\n\037is_transfer_to_main_" +
"\031is_transfer_to_safe_point\030\003 \001(\010B\033\n\031emu." + "house_point\030\005 \001(\010\022!\n\031is_transfer_to_safe" +
"grasscutter.net.protob\006proto3" "_point\030\003 \001(\010B\033\n\031emu.grasscutter.net.prot" +
"ob\006proto3"
}; };
descriptor = com.google.protobuf.Descriptors.FileDescriptor descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData, .internalBuildGeneratedFileFrom(descriptorData,
@ -682,7 +683,7 @@ public final class HomeTransferReqOuterClass {
internal_static_HomeTransferReq_fieldAccessorTable = new internal_static_HomeTransferReq_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_HomeTransferReq_descriptor, internal_static_HomeTransferReq_descriptor,
new java.lang.String[] { "Guid", "JFEOCNJLCLG", "IsTransferToSafePoint", }); new java.lang.String[] { "Guid", "IsTransferToMainHousePoint", "IsTransferToSafePoint", });
} }
// @@protoc_insertion_point(outer_class_scope) // @@protoc_insertion_point(outer_class_scope)

View File

@ -37,10 +37,10 @@ public final class TryEnterHomeReqOuterClass {
int getTargetPoint(); int getTargetPoint();
/** /**
* <code>bool JFEOCNJLCLG = 12;</code> * <code>bool is_transfer_to_main_house_point = 12;</code>
* @return The jFEOCNJLCLG. * @return The isTransferToMainHousePoint.
*/ */
boolean getJFEOCNJLCLG(); boolean getIsTransferToMainHousePoint();
} }
/** /**
* <pre> * <pre>
@ -109,7 +109,7 @@ public final class TryEnterHomeReqOuterClass {
} }
case 96: { case 96: {
jFEOCNJLCLG_ = input.readBool(); isTransferToMainHousePoint_ = input.readBool();
break; break;
} }
default: { default: {
@ -177,15 +177,15 @@ public final class TryEnterHomeReqOuterClass {
return targetPoint_; return targetPoint_;
} }
public static final int JFEOCNJLCLG_FIELD_NUMBER = 12; public static final int IS_TRANSFER_TO_MAIN_HOUSE_POINT_FIELD_NUMBER = 12;
private boolean jFEOCNJLCLG_; private boolean isTransferToMainHousePoint_;
/** /**
* <code>bool JFEOCNJLCLG = 12;</code> * <code>bool is_transfer_to_main_house_point = 12;</code>
* @return The jFEOCNJLCLG. * @return The isTransferToMainHousePoint.
*/ */
@java.lang.Override @java.lang.Override
public boolean getJFEOCNJLCLG() { public boolean getIsTransferToMainHousePoint() {
return jFEOCNJLCLG_; return isTransferToMainHousePoint_;
} }
private byte memoizedIsInitialized = -1; private byte memoizedIsInitialized = -1;
@ -211,8 +211,8 @@ public final class TryEnterHomeReqOuterClass {
if (isTransferToSafePoint_ != false) { if (isTransferToSafePoint_ != false) {
output.writeBool(9, isTransferToSafePoint_); output.writeBool(9, isTransferToSafePoint_);
} }
if (jFEOCNJLCLG_ != false) { if (isTransferToMainHousePoint_ != false) {
output.writeBool(12, jFEOCNJLCLG_); output.writeBool(12, isTransferToMainHousePoint_);
} }
unknownFields.writeTo(output); unknownFields.writeTo(output);
} }
@ -235,9 +235,9 @@ public final class TryEnterHomeReqOuterClass {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeBoolSize(9, isTransferToSafePoint_); .computeBoolSize(9, isTransferToSafePoint_);
} }
if (jFEOCNJLCLG_ != false) { if (isTransferToMainHousePoint_ != false) {
size += com.google.protobuf.CodedOutputStream size += com.google.protobuf.CodedOutputStream
.computeBoolSize(12, jFEOCNJLCLG_); .computeBoolSize(12, isTransferToMainHousePoint_);
} }
size += unknownFields.getSerializedSize(); size += unknownFields.getSerializedSize();
memoizedSize = size; memoizedSize = size;
@ -260,8 +260,8 @@ public final class TryEnterHomeReqOuterClass {
!= other.getIsTransferToSafePoint()) return false; != other.getIsTransferToSafePoint()) return false;
if (getTargetPoint() if (getTargetPoint()
!= other.getTargetPoint()) return false; != other.getTargetPoint()) return false;
if (getJFEOCNJLCLG() if (getIsTransferToMainHousePoint()
!= other.getJFEOCNJLCLG()) return false; != other.getIsTransferToMainHousePoint()) return false;
if (!unknownFields.equals(other.unknownFields)) return false; if (!unknownFields.equals(other.unknownFields)) return false;
return true; return true;
} }
@ -280,9 +280,9 @@ public final class TryEnterHomeReqOuterClass {
getIsTransferToSafePoint()); getIsTransferToSafePoint());
hash = (37 * hash) + TARGET_POINT_FIELD_NUMBER; hash = (37 * hash) + TARGET_POINT_FIELD_NUMBER;
hash = (53 * hash) + getTargetPoint(); hash = (53 * hash) + getTargetPoint();
hash = (37 * hash) + JFEOCNJLCLG_FIELD_NUMBER; hash = (37 * hash) + IS_TRANSFER_TO_MAIN_HOUSE_POINT_FIELD_NUMBER;
hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
getJFEOCNJLCLG()); getIsTransferToMainHousePoint());
hash = (29 * hash) + unknownFields.hashCode(); hash = (29 * hash) + unknownFields.hashCode();
memoizedHashCode = hash; memoizedHashCode = hash;
return hash; return hash;
@ -427,7 +427,7 @@ public final class TryEnterHomeReqOuterClass {
targetPoint_ = 0; targetPoint_ = 0;
jFEOCNJLCLG_ = false; isTransferToMainHousePoint_ = false;
return this; return this;
} }
@ -458,7 +458,7 @@ public final class TryEnterHomeReqOuterClass {
result.targetUid_ = targetUid_; result.targetUid_ = targetUid_;
result.isTransferToSafePoint_ = isTransferToSafePoint_; result.isTransferToSafePoint_ = isTransferToSafePoint_;
result.targetPoint_ = targetPoint_; result.targetPoint_ = targetPoint_;
result.jFEOCNJLCLG_ = jFEOCNJLCLG_; result.isTransferToMainHousePoint_ = isTransferToMainHousePoint_;
onBuilt(); onBuilt();
return result; return result;
} }
@ -516,8 +516,8 @@ public final class TryEnterHomeReqOuterClass {
if (other.getTargetPoint() != 0) { if (other.getTargetPoint() != 0) {
setTargetPoint(other.getTargetPoint()); setTargetPoint(other.getTargetPoint());
} }
if (other.getJFEOCNJLCLG() != false) { if (other.getIsTransferToMainHousePoint() != false) {
setJFEOCNJLCLG(other.getJFEOCNJLCLG()); setIsTransferToMainHousePoint(other.getIsTransferToMainHousePoint());
} }
this.mergeUnknownFields(other.unknownFields); this.mergeUnknownFields(other.unknownFields);
onChanged(); onChanged();
@ -641,33 +641,33 @@ public final class TryEnterHomeReqOuterClass {
return this; return this;
} }
private boolean jFEOCNJLCLG_ ; private boolean isTransferToMainHousePoint_ ;
/** /**
* <code>bool JFEOCNJLCLG = 12;</code> * <code>bool is_transfer_to_main_house_point = 12;</code>
* @return The jFEOCNJLCLG. * @return The isTransferToMainHousePoint.
*/ */
@java.lang.Override @java.lang.Override
public boolean getJFEOCNJLCLG() { public boolean getIsTransferToMainHousePoint() {
return jFEOCNJLCLG_; return isTransferToMainHousePoint_;
} }
/** /**
* <code>bool JFEOCNJLCLG = 12;</code> * <code>bool is_transfer_to_main_house_point = 12;</code>
* @param value The jFEOCNJLCLG to set. * @param value The isTransferToMainHousePoint to set.
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder setJFEOCNJLCLG(boolean value) { public Builder setIsTransferToMainHousePoint(boolean value) {
jFEOCNJLCLG_ = value; isTransferToMainHousePoint_ = value;
onChanged(); onChanged();
return this; return this;
} }
/** /**
* <code>bool JFEOCNJLCLG = 12;</code> * <code>bool is_transfer_to_main_house_point = 12;</code>
* @return This builder for chaining. * @return This builder for chaining.
*/ */
public Builder clearJFEOCNJLCLG() { public Builder clearIsTransferToMainHousePoint() {
jFEOCNJLCLG_ = false; isTransferToMainHousePoint_ = false;
onChanged(); onChanged();
return this; return this;
} }
@ -738,11 +738,11 @@ public final class TryEnterHomeReqOuterClass {
descriptor; descriptor;
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n\025TryEnterHomeReq.proto\"s\n\017TryEnterHomeR" + "\n\025TryEnterHomeReq.proto\"\207\001\n\017TryEnterHome" +
"eq\022\022\n\ntarget_uid\030\004 \001(\r\022!\n\031is_transfer_to" + "Req\022\022\n\ntarget_uid\030\004 \001(\r\022!\n\031is_transfer_t" +
"_safe_point\030\t \001(\010\022\024\n\014target_point\030\005 \001(\r\022" + "o_safe_point\030\t \001(\010\022\024\n\014target_point\030\005 \001(\r" +
"\023\n\013JFEOCNJLCLG\030\014 \001(\010B\033\n\031emu.grasscutter." + "\022\'\n\037is_transfer_to_main_house_point\030\014 \001(" +
"net.protob\006proto3" "\010B\033\n\031emu.grasscutter.net.protob\006proto3"
}; };
descriptor = com.google.protobuf.Descriptors.FileDescriptor descriptor = com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData, .internalBuildGeneratedFileFrom(descriptorData,
@ -753,7 +753,7 @@ public final class TryEnterHomeReqOuterClass {
internal_static_TryEnterHomeReq_fieldAccessorTable = new internal_static_TryEnterHomeReq_fieldAccessorTable = new
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
internal_static_TryEnterHomeReq_descriptor, internal_static_TryEnterHomeReq_descriptor,
new java.lang.String[] { "TargetUid", "IsTransferToSafePoint", "TargetPoint", "JFEOCNJLCLG", }); new java.lang.String[] { "TargetUid", "IsTransferToSafePoint", "TargetPoint", "IsTransferToMainHousePoint", });
} }
// @@protoc_insertion_point(outer_class_scope) // @@protoc_insertion_point(outer_class_scope)

View File

@ -1,8 +1,32 @@
# Handbook Data # Handbook Data
Use Grasscutter's dumpers to generate the data to put here. Use Grasscutter's dumpers to generate the data to put here.
# Generating Data
When you have Grasscutter set up, you can use the following commands to generate the data:
- Commands - `grasscutter.jar -dump=commands,en-us`
- Items - `grasscutter.jar -dump=items,EN`
- Avatars - `grasscutter.jar -dump=avatars,EN`
- Quests - `grasscutter.jar -dump=quests,EN`
- Entities - `grasscutter.jar -dump=entities,en-us`
- Areas - `grasscutter.jar -dump=areas,EN`
- Scenes - `grasscutter.jar -dump=scenes,en-us`
Grasscutter being "set up" means:
- A Java runtime is installed
- Resources are provided in the working directory
## Language Locales
You can replace `en-us` or `EN` using the language locale which matches the format.
| Grasscutter Language Locale | Handbook Language Locale |
|-----------------------------|--------------------------|
| en-us | EN |
## Files Required ## Files Required
- `mainquests.csv' - `mainquests.csv`
- `commands.json` - `commands.json`
- `entities.csv` - `entities.csv`
- `avatars.csv` - `avatars.csv`

View File

@ -1,12 +1,12 @@
package emu.grasscutter; package emu.grasscutter;
public final class DebugConstants { public final class DebugConstants {
public static boolean LOG_ABILITIES = false; public static final boolean LOG_ABILITIES = false;
public static boolean LOG_LUA_SCRIPTS = false; public static final boolean LOG_LUA_SCRIPTS = false;
public static boolean LOG_QUEST_START = false; public static final boolean LOG_QUEST_START = false;
public static boolean LOG_MISSING_ABILITIES = false; public static final boolean LOG_MISSING_ABILITIES = false;
public static boolean LOG_MISSING_LUA_SCRIPTS = false; public static final boolean LOG_MISSING_LUA_SCRIPTS = false;
public static boolean LOG_MISSING_ABILITY_HANDLERS = 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 * 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; import java.util.Arrays;
public final class GameConstants { public final class GameConstants {
public static String VERSION = "4.0.0"; public static final String VERSION = "4.0.0";
public static int[] VERSION_PARTS = {4, 0, 0}; public static final int[] VERSION_PARTS = {4, 0, 0};
public static boolean DEBUG = false; public static boolean DEBUG = false;
public static final int DEFAULT_TEAMS = 4; public static final int DEFAULT_TEAMS = 4;

View File

@ -1,5 +1,8 @@
package emu.grasscutter; package emu.grasscutter;
import static emu.grasscutter.config.Configuration.SERVER;
import static emu.grasscutter.utils.lang.Language.translate;
import ch.qos.logback.classic.*; import ch.qos.logback.classic.*;
import emu.grasscutter.auth.*; import emu.grasscutter.auth.*;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
@ -18,20 +21,16 @@ import emu.grasscutter.tools.Tools;
import emu.grasscutter.utils.*; import emu.grasscutter.utils.*;
import emu.grasscutter.utils.lang.Language; import emu.grasscutter.utils.lang.Language;
import io.netty.util.concurrent.FastThreadLocalThread; import io.netty.util.concurrent.FastThreadLocalThread;
import java.io.*;
import java.util.Calendar;
import java.util.concurrent.*;
import javax.annotation.Nullable;
import lombok.*; import lombok.*;
import org.jline.reader.*; import org.jline.reader.*;
import org.jline.terminal.*; import org.jline.terminal.*;
import org.reflections.Reflections; import org.reflections.Reflections;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.*;
import java.util.Calendar;
import java.util.concurrent.*;
import static emu.grasscutter.config.Configuration.SERVER;
import static emu.grasscutter.utils.lang.Language.translate;
public final class Grasscutter { public final class Grasscutter {
public static final File configFile = new File("./config.json"); public static final File configFile = new File("./config.json");
public static final Reflections reflector = new Reflections("emu.grasscutter"); public static final Reflections reflector = new Reflections("emu.grasscutter");
@ -159,6 +158,8 @@ public final class Grasscutter {
// Generate handbooks. // Generate handbooks.
Tools.createGmHandbooks(false); Tools.createGmHandbooks(false);
// Generate gacha mappings.
Tools.generateGachaMappings();
} }
// Start servers. // Start servers.
@ -211,11 +212,7 @@ public final class Grasscutter {
} }
} }
/** /** Utility method for starting the: - SDK server - Dispatch server */
* Utility method for starting the:
* - SDK server
* - Dispatch server
*/
public static void startDispatch() throws Exception { public static void startDispatch() throws Exception {
httpServer.start(); // Start the SDK/HTTP server. httpServer.start(); // Start the SDK/HTTP server.
@ -315,7 +312,7 @@ public final class Grasscutter {
public static void updateDayOfWeek() { public static void updateDayOfWeek() {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
Grasscutter.currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); 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() { public static void startConsole() {

View File

@ -4,9 +4,8 @@ import emu.grasscutter.game.Account;
import emu.grasscutter.server.http.objects.*; import emu.grasscutter.server.http.objects.*;
import emu.grasscutter.utils.DispatchUtils; import emu.grasscutter.utils.DispatchUtils;
import io.javalin.http.Context; import io.javalin.http.Context;
import lombok.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import lombok.*;
/** Defines an authenticator for the server. Can be changed by plugins. */ /** Defines an authenticator for the server. Can be changed by plugins. */
public interface AuthenticationSystem { public interface AuthenticationSystem {

View File

@ -1,13 +1,13 @@
package emu.grasscutter.auth; package emu.grasscutter.auth;
import static emu.grasscutter.config.Configuration.ACCOUNT;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.auth.DefaultAuthenticators.*; import emu.grasscutter.auth.DefaultAuthenticators.*;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.server.http.objects.*; import emu.grasscutter.server.http.objects.*;
import static emu.grasscutter.config.Configuration.ACCOUNT;
import static emu.grasscutter.utils.lang.Language.translate;
/** /**
* The default Grasscutter authentication implementation. Allows all users to access any account. * The default Grasscutter authentication implementation. Allows all users to access any account.
*/ */

View File

@ -1,5 +1,8 @@
package emu.grasscutter.auth; package emu.grasscutter.auth;
import static emu.grasscutter.config.Configuration.ACCOUNT;
import static emu.grasscutter.utils.lang.Language.translate;
import at.favre.lib.crypto.bcrypt.BCrypt; import at.favre.lib.crypto.bcrypt.BCrypt;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerRunMode; import emu.grasscutter.Grasscutter.ServerRunMode;
@ -10,16 +13,12 @@ import emu.grasscutter.server.dispatch.*;
import emu.grasscutter.server.http.objects.*; import emu.grasscutter.server.http.objects.*;
import emu.grasscutter.utils.*; import emu.grasscutter.utils.*;
import io.javalin.http.ContentType; import io.javalin.http.ContentType;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec;
import java.util.concurrent.*; import java.util.concurrent.*;
import javax.crypto.Cipher;
import static emu.grasscutter.config.Configuration.ACCOUNT;
import static emu.grasscutter.utils.lang.Language.translate;
/** A class containing default authenticators. */ /** A class containing default authenticators. */
public final class DefaultAuthenticators { public final class DefaultAuthenticators {
@ -104,7 +103,7 @@ public final class DefaultAuthenticators {
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKey private_key = (RSAPrivateKey) keyFactory.generatePrivate(keySpec); 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); cipher.init(Cipher.DECRYPT_MODE, private_key);

View File

@ -1,13 +1,12 @@
package emu.grasscutter.command; package emu.grasscutter.command;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent; import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent;
import java.util.*; import java.util.*;
import static emu.grasscutter.utils.lang.Language.translate;
public interface CommandHandler { public interface CommandHandler {
/** /**

View File

@ -1,9 +1,10 @@
package emu.grasscutter.command; package emu.grasscutter.command;
import javax.annotation.Nonnull; import emu.grasscutter.game.world.Position;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.regex.*; import java.util.regex.*;
import javax.annotation.Nonnull;
public class CommandHelpers { public class CommandHelpers {
public static final Pattern lvlRegex = public static final Pattern lvlRegex =
@ -54,4 +55,78 @@ public class CommandHelpers {
}); });
return args; return args;
} }
public static float parseRelative(String input, Float current) {
if (input.contains("~")) { // Relative
if (!input.equals("~")) { // Relative with offset
current += Float.parseFloat(input.replace("~", ""));
} // Else no offset, no modification
} else { // Absolute
current = Float.parseFloat(input);
}
return current;
}
public static Position parsePosition(
String inputX, String inputY, String inputZ, Position curPos, Position curRot) {
Position offset = new Position();
Position target = new Position(curPos);
if (inputX.contains("~")) { // Relative
if (!inputX.equals("~")) { // Relative with offset
target.addX(Float.parseFloat(inputX.replace("~", "")));
}
} else if (inputX.contains("^")) {
if (!inputX.equals("^")) {
offset.setX(Float.parseFloat(inputX.replace("^", "")));
}
} else { // Absolute
target.setX(Float.parseFloat(inputX));
}
if (inputY.contains("~")) { // Relative
if (!inputY.equals("~")) { // Relative with offset
target.addY(Float.parseFloat(inputY.replace("~", "")));
}
} else if (inputY.contains("^")) {
if (!inputY.equals("^")) {
offset.setY(Float.parseFloat(inputY.replace("^", "")));
}
} else { // Absolute
target.setY(Float.parseFloat(inputY));
}
if (inputZ.contains("~")) { // Relative
if (!inputZ.equals("~")) { // Relative with offset
target.addZ(Float.parseFloat(inputZ.replace("~", "")));
}
} else if (inputZ.contains("^")) {
if (!inputZ.equals("^")) {
offset.setZ(Float.parseFloat(inputZ.replace("^", "")));
}
} else { // Absolute
target.setZ(Float.parseFloat(inputZ));
}
if (!offset.equal3d(Position.ZERO)) {
return calculateOffset(target, curRot, offset);
} else {
return target;
}
}
public static Position calculateOffset(Position pos, Position rot, Position offset) {
// Degrees to radians
float angleZ = (float) Math.toRadians(rot.getY());
float angleX = (float) Math.toRadians(rot.getY() + 90);
// Calculate offset based on current position and rotation
return new Position(
pos.getX()
+ offset.getZ() * (float) Math.sin(angleZ)
+ offset.getX() * (float) Math.sin(angleX),
pos.getY() + offset.getY(),
pos.getZ()
+ offset.getZ() * (float) Math.cos(angleZ)
+ offset.getX() * (float) Math.cos(angleX));
}
} }

View File

@ -1,15 +1,14 @@
package emu.grasscutter.command; package emu.grasscutter.command;
import static emu.grasscutter.config.Configuration.SERVER;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.event.game.ExecuteCommandEvent; import emu.grasscutter.server.event.game.ExecuteCommandEvent;
import it.unimi.dsi.fastutil.objects.*; import it.unimi.dsi.fastutil.objects.*;
import org.reflections.Reflections;
import java.util.*; import java.util.*;
import org.reflections.Reflections;
import static emu.grasscutter.config.Configuration.SERVER;
@SuppressWarnings({"UnusedReturnValue", "unused"}) @SuppressWarnings({"UnusedReturnValue", "unused"})
public final class CommandMap { public final class CommandMap {
@ -54,7 +53,7 @@ public final class CommandMap {
* @return Instance chaining. * @return Instance chaining.
*/ */
public CommandMap registerCommand(String label, CommandHandler command) { public CommandMap registerCommand(String label, CommandHandler command) {
Grasscutter.getLogger().trace("Registered command: " + label); Grasscutter.getLogger().trace("Registered command: {}", label);
label = label.toLowerCase(); label = label.toLowerCase();
// Get command data. // Get command data.
@ -77,7 +76,7 @@ public final class CommandMap {
* @return Instance chaining. * @return Instance chaining.
*/ */
public CommandMap unregisterCommand(String label) { 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); CommandHandler handler = this.commands.get(label);
if (handler == null) return this; if (handler == null) return this;
@ -232,14 +231,12 @@ public final class CommandMap {
if (player != null) { if (player != null) {
Grasscutter.getLogger() Grasscutter.getLogger()
.info( .info(
"Command used by [" "Command used by [{} (Player UID: {})]: {}",
+ player.getAccount().getUsername() player.getAccount().getUsername(),
+ " (Player UID: " player.getUid(),
+ player.getUid() rawMessage);
+ ")]: "
+ rawMessage);
} else { } else {
Grasscutter.getLogger().info("Command used by server console: " + rawMessage); Grasscutter.getLogger().info("Command used by server console: {}", rawMessage);
} }
} }
@ -351,11 +348,12 @@ public final class CommandMap {
this.registerCommand(cmdData.label(), (CommandHandler) object); this.registerCommand(cmdData.label(), (CommandHandler) object);
else else
Grasscutter.getLogger() Grasscutter.getLogger()
.error("Class " + annotated.getName() + " is not a CommandHandler!"); .error("Class {} is not a CommandHandler!", annotated.getName());
} catch (Exception exception) { } catch (Exception exception) {
Grasscutter.getLogger() Grasscutter.getLogger()
.error( .error(
"Failed to register command handler for " + annotated.getSimpleName(), "Failed to register command handler for {}",
annotated.getSimpleName(),
exception); exception);
} }
}); });

View File

@ -1,5 +1,7 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import at.favre.lib.crypto.bcrypt.BCrypt; import at.favre.lib.crypto.bcrypt.BCrypt;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
@ -7,12 +9,9 @@ import emu.grasscutter.config.Configuration;
import emu.grasscutter.database.*; import emu.grasscutter.database.*;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "account", label = "account",
usage = { usage = {

View File

@ -5,7 +5,6 @@ import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.achievement.AchievementData; import emu.grasscutter.data.excels.achievement.AchievementData;
import emu.grasscutter.game.achievement.*; import emu.grasscutter.game.achievement.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -70,7 +69,7 @@ public final class AchievementCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) { if (args.isEmpty()) {
this.sendUsageMessage(sender); this.sendUsageMessage(sender);
return; return;
} }
@ -89,7 +88,7 @@ public final class AchievementCommand implements CommandHandler {
private void grant( private void grant(
Player sender, Player targetPlayer, Achievements achievements, List<String> args) { Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
if (args.size() < 1) { if (args.isEmpty()) {
this.sendUsageMessage(sender); this.sendUsageMessage(sender);
} }
@ -110,7 +109,7 @@ public final class AchievementCommand implements CommandHandler {
private void revoke( private void revoke(
Player sender, Player targetPlayer, Achievements achievements, List<String> args) { Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
if (args.size() < 1) { if (args.isEmpty()) {
this.sendUsageMessage(sender); this.sendUsageMessage(sender);
} }
@ -137,20 +136,19 @@ public final class AchievementCommand implements CommandHandler {
parseInt(args.remove(0)) parseInt(args.remove(0))
.ifPresentOrElse( .ifPresentOrElse(
integer -> { integer ->
parseInt(args.remove(0)) parseInt(args.remove(0))
.ifPresentOrElse( .ifPresentOrElse(
progress -> { progress -> {
var ret = achievements.progress(integer, progress); var ret = achievements.progress(integer, progress);
switch (ret.getRet()) { switch (ret.getRet()) {
case SUCCESS -> sendSuccessMessage( case SUCCESS -> sendSuccessMessage(
sender, "progress", targetPlayer.getNickname(), integer, progress); sender, "progress", targetPlayer.getNickname(), integer, progress);
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage( case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
sender, ret.getRet().getKey()); sender, ret.getRet().getKey());
} }
}, },
() -> this.sendUsageMessage(sender)); () -> this.sendUsageMessage(sender)),
},
() -> this.sendUsageMessage(sender)); () -> this.sendUsageMessage(sender));
} }
} }

View File

@ -1,14 +1,13 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.PacketServerAnnounceNotify; import emu.grasscutter.server.packet.send.PacketServerAnnounceNotify;
import java.util.*; import java.util.*;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "announce", label = "announce",
usage = {"<content>", "refresh", "(tpl|revoke) <templateId>"}, usage = {"<content>", "refresh", "(tpl|revoke) <templateId>"},
@ -20,7 +19,7 @@ public final class AnnounceCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
var manager = Grasscutter.getGameServer().getAnnouncementSystem(); var manager = Grasscutter.getGameServer().getAnnouncementSystem();
if (args.size() < 1) { if (args.isEmpty()) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }

View File

@ -4,7 +4,6 @@ import emu.grasscutter.command.*;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import java.util.List; import java.util.List;
@Command( @Command(

View File

@ -1,16 +1,15 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.command.CommandHelpers.*;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.inventory.*; import emu.grasscutter.game.inventory.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import lombok.Setter;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Stream; import java.util.stream.Stream;
import lombok.Setter;
import static emu.grasscutter.command.CommandHelpers.*;
@Command( @Command(
label = "clear", label = "clear",
@ -52,7 +51,7 @@ public final class ClearCommand implements CommandHandler {
// Extract any tagged int arguments (e.g. "lv90", "x100", "r5") // Extract any tagged int arguments (e.g. "lv90", "x100", "r5")
parseIntParameters(args, param, intCommandHandlers); parseIntParameters(args, param, intCommandHandlers);
if (args.size() < 1) { if (args.isEmpty()) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
@ -94,9 +93,10 @@ public final class ClearCommand implements CommandHandler {
} }
} }
@Setter
private static class ClearItemParameters { private static class ClearItemParameters {
@Setter public int lvl = 1; public int lvl = 1;
@Setter public int refinement = 1; public int refinement = 1;
@Setter public int rank = 4; public int rank = 4;
} }
} }

View File

@ -3,7 +3,6 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
@Command( @Command(

View File

@ -3,9 +3,8 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.PacketCutsceneBeginNotify; import emu.grasscutter.server.packet.send.PacketCutsceneBeginNotify;
import lombok.val;
import java.util.List; import java.util.List;
import lombok.val;
@Command( @Command(
label = "cutscene", label = "cutscene",

View File

@ -3,7 +3,6 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
@Command( @Command(
@ -33,9 +32,12 @@ public final class DebugCommand implements CommandHandler {
var scene = sender.getScene(); var scene = sender.getScene();
var entityId = Integer.parseInt(args.get(0)); var entityId = Integer.parseInt(args.get(0));
// TODO Might want to allow groupId specification,
// because there can be more than one entity with
// the given config ID.
var entity = var entity =
args.size() > 1 && args.get(1).equals("config") args.size() > 1 && args.get(1).equals("config")
? scene.getEntityByConfigId(entityId) ? scene.getFirstEntityByConfigId(entityId)
: scene.getEntityById(entityId); : scene.getEntityById(entityId);
if (entity == null) { if (entity == null) {
sender.dropMessage("Entity not found."); sender.dropMessage("Entity not found.");

View File

@ -1,12 +1,11 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "enter_dungeon", label = "enter_dungeon",
aliases = {"enterdungeon", "dungeon"}, aliases = {"enterdungeon", "dungeon"},
@ -17,7 +16,7 @@ public final class EnterDungeonCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) { if (args.isEmpty()) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
@ -34,7 +33,7 @@ public final class EnterDungeonCommand implements CommandHandler {
targetPlayer targetPlayer
.getServer() .getServer()
.getDungeonSystem() .getDungeonSystem()
.enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId); .enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId, true);
if (!result) { if (!result) {
CommandHandler.sendMessage( CommandHandler.sendMessage(

View File

@ -1,5 +1,8 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.command.CommandHelpers.*;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.entity.*; import emu.grasscutter.game.entity.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
@ -7,14 +10,10 @@ import emu.grasscutter.game.props.*;
import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.Scene;
import emu.grasscutter.server.event.entity.EntityDamageEvent; import emu.grasscutter.server.event.entity.EntityDamageEvent;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import lombok.Setter;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import lombok.Setter;
import static emu.grasscutter.command.CommandHelpers.*;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "entity", label = "entity",
@ -52,7 +51,10 @@ public final class EntityCommand implements CommandHandler {
} }
param.scene = targetPlayer.getScene(); param.scene = targetPlayer.getScene();
var entity = param.scene.getEntityByConfigId(param.configId); // TODO Might want to allow groupId specification,
// because there can be more than one entity with
// the given config ID.
var entity = param.scene.getFirstEntityByConfigId(param.configId);
if (entity == null) { if (entity == null) {
CommandHandler.sendMessage(sender, translate(sender, "commands.entity.not_found_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.entity.not_found_error"));

View File

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

View File

@ -1,13 +1,12 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.SceneGroupInstance; import emu.grasscutter.game.world.SceneGroupInstance;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "group", label = "group",
aliases = {"gr"}, aliases = {"gr"},
@ -64,9 +63,7 @@ public final class GroupCommand implements CommandHandler {
CommandHandler.sendMessage(sender, translate(sender, "commands.group.refreshed", groupId)); CommandHandler.sendMessage(sender, translate(sender, "commands.group.refreshed", groupId));
} }
default -> { default -> sendUsageMessage(sender);
sendUsageMessage(sender);
}
} }
} }
} }

View File

@ -1,14 +1,13 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.server.packet.send.*; import emu.grasscutter.server.packet.send.*;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "heal", label = "heal",
aliases = {"h"}, aliases = {"h"},

View File

@ -1,13 +1,12 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.*; import java.util.*;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "help", label = "help",
usage = {"[<command>]"}, usage = {"[<command>]"},

View File

@ -50,8 +50,8 @@ public final class InfoCommand implements CommandHandler {
Player Count: %d Player Count: %d
Questing Enabled: %s Questing Enabled: %s
Scripts Enabled: %s Scripts Enabled: %s
Operating System: %s
Using Fast Require: %s Using Fast Require: %s
Operating System: %s
Resource Information: %s Resource Information: %s
discord.gg/T5vZU6UyeG""" discord.gg/T5vZU6UyeG"""

View File

@ -2,7 +2,6 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
@Command( @Command(

View File

@ -1,14 +1,13 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.entity.*; import emu.grasscutter.game.entity.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.Scene;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "killall", label = "killall",
usage = {"[<sceneId>]"}, usage = {"[<sceneId>]"},

View File

@ -1,15 +1,14 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.*; import emu.grasscutter.game.props.*;
import emu.grasscutter.server.packet.send.*; import emu.grasscutter.server.packet.send.*;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "killCharacter", label = "killCharacter",
aliases = {"suicide", "kill"}, aliases = {"suicide", "kill"},

View File

@ -1,14 +1,13 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import java.util.*; import java.util.*;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "language", label = "language",
usage = {"[<language code>]"}, usage = {"[<language code>]"},

View File

@ -1,13 +1,12 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.*; import java.util.*;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "list", label = "list",
aliases = {"players"}, aliases = {"players"},
@ -20,14 +19,14 @@ public final class ListCommand implements CommandHandler {
Map<Integer, Player> playersMap = Grasscutter.getGameServer().getPlayers(); Map<Integer, Player> playersMap = Grasscutter.getGameServer().getPlayers();
boolean needUID = false; boolean needUID = false;
if (args.size() > 0) { if (!args.isEmpty()) {
needUID = args.get(0).equals("uid"); needUID = args.get(0).equals("uid");
} }
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.list.success", playersMap.size())); sender, translate(sender, "commands.list.success", playersMap.size()));
if (playersMap.size() != 0) { if (!playersMap.isEmpty()) {
StringBuilder playerSet = new StringBuilder(); StringBuilder playerSet = new StringBuilder();
boolean finalNeedUID = needUID; boolean finalNeedUID = needUID;

View File

@ -1,15 +1,14 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.command.Command.TargetRequirement; import emu.grasscutter.command.Command.TargetRequirement;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "permission", label = "permission",
usage = {"add <permission>", "remove <permission>", "clear", "list"}, usage = {"add <permission>", "remove <permission>", "clear", "list"},

View File

@ -3,7 +3,6 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.Position; import emu.grasscutter.game.world.Position;
import java.util.List; import java.util.List;
@Command( @Command(

View File

@ -1,15 +1,14 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameQuest; import emu.grasscutter.game.quest.GameQuest;
import emu.grasscutter.game.quest.enums.*; import emu.grasscutter.game.quest.enums.*;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "quest", label = "quest",
aliases = {"q"}, aliases = {"q"},

View File

@ -1,13 +1,12 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "reload", label = "reload",
permission = "server.reload", permission = "server.reload",

View File

@ -1,14 +1,13 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "resetConst", label = "resetConst",
aliases = {"resetconstellation"}, aliases = {"resetconstellation"},
@ -19,7 +18,7 @@ public final class ResetConstCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() > 0 && args.get(0).equalsIgnoreCase("all")) { if (!args.isEmpty() && args.get(0).equalsIgnoreCase("all")) {
targetPlayer.getAvatars().forEach(this::resetConstellation); targetPlayer.getAvatars().forEach(this::resetConstellation);
CommandHandler.sendMessage(sender, translate(sender, "commands.resetConst.reset_all")); CommandHandler.sendMessage(sender, translate(sender, "commands.resetConst.reset_all"));
} else { } else {

View File

@ -1,12 +1,11 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "resetShopLimit", label = "resetShopLimit",
aliases = {"resetshop"}, aliases = {"resetshop"},

View File

@ -1,15 +1,14 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.mail.Mail; import emu.grasscutter.game.mail.Mail;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.*; import java.util.*;
import static emu.grasscutter.utils.lang.Language.translate;
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
@Command( @Command(
label = "sendMail", label = "sendMail",
@ -25,8 +24,7 @@ public final class SendMailCommand implements CommandHandler {
// the command system (again). For now this will do // the command system (again). For now this will do
// Key = User that is constructing the mail. // Key = User that is constructing the mail.
private static final HashMap<Integer, MailBuilder> mailBeingConstructed = private static final HashMap<Integer, MailBuilder> mailBeingConstructed = new HashMap<>();
new HashMap<Integer, MailBuilder>();
// Yes this is awful and I hate it. // Yes this is awful and I hate it.
@Override @Override
@ -70,7 +68,7 @@ public final class SendMailCommand implements CommandHandler {
} else { } else {
MailBuilder mailBuilder = mailBeingConstructed.get(senderId); MailBuilder mailBuilder = mailBeingConstructed.get(senderId);
if (args.size() >= 1) { if (!args.isEmpty()) {
switch (args.get(0).toLowerCase()) { switch (args.get(0).toLowerCase()) {
case "stop" -> { case "stop" -> {
mailBeingConstructed.remove(senderId); mailBeingConstructed.remove(senderId);
@ -107,14 +105,12 @@ public final class SendMailCommand implements CommandHandler {
getConstructionArgs(mailBuilder.constructionStage, sender))); getConstructionArgs(mailBuilder.constructionStage, sender)));
} }
} }
case "help" -> { case "help" -> CommandHandler.sendMessage(
CommandHandler.sendMessage( sender,
sender, translate(
translate( sender,
sender, "commands.sendMail.please_use",
"commands.sendMail.please_use", getConstructionArgs(mailBuilder.constructionStage, sender)));
getConstructionArgs(mailBuilder.constructionStage, sender)));
}
default -> { default -> {
switch (mailBuilder.constructionStage) { switch (mailBuilder.constructionStage) {
case 0 -> { case 0 -> {

View File

@ -4,7 +4,6 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.command.Command.TargetRequirement; import emu.grasscutter.command.Command.TargetRequirement;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
@Command( @Command(
@ -18,7 +17,7 @@ public final class SendMessageCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() == 0) { if (args.isEmpty()) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }

View File

@ -6,7 +6,6 @@ import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.*; import emu.grasscutter.game.world.*;
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify; import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
import java.util.List; import java.util.List;
@Command( @Command(
@ -18,7 +17,7 @@ import java.util.List;
public final class SetConstCommand implements CommandHandler { public final class SetConstCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) { if (args.isEmpty()) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }

View File

@ -1,15 +1,14 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify; import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "setFetterLevel", label = "setFetterLevel",
usage = {"<level>"}, usage = {"<level>"},

View File

@ -6,7 +6,6 @@ import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.tower.TowerLevelRecord; import emu.grasscutter.game.tower.TowerLevelRecord;
import emu.grasscutter.server.packet.send.*; import emu.grasscutter.server.packet.send.*;
import java.util.*; import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.IntStream; import java.util.stream.IntStream;
@ -292,9 +291,9 @@ public final class SetPropCommand implements CommandHandler {
} }
static class Prop { static class Prop {
String name; final String name;
PlayerProperty prop; final PlayerProperty prop;
PseudoProp pseudoProp; final PseudoProp pseudoProp;
public Prop(PlayerProperty prop) { public Prop(PlayerProperty prop) {
this(prop.toString(), prop, PseudoProp.NONE); this(prop.toString(), prop, PseudoProp.NONE);

View File

@ -0,0 +1,123 @@
package emu.grasscutter.command.commands;
import emu.grasscutter.command.*;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.scene.SceneTagData;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import java.util.*;
import lombok.val;
@Command(
label = "setSceneTag",
aliases = {"tag"},
usage = {"<add|remove|unlockall|reset> <sceneTagId>"},
permission = "player.setscenetag",
permissionTargeted = "player.setscenetag.others")
public final class SetSceneTagCommand implements CommandHandler {
private final Int2ObjectMap<SceneTagData> sceneTagData = GameData.getSceneTagDataMap();
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.isEmpty()) {
sendUsageMessage(sender);
return;
}
val actionStr = args.get(0).toLowerCase();
var value = -1;
if (args.size() > 1) {
try {
value = Integer.parseInt(args.get(1));
} catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
return;
}
} else {
if (actionStr.equals("unlockall")) {
unlockAllSceneTags(targetPlayer);
return;
} else if (actionStr.equals("reset") || actionStr.equals("restore")) {
resetAllSceneTags(targetPlayer);
return;
} else {
CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
return;
}
}
val userVal = value;
var sceneData =
sceneTagData.values().stream().filter(sceneTag -> sceneTag.getId() == userVal).findFirst();
if (sceneData.isEmpty()) {
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.id");
return;
}
int scene = sceneData.get().getSceneId();
switch (actionStr) {
case "add", "set" -> addSceneTag(targetPlayer, scene, value);
case "remove", "del" -> removeSceneTag(targetPlayer, scene, value);
default -> CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
}
CommandHandler.sendTranslatedMessage(sender, "commands.generic.set_to", value, actionStr);
}
private void addSceneTag(Player targetPlayer, int scene, int value) {
targetPlayer.getProgressManager().addSceneTag(scene, value);
}
private void removeSceneTag(Player targetPlayer, int scene, int value) {
targetPlayer.getProgressManager().delSceneTag(scene, value);
}
private void unlockAllSceneTags(Player targetPlayer) {
var allData = sceneTagData.values();
// Add all SceneTags
allData.stream()
.toList()
.forEach(
sceneTag -> {
targetPlayer
.getSceneTags()
.computeIfAbsent(sceneTag.getSceneId(), k -> new HashSet<>());
targetPlayer.getSceneTags().get(sceneTag.getSceneId()).add(sceneTag.getId());
});
// Remove default SceneTags, as most are "before" or "locked" states
allData.stream()
.filter(SceneTagData::isDefaultValid)
// 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()));
this.setSceneTags(targetPlayer);
}
private void resetAllSceneTags(Player targetPlayer) {
targetPlayer.getSceneTags().clear();
// targetPlayer.applyStartingSceneTags(); // private
GameData.getSceneTagDataMap().values().stream()
.filter(SceneTagData::isDefaultValid)
.forEach(
sceneTag -> {
targetPlayer
.getSceneTags()
.computeIfAbsent(sceneTag.getSceneId(), k -> new HashSet<>());
targetPlayer.getSceneTags().get(sceneTag.getSceneId()).add(sceneTag.getId());
});
this.setSceneTags(targetPlayer);
}
private void setSceneTags(Player targetPlayer) {
targetPlayer.sendPacket(new PacketPlayerWorldSceneInfoListNotify(targetPlayer));
}
}

View File

@ -6,7 +6,6 @@ import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import java.util.*; import java.util.*;
@Command( @Command(
@ -172,8 +171,8 @@ public final class SetStatsCommand implements CommandHandler {
} }
private static class Stat { private static class Stat {
String name; final String name;
FightProperty prop; final FightProperty prop;
public Stat(FightProperty prop) { public Stat(FightProperty prop) {
this.name = prop.toString(); this.name = prop.toString();

View File

@ -1,14 +1,13 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.Position; import emu.grasscutter.game.world.Position;
import emu.grasscutter.server.packet.send.PacketScenePlayerSoundNotify; import emu.grasscutter.server.packet.send.PacketScenePlayerSoundNotify;
import lombok.val;
import java.util.List; import java.util.List;
import lombok.val;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "sound", label = "sound",

View File

@ -1,5 +1,9 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.command.CommandHelpers.*;
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.*; import emu.grasscutter.data.excels.*;
@ -8,23 +12,18 @@ import emu.grasscutter.game.entity.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.*; import emu.grasscutter.game.props.*;
import emu.grasscutter.game.world.*; import emu.grasscutter.game.world.*;
import lombok.Setter;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import lombok.Setter;
import static emu.grasscutter.command.CommandHelpers.*;
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "spawn", label = "spawn",
aliases = {"drop", "s"}, aliases = {"drop", "s"},
usage = { usage = {
"<itemId> [x<amount>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>", "<itemId> [x<amount>] [blk<blockId>] [grp<groupId>] [cfg<configId>] [<x> <y> <z>] [<rotX> <rotY> <rotZ>]",
"<gadgetId> [x<amount>] [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>", "<gadgetId> [x<amount>] [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] [<x> <y> <z>] [<rotX> <rotY> <rotZ>]",
"<monsterId> [x<amount>] [lv<level>] [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>" "<monsterId> [x<amount>] [lv<level>] [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] [<x> <y> <z>] [<rotX> <rotY> <rotZ>]"
}, },
permission = "server.spawn", permission = "server.spawn",
permissionTargeted = "server.spawn.others") permissionTargeted = "server.spawn.others")
@ -50,18 +49,27 @@ public final class SpawnCommand implements CommandHandler {
parseIntParameters(args, param, intCommandHandlers); parseIntParameters(args, param, intCommandHandlers);
// At this point, first remaining argument MUST be the id and the rest the pos // 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 sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
Position pos = new Position(targetPlayer.getPosition());
Position rot = new Position(targetPlayer.getRotation());
switch (args.size()) { switch (args.size()) {
case 7:
try {
rot.setX(CommandHelpers.parseRelative(args.get(4), rot.getX()));
rot.setY(CommandHelpers.parseRelative(args.get(5), rot.getY()));
rot.setZ(CommandHelpers.parseRelative(args.get(6), rot.getZ()));
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(
sender, translate(sender, "commands.execution.argument_error"));
} // Fallthrough
case 4: case 4:
try { try {
float x, y, z; pos = CommandHelpers.parsePosition(args.get(1), args.get(2), args.get(3), pos, rot);
x = Float.parseFloat(args.get(1));
y = Float.parseFloat(args.get(2));
z = Float.parseFloat(args.get(3));
param.pos = new Position(x, y, z);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.execution.argument_error")); sender, translate(sender, "commands.execution.argument_error"));
@ -78,6 +86,8 @@ public final class SpawnCommand implements CommandHandler {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
param.pos = pos;
param.rot = rot;
MonsterData monsterData = GameData.getMonsterDataMap().get(param.id); MonsterData monsterData = GameData.getMonsterDataMap().get(param.id);
GadgetData gadgetData = GameData.getGadgetDataMap().get(param.id); GadgetData gadgetData = GameData.getGadgetDataMap().get(param.id);
@ -103,12 +113,8 @@ public final class SpawnCommand implements CommandHandler {
} }
double maxRadius = Math.sqrt(param.amount * 0.2 / Math.PI); double maxRadius = Math.sqrt(param.amount * 0.2 / Math.PI);
if (param.pos == null) {
param.pos = targetPlayer.getPosition();
}
for (int i = 0; i < param.amount; i++) { for (int i = 0; i < param.amount; i++) {
Position pos = GetRandomPositionInCircle(param.pos, maxRadius).addY(3); pos = GetRandomPositionInCircle(param.pos, maxRadius).addY(3);
GameEntity entity = null; GameEntity entity = null;
if (itemData != null) { if (itemData != null) {
entity = createItem(itemData, param, pos); entity = createItem(itemData, param, pos);
@ -129,12 +135,12 @@ public final class SpawnCommand implements CommandHandler {
} }
private EntityItem createItem(ItemData itemData, SpawnParameters param, Position pos) { private EntityItem createItem(ItemData itemData, SpawnParameters param, Position pos) {
return new EntityItem(param.scene, null, itemData, pos, 1, true); return new EntityItem(param.scene, null, itemData, pos, param.rot, 1, true);
} }
private EntityMonster createMonster( private EntityMonster createMonster(
MonsterData monsterData, SpawnParameters param, Position pos) { MonsterData monsterData, SpawnParameters param, Position pos) {
var entity = new EntityMonster(param.scene, monsterData, pos, param.lvl); var entity = new EntityMonster(param.scene, monsterData, pos, param.rot, param.lvl);
if (param.ai != -1) { if (param.ai != -1) {
entity.setAiId(param.ai); entity.setAiId(param.ai);
} }
@ -145,16 +151,13 @@ public final class SpawnCommand implements CommandHandler {
GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) { GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) {
EntityBaseGadget entity; EntityBaseGadget entity;
if (gadgetData.getType() == EntityType.Vehicle) { if (gadgetData.getType() == EntityType.Vehicle) {
entity = entity = new EntityVehicle(param.scene, targetPlayer, param.id, 0, pos, param.rot);
new EntityVehicle(
param.scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation());
} else { } else {
entity = new EntityGadget(param.scene, param.id, pos, targetPlayer.getRotation()); entity = new EntityGadget(param.scene, param.id, pos, param.rot);
if (param.state != -1) { if (param.state != -1) {
((EntityGadget) entity).setState(param.state); ((EntityGadget) entity).setState(param.state);
} }
} }
return entity; return entity;
} }
@ -208,6 +211,7 @@ public final class SpawnCommand implements CommandHandler {
@Setter public int def = -1; @Setter public int def = -1;
@Setter public int ai = -1; @Setter public int ai = -1;
@Setter public Position pos = null; @Setter public Position pos = null;
@Setter public Position rot = null;
public Scene scene = null; public Scene scene = null;
} }
} }

View File

@ -1,13 +1,12 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "stop", label = "stop",
aliases = {"shutdown"}, aliases = {"shutdown"},

View File

@ -6,7 +6,6 @@ import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.utils.lang.Language; import emu.grasscutter.utils.lang.Language;
import java.util.List; import java.util.List;
@Command( @Command(
@ -28,7 +27,7 @@ public final class TalentCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) { if (args.isEmpty()) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
@ -46,9 +45,7 @@ public final class TalentCommand implements CommandHandler {
String cmdSwitch = args.get(0).toLowerCase(); String cmdSwitch = args.get(0).toLowerCase();
switch (cmdSwitch) { switch (cmdSwitch) {
default -> { default -> sendUsageMessage(sender);
sendUsageMessage(sender);
}
case "set" -> { case "set" -> {
if (args.size() < 3) { if (args.size() < 3) {
sendUsageMessage(sender); sendUsageMessage(sender);

View File

@ -1,13 +1,12 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.packet.send.PacketChangeMpTeamAvatarRsp; import emu.grasscutter.server.packet.send.PacketChangeMpTeamAvatarRsp;
import java.util.*; import java.util.*;
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
@Command( @Command(
label = "team", label = "team",
usage = {"add <avatarId,...>", "(remove|set) [index|first|last|index-index,...]"}, usage = {"add <avatarId,...>", "(remove|set) [index|first|last|index-index,...]"},

View File

@ -1,13 +1,12 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType; import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "teleportAll", label = "teleportAll",
aliases = {"tpall"}, aliases = {"tpall"},

View File

@ -1,14 +1,13 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.Position; import emu.grasscutter.game.world.Position;
import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType; import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "teleport", label = "teleport",
aliases = {"tp"}, aliases = {"tp"},
@ -17,24 +16,10 @@ import static emu.grasscutter.utils.lang.Language.translate;
permissionTargeted = "player.teleport.others") permissionTargeted = "player.teleport.others")
public final class TeleportCommand implements CommandHandler { public final class TeleportCommand implements CommandHandler {
private float parseRelative(
String input, Float current) { // TODO: Maybe this will be useful elsewhere later
if (input.contains("~")) { // Relative
if (!input.equals("~")) { // Relative with offset
current += Float.parseFloat(input.replace("~", ""));
} // Else no offset, no modification
} else { // Absolute
current = Float.parseFloat(input);
}
return current;
}
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
Position pos = targetPlayer.getPosition(); Position pos = new Position(targetPlayer.getPosition());
float x = pos.getX(); Position rot = new Position(targetPlayer.getRotation());
float y = pos.getY();
float z = pos.getZ();
int sceneId = targetPlayer.getSceneId(); int sceneId = targetPlayer.getSceneId();
switch (args.size()) { switch (args.size()) {
@ -47,9 +32,7 @@ public final class TeleportCommand implements CommandHandler {
} // Fallthrough } // Fallthrough
case 3: case 3:
try { try {
x = this.parseRelative(args.get(0), x); pos = CommandHelpers.parsePosition(args.get(0), args.get(1), args.get(2), pos, rot);
y = this.parseRelative(args.get(1), y);
z = this.parseRelative(args.get(2), z);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.teleport.invalid_position")); sender, translate(sender, "commands.teleport.invalid_position"));
@ -60,11 +43,10 @@ public final class TeleportCommand implements CommandHandler {
return; return;
} }
Position target_pos = new Position(x, y, z);
boolean result = boolean result =
targetPlayer targetPlayer
.getWorld() .getWorld()
.transferPlayerToScene(targetPlayer, sceneId, TeleportType.COMMAND, target_pos); .transferPlayerToScene(targetPlayer, sceneId, TeleportType.COMMAND, pos);
if (!result) { if (!result) {
CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.exists_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.exists_error"));
@ -72,7 +54,13 @@ public final class TeleportCommand implements CommandHandler {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, sender,
translate( translate(
sender, "commands.teleport.success", targetPlayer.getNickname(), x, y, z, sceneId)); sender,
"commands.teleport.success",
targetPlayer.getNickname(),
pos.getX(),
pos.getY(),
pos.getZ(),
sceneId));
} }
} }
} }

View File

@ -1,16 +1,15 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.activity.trialavatar.*; import emu.grasscutter.game.activity.trialavatar.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActivityType; import emu.grasscutter.game.props.ActivityType;
import emu.grasscutter.server.packet.send.PacketActivityInfoNotify; import emu.grasscutter.server.packet.send.PacketActivityInfoNotify;
import emu.grasscutter.utils.JsonUtils; import emu.grasscutter.utils.JsonUtils;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "trialAvatarActivity", label = "trialAvatarActivity",
aliases = {"taa"}, aliases = {"taa"},
@ -132,7 +131,7 @@ public final class TrialAvatarActivityCommand implements CommandHandler {
translate( translate(
sender, "commands.trialAvatarActivity.success_reward", Integer.parseInt(param))); sender, "commands.trialAvatarActivity.success_reward", Integer.parseInt(param)));
} else { } else {
if (!param.toLowerCase().equals("all")) { if (!param.equalsIgnoreCase("all")) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.invalid_param")); sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
return; return;

View File

@ -3,7 +3,6 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
@Command( @Command(

View File

@ -1,14 +1,13 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.lang.Language.translate;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.game.player.*; import emu.grasscutter.game.player.*;
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify; import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
import java.util.*; import java.util.*;
import static emu.grasscutter.utils.lang.Language.translate;
@Command( @Command(
label = "unlockall", label = "unlockall",
usage = {""}, usage = {""},

View File

@ -3,7 +3,6 @@ package emu.grasscutter.command.commands;
import emu.grasscutter.command.*; import emu.grasscutter.command.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ClimateType; import emu.grasscutter.game.props.ClimateType;
import java.util.List; import java.util.List;
@Command( @Command(

View File

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

View File

@ -1,12 +1,11 @@
package emu.grasscutter.config; package emu.grasscutter.config;
import emu.grasscutter.utils.FileUtils; import static emu.grasscutter.Grasscutter.config;
import emu.grasscutter.utils.FileUtils;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Locale; import java.util.Locale;
import static emu.grasscutter.Grasscutter.config;
/** /**
* A data container for the server's configuration. * A data container for the server's configuration.
* *

View File

@ -1,15 +1,19 @@
package emu.grasscutter.data; package emu.grasscutter.data;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.server.http.handlers.GachaHandler; import emu.grasscutter.utils.FileUtils;
import emu.grasscutter.tools.Tools; import emu.grasscutter.utils.JsonUtils;
import emu.grasscutter.utils.*; 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; import lombok.val;
import java.io.*;
import java.nio.file.*;
import java.util.*;
public class DataLoader { public class DataLoader {
/** /**
@ -18,7 +22,7 @@ public class DataLoader {
* *
* @param resourcePath The path to the data file to be loaded. * @param resourcePath The path to the data file to be loaded.
* @return InputStream of the data file. * @return InputStream of the data file.
* @throws FileNotFoundException * @throws FileNotFoundException If the file is not found.
* @see #load(String, boolean) * @see #load(String, boolean)
*/ */
public static InputStream load(String resourcePath) throws FileNotFoundException { public static InputStream load(String resourcePath) throws FileNotFoundException {
@ -27,22 +31,18 @@ public class DataLoader {
/** /**
* Creates an input stream reader for a data file. If the file isn't found within the /data * 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. * @param resourcePath The path to the data file to be loaded.
* @return InputStreamReader of the data file. * @return InputStreamReader of the data file.
* @throws IOException * @throws IOException If the file is not found.
* @throws FileNotFoundException * @throws FileNotFoundException If the file is not found.
* @see #load(String, boolean) * @see #load(String, boolean)
*/ */
public static InputStreamReader loadReader(String resourcePath) public static InputStreamReader loadReader(String resourcePath) throws IOException {
throws IOException, FileNotFoundException { InputStream is = load(resourcePath, true);
try { if (is == null) throw new FileNotFoundException("File not found: " + resourcePath);
InputStream is = load(resourcePath, true); return new InputStreamReader(is);
return new InputStreamReader(is);
} catch (FileNotFoundException exception) {
throw exception;
}
} }
/** /**
@ -52,7 +52,7 @@ public class DataLoader {
* @param useFallback If the file does not exist in the /data directory, should it use the default * @param useFallback If the file does not exist in the /data directory, should it use the default
* file in the jar? * file in the jar?
* @return InputStream of the data file. * @return InputStream of the data file.
* @throws FileNotFoundException * @throws FileNotFoundException If the file is not found.
*/ */
public static InputStream load(String resourcePath, boolean useFallback) public static InputStream load(String resourcePath, boolean useFallback)
throws FileNotFoundException { throws FileNotFoundException {
@ -92,7 +92,7 @@ public class DataLoader {
public static <T> List<T> loadTableToList(String resourcePath, Class<T> classType) public static <T> List<T> loadTableToList(String resourcePath, Class<T> classType)
throws IOException { throws IOException {
val path = FileUtils.getDataPathTsjJsonTsv(resourcePath); 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)) { return switch (FileUtils.getFileExtension(path)) {
case "json" -> JsonUtils.loadToList(path, classType); case "json" -> JsonUtils.loadToList(path, classType);
case "tsj" -> TsvUtils.loadTsjToListSetField(path, classType); case "tsj" -> TsvUtils.loadTsjToListSetField(path, classType);
@ -115,8 +115,6 @@ public class DataLoader {
} catch (Exception e) { } catch (Exception e) {
Grasscutter.getLogger().error("An error occurred while trying to check the data folder.", e); Grasscutter.getLogger().error("An error occurred while trying to check the data folder.", e);
} }
generateGachaMappings();
} }
private static void checkAndCopyData(String name) { private static void checkAndCopyData(String name) {
@ -125,23 +123,10 @@ public class DataLoader {
if (!Files.exists(filePath)) { if (!Files.exists(filePath)) {
var root = filePath.getParent(); var root = filePath.getParent();
if (root.toFile().mkdirs()) if (root.toFile().mkdirs()) Grasscutter.getLogger().info("Created data folder '{}'", root);
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()); FileUtils.copyResource("/defaults/data/" + name, filePath.toString());
} }
} }
private static void generateGachaMappings() {
var path = GachaHandler.getGachaMappingsPath();
if (!Files.exists(path)) {
try {
Grasscutter.getLogger().debug("Creating default '" + path + "' data");
Tools.createGachaMappings(path);
} catch (Exception exception) {
Grasscutter.getLogger().warn("Failed to create gacha mappings. \n" + exception);
}
}
}
} }

View File

@ -4,34 +4,54 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.binout.*; import emu.grasscutter.data.binout.*;
import emu.grasscutter.data.binout.config.*; import emu.grasscutter.data.binout.config.*;
import emu.grasscutter.data.binout.routes.Route; import emu.grasscutter.data.binout.routes.Route;
import emu.grasscutter.data.custom.*; import emu.grasscutter.data.custom.TrialAvatarActivityCustomData;
import emu.grasscutter.data.custom.TrialAvatarCustomData;
import emu.grasscutter.data.excels.*; import emu.grasscutter.data.excels.*;
import emu.grasscutter.data.excels.achievement.*; import emu.grasscutter.data.excels.achievement.AchievementData;
import emu.grasscutter.data.excels.activity.*; import emu.grasscutter.data.excels.achievement.AchievementGoalData;
import emu.grasscutter.data.excels.activity.ActivityCondExcelConfigData;
import emu.grasscutter.data.excels.activity.ActivityData;
import emu.grasscutter.data.excels.activity.ActivityShopData;
import emu.grasscutter.data.excels.activity.ActivityWatcherData;
import emu.grasscutter.data.excels.avatar.*; import emu.grasscutter.data.excels.avatar.*;
import emu.grasscutter.data.excels.codex.*; import emu.grasscutter.data.excels.codex.*;
import emu.grasscutter.data.excels.dungeon.*; import emu.grasscutter.data.excels.dungeon.*;
import emu.grasscutter.data.excels.giving.*; import emu.grasscutter.data.excels.giving.GivingData;
import emu.grasscutter.data.excels.monster.*; import emu.grasscutter.data.excels.giving.GivingGroupData;
import emu.grasscutter.data.excels.quest.*; import emu.grasscutter.data.excels.monster.MonsterCurveData;
import emu.grasscutter.data.excels.reliquary.*; import emu.grasscutter.data.excels.monster.MonsterData;
import emu.grasscutter.data.excels.monster.MonsterDescribeData;
import emu.grasscutter.data.excels.monster.MonsterSpecialNameData;
import emu.grasscutter.data.excels.quest.QuestData;
import emu.grasscutter.data.excels.quest.QuestGlobalVarData;
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
import emu.grasscutter.data.excels.reliquary.ReliquaryLevelData;
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
import emu.grasscutter.data.excels.reliquary.ReliquarySetData;
import emu.grasscutter.data.excels.scene.*; import emu.grasscutter.data.excels.scene.*;
import emu.grasscutter.data.excels.tower.*; import emu.grasscutter.data.excels.tower.TowerFloorData;
import emu.grasscutter.data.excels.tower.TowerLevelData;
import emu.grasscutter.data.excels.tower.TowerScheduleData;
import emu.grasscutter.data.excels.trial.*; import emu.grasscutter.data.excels.trial.*;
import emu.grasscutter.data.excels.weapon.*; import emu.grasscutter.data.excels.weapon.WeaponCurveData;
import emu.grasscutter.data.excels.world.*; import emu.grasscutter.data.excels.weapon.WeaponLevelData;
import emu.grasscutter.data.excels.weapon.WeaponPromoteData;
import emu.grasscutter.data.excels.world.WeatherData;
import emu.grasscutter.data.excels.world.WorldAreaData;
import emu.grasscutter.data.excels.world.WorldLevelData;
import emu.grasscutter.data.server.*; import emu.grasscutter.data.server.*;
import emu.grasscutter.game.dungeons.DungeonDropEntry; import emu.grasscutter.game.dungeons.DungeonDropEntry;
import emu.grasscutter.game.quest.*; import emu.grasscutter.game.quest.QuestEncryptionKey;
import emu.grasscutter.game.quest.RewindData;
import emu.grasscutter.game.quest.TeleportData;
import emu.grasscutter.game.quest.enums.QuestCond; import emu.grasscutter.game.quest.enums.QuestCond;
import emu.grasscutter.game.world.GroupReplacementData; import emu.grasscutter.game.world.GroupReplacementData;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import lombok.*;
import javax.annotation.Nullable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.*; import java.util.*;
import javax.annotation.Nullable;
import lombok.*;
@SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection"}) @SuppressWarnings({"unused", "MismatchedQueryAndUpdateOfCollection"})
public final class GameData { public final class GameData {
@ -194,6 +214,14 @@ public final class GameData {
private static final Int2ObjectMap<CookRecipeData> cookRecipeDataMap = private static final Int2ObjectMap<CookRecipeData> cookRecipeDataMap =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<CoopChapterData> coopChapterDataMap =
new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<CoopPointData> coopPointDataMap =
new Int2ObjectOpenHashMap<>();
@Getter @Getter
private static final Int2ObjectMap<CompoundData> compoundDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<CompoundData> compoundDataMap = new Int2ObjectOpenHashMap<>();
@ -258,14 +286,26 @@ public final class GameData {
private static final Int2ObjectMap<GuideTriggerData> guideTriggerDataMap = private static final Int2ObjectMap<GuideTriggerData> guideTriggerDataMap =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<HomeWorldAnimalData> homeWorldAnimalDataMap =
new Int2ObjectOpenHashMap<>();
@Getter @Getter
private static final Int2ObjectMap<HomeWorldBgmData> homeWorldBgmDataMap = private static final Int2ObjectMap<HomeWorldBgmData> homeWorldBgmDataMap =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<HomeWorldEventData> homeWorldEventDataMap =
new Int2ObjectOpenHashMap<>();
@Getter @Getter
private static final Int2ObjectMap<HomeWorldLevelData> homeWorldLevelDataMap = private static final Int2ObjectMap<HomeWorldLevelData> homeWorldLevelDataMap =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
@Getter
private static final Int2ObjectMap<HomeWorldModuleData> homeWorldModuleDataMap =
new Int2ObjectOpenHashMap<>();
@Getter @Getter
private static final Int2ObjectMap<HomeWorldNPCData> homeWorldNPCDataMap = private static final Int2ObjectMap<HomeWorldNPCData> homeWorldNPCDataMap =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
@ -529,8 +569,8 @@ public final class GameData {
private static final Int2IntMap trialAvatarIndexIdTrialActivityDataDataMap = private static final Int2IntMap trialAvatarIndexIdTrialActivityDataDataMap =
new Int2IntOpenHashMap(); new Int2IntOpenHashMap();
private static Map<Integer, List<Integer>> fetters = new HashMap<>(); private static final Map<Integer, List<Integer>> fetters = new HashMap<>();
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>(); private static final Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
// Getters with different names that stay for now // Getters with different names that stay for now
public static Int2ObjectMap<MainQuestData> getMainQuestDataMap() { public static Int2ObjectMap<MainQuestData> getMainQuestDataMap() {
@ -590,15 +630,21 @@ public final class GameData {
// Non-nullable value getters // Non-nullable value getters
public static int getAvatarLevelExpRequired(int level) { 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) { 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) { 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 // Generic getter
@ -615,7 +661,7 @@ public final class GameData {
field.setAccessible(false); field.setAccessible(false);
} catch (Exception e) { } catch (Exception e) {
Grasscutter.getLogger() Grasscutter.getLogger()
.error("Error fetching resource map for " + resourceDefinition.getSimpleName(), e); .error("Error fetching resource map for {}", resourceDefinition.getSimpleName(), e);
} }
return map; return map;
@ -673,8 +719,8 @@ public final class GameData {
/** /**
* Fetches the trial data * Fetches the trial data
* *
* @param trialAvatarIndexId * @param trialAvatarIndexId The ID of the trial avatar
* @return * @return The trial data for the trial avatar
*/ */
@Nullable public static TrialAvatarActivityDataData getTrialAvatarActivityDataByAvatarIndex( @Nullable public static TrialAvatarActivityDataData getTrialAvatarActivityDataByAvatarIndex(
int trialAvatarIndexId) { int trialAvatarIndexId) {

View File

@ -7,24 +7,23 @@ import emu.grasscutter.game.managers.blossom.BlossomConfig;
import emu.grasscutter.game.world.SpawnDataEntry; import emu.grasscutter.game.world.SpawnDataEntry;
import emu.grasscutter.utils.objects.WeightedList; import emu.grasscutter.utils.objects.WeightedList;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import lombok.*;
import java.util.*; import java.util.*;
import lombok.*;
public class GameDepot { public class GameDepot {
public static final int[] BLOCK_SIZE = new int[] {50, 500}; // Scales 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<>(); new Int2ObjectOpenHashMap<>();
private static Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot = private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
private static Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot = private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
@Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>(); @Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
@Getter @Getter
private static HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists = private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
new HashMap<>(); new HashMap<>();
@Getter @Setter private static BlossomConfig blossomConfig; @Getter @Setter private static BlossomConfig blossomConfig;
@ -51,7 +50,7 @@ public class GameDepot {
list.add(data); list.add(data);
} }
// Let the server owner know if theyre missing weights // Let the server owner know if theyre missing weights
if (relicMainPropDepot.size() == 0 || relicAffixDepot.size() == 0) { if (relicMainPropDepot.isEmpty() || relicAffixDepot.isEmpty()) {
Grasscutter.getLogger() Grasscutter.getLogger()
.error( .error(
"Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder."); "Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder.");

View File

@ -1,5 +1,8 @@
package emu.grasscutter.data; package emu.grasscutter.data;
import static emu.grasscutter.utils.FileUtils.*;
import static emu.grasscutter.utils.lang.Language.translate;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
@ -20,9 +23,6 @@ import emu.grasscutter.scripts.*;
import emu.grasscutter.utils.*; import emu.grasscutter.utils.*;
import it.unimi.dsi.fastutil.Pair; import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.ints.*;
import lombok.*;
import javax.script.*;
import java.io.*; import java.io.*;
import java.nio.file.*; import java.nio.file.*;
import java.util.*; import java.util.*;
@ -30,9 +30,8 @@ import java.util.Map.Entry;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.*; import java.util.stream.*;
import javax.script.*;
import static emu.grasscutter.utils.FileUtils.*; import lombok.*;
import static emu.grasscutter.utils.lang.Language.translate;
public final class ResourceLoader { public final class ResourceLoader {
@ -64,7 +63,7 @@ public final class ResourceLoader {
private static List<Set<Class<?>>> getResourceDefClassesPrioritySets() { private static List<Set<Class<?>>> getResourceDefClassesPrioritySets() {
val classes = Grasscutter.reflector.getSubTypesOf(GameResource.class); val classes = Grasscutter.reflector.getSubTypesOf(GameResource.class);
val priorities = ResourceType.LoadPriority.getInOrder(); 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()); val map = new LinkedHashMap<ResourceType.LoadPriority, Set<Class<?>>>(priorities.size());
priorities.forEach(p -> map.put(p, new HashSet<>())); priorities.forEach(p -> map.put(p, new HashSet<>()));
@ -141,36 +140,35 @@ public final class ResourceLoader {
getResourceDefClassesPrioritySets() getResourceDefClassesPrioritySets()
.forEach( .forEach(
classes -> { classes ->
classes.stream() classes.stream()
.parallel() .parallel()
.unordered() .unordered()
.forEach( .forEach(
c -> { c -> {
val type = c.getAnnotation(ResourceType.class); val type = c.getAnnotation(ResourceType.class);
if (type == null) return; if (type == null) return;
val map = GameData.getMapByResourceDef(c); val map = GameData.getMapByResourceDef(c);
if (map == null) return; if (map == null) return;
try { try {
loadFromResource(c, type, map, doReload); loadFromResource(c, type, map, doReload);
} catch (Exception e) { } catch (Exception e) {
errors.add(Pair.of(Arrays.toString(type.name()), e)); errors.add(Pair.of(Arrays.toString(type.name()), e));
} }
}); }));
});
errors.forEach( errors.forEach(
pair -> pair ->
Grasscutter.getLogger() 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 endTime = System.nanoTime();
long ns = (endTime - startTime); // divide by 1000000 to get milliseconds. 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") @SuppressWarnings("rawtypes")
protected static void loadFromResource( private static void loadFromResource(
Class<?> c, ResourceType type, Int2ObjectMap map, boolean doReload) throws Exception { Class<?> c, ResourceType type, Int2ObjectMap map, boolean doReload) throws Exception {
val simpleName = c.getSimpleName(); val simpleName = c.getSimpleName();
if (doReload || !loadedResources.contains(simpleName)) { if (doReload || !loadedResources.contains(simpleName)) {
@ -182,7 +180,7 @@ public final class ResourceLoader {
} }
@SuppressWarnings({"rawtypes", "unchecked"}) @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 { throws Exception {
val results = val results =
switch (FileUtils.getFileExtension(filename)) { switch (FileUtils.getFileExtension(filename)) {
@ -201,7 +199,7 @@ public final class ResourceLoader {
} }
@SuppressWarnings({"rawtypes", "unchecked"}) @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 { throws Exception {
JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c) JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c)
.forEach( .forEach(
@ -284,7 +282,7 @@ public final class ResourceLoader {
} }
}); });
Grasscutter.getLogger() Grasscutter.getLogger()
.debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneRouteDatas."); .debug("Loaded {} SceneRouteDatas.", GameData.getSceneNpcBornData().size());
} catch (IOException e) { } catch (IOException e) {
Grasscutter.getLogger().error("Failed to load SceneRouteData folder."); Grasscutter.getLogger().error("Failed to load SceneRouteData folder.");
} }
@ -405,7 +403,7 @@ public final class ResourceLoader {
.forEach(data -> loadAbilityData(data.Default)); .forEach(data -> loadAbilityData(data.Default));
} catch (IOException e) { } catch (IOException e) {
Grasscutter.getLogger() Grasscutter.getLogger()
.error("Error loading ability modifiers from path " + path.toString() + ": ", e); .error("Error loading ability modifiers from path {}: ", path.toString(), e);
} }
} }
@ -414,7 +412,7 @@ public final class ResourceLoader {
GameData.getAbilityHashes().put(Utils.abilityHash(data.abilityName), data.abilityName); GameData.getAbilityHashes().put(Utils.abilityHash(data.abilityName), data.abilityName);
var modifiers = data.modifiers; var modifiers = data.modifiers;
if (modifiers == null || modifiers.size() == 0) return; if (modifiers == null || modifiers.isEmpty()) return;
var name = data.abilityName; var name = data.abilityName;
var modifierEntry = new AbilityModifierEntry(name); var modifierEntry = new AbilityModifierEntry(name);
@ -467,7 +465,7 @@ public final class ResourceLoader {
path, String.class, new TypeToken<List<TalentData>>() {}.getType())); path, String.class, new TypeToken<List<TalentData>>() {}.getType()));
} catch (IOException e) { } catch (IOException e) {
Grasscutter.getLogger() Grasscutter.getLogger()
.error("Error loading ability modifiers from path " + path.toString() + ": ", e); .error("Error loading ability modifiers from path {}: ", path.toString(), e);
} }
} }
@ -534,7 +532,7 @@ public final class ResourceLoader {
}); });
} catch (IOException e) { } catch (IOException e) {
Grasscutter.getLogger() Grasscutter.getLogger()
.error("Error loading open config: no files found in " + folderName); .error("Error loading open config: no files found in {}", folderName);
return; return;
} }
} }
@ -590,7 +588,7 @@ public final class ResourceLoader {
} }
Grasscutter.getLogger() Grasscutter.getLogger()
.debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas."); .debug("Loaded {} MainQuestDatas.", GameData.getMainQuestDataMap().size());
} }
public static void loadScriptSceneData() { public static void loadScriptSceneData() {
@ -608,7 +606,7 @@ public final class ResourceLoader {
} }
}); });
Grasscutter.getLogger() Grasscutter.getLogger()
.debug("Loaded " + GameData.getScriptSceneDataMap().size() + " ScriptSceneDatas."); .debug("Loaded {} ScriptSceneDatas.", GameData.getScriptSceneDataMap().size());
} catch (IOException e) { } catch (IOException e) {
Grasscutter.getLogger().debug("ScriptSceneData folder missing or empty."); Grasscutter.getLogger().debug("ScriptSceneData folder missing or empty.");
} }
@ -633,9 +631,8 @@ public final class ResourceLoader {
}); });
Grasscutter.getLogger() Grasscutter.getLogger()
.debug( .debug(
"Loaded " "Loaded {} HomeworldDefaultSaveDatas.",
+ GameData.getHomeworldDefaultSaveData().size() GameData.getHomeworldDefaultSaveData().size());
+ " HomeworldDefaultSaveDatas.");
} catch (IOException e) { } catch (IOException e) {
Grasscutter.getLogger().error("Failed to load HomeworldDefaultSave folder."); Grasscutter.getLogger().error("Failed to load HomeworldDefaultSave folder.");
} }
@ -648,7 +645,7 @@ public final class ResourceLoader {
path -> { path -> {
try { try {
val data = JsonUtils.loadToClass(path, SceneNpcBornData.class); val data = JsonUtils.loadToClass(path, SceneNpcBornData.class);
if (data.getBornPosList() == null || data.getBornPosList().size() == 0) { if (data.getBornPosList() == null || data.getBornPosList().isEmpty()) {
return; return;
} }
@ -660,7 +657,7 @@ public final class ResourceLoader {
} }
}); });
Grasscutter.getLogger() Grasscutter.getLogger()
.debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneNpcBornDatas."); .debug("Loaded {} SceneNpcBornDatas.", GameData.getSceneNpcBornData().size());
} catch (IOException e) { } catch (IOException e) {
Grasscutter.getLogger().error("Failed to load SceneNpcBorn folder."); Grasscutter.getLogger().error("Failed to load SceneNpcBorn folder.");
} }
@ -838,7 +835,6 @@ public final class ResourceLoader {
try { try {
JsonUtils.loadToList(getResourcePath("Server/SubfieldMapping.json"), SubfieldMapping.class) JsonUtils.loadToList(getResourcePath("Server/SubfieldMapping.json"), SubfieldMapping.class)
.forEach(entry -> subfieldMap.put(entry.getEntityId(), entry)); .forEach(entry -> subfieldMap.put(entry.getEntityId(), entry));
;
} catch (IOException | NullPointerException ignored) { } catch (IOException | NullPointerException ignored) {
} }
Grasscutter.getLogger().debug("Loaded {} subfield mappings.", subfieldMap.size()); Grasscutter.getLogger().debug("Loaded {} subfield mappings.", subfieldMap.size());
@ -852,7 +848,6 @@ public final class ResourceLoader {
JsonUtils.loadToList( JsonUtils.loadToList(
getResourcePath("Server/DropSubfieldMapping.json"), DropSubfieldMapping.class) getResourcePath("Server/DropSubfieldMapping.json"), DropSubfieldMapping.class)
.forEach(entry -> dropSubfieldMap.put(entry.getDropId(), entry)); .forEach(entry -> dropSubfieldMap.put(entry.getDropId(), entry));
;
} catch (IOException | NullPointerException ignored) { } catch (IOException | NullPointerException ignored) {
} }
Grasscutter.getLogger().debug("Loaded {} drop subfield mappings.", dropSubfieldMap.size()); Grasscutter.getLogger().debug("Loaded {} drop subfield mappings.", dropSubfieldMap.size());
@ -867,7 +862,6 @@ public final class ResourceLoader {
getResourcePath("Server/DropTableExcelConfigData.json"), getResourcePath("Server/DropTableExcelConfigData.json"),
DropTableExcelConfigData.class) DropTableExcelConfigData.class)
.forEach(entry -> dropTableExcelConfigDataMap.put(entry.getId(), entry)); .forEach(entry -> dropTableExcelConfigDataMap.put(entry.getId(), entry));
;
} catch (IOException | NullPointerException ignored) { } catch (IOException | NullPointerException ignored) {
} }
Grasscutter.getLogger() Grasscutter.getLogger()

View File

@ -3,7 +3,6 @@ package emu.grasscutter.data.binout;
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction; import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
import emu.grasscutter.game.ability.AbilityLocalIdGenerator; import emu.grasscutter.game.ability.AbilityLocalIdGenerator;
import emu.grasscutter.game.ability.AbilityLocalIdGenerator.ConfigAbilitySubContainerType; import emu.grasscutter.game.ability.AbilityLocalIdGenerator.ConfigAbilitySubContainerType;
import java.util.*; import java.util.*;
public class AbilityData { public class AbilityData {

View File

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

View File

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

View File

@ -3,12 +3,12 @@ package emu.grasscutter.data.binout;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.common.DynamicFloat; import emu.grasscutter.data.common.DynamicFloat;
import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.ElementType;
import java.io.Serial;
import java.io.Serializable;
import lombok.ToString; import lombok.ToString;
import java.io.Serializable;
public class AbilityModifier implements Serializable { public class AbilityModifier implements Serializable {
private static final long serialVersionUID = -2001232313615923575L; @Serial private static final long serialVersionUID = -2001232313615923575L;
public State state; public State state;
@ -43,6 +43,7 @@ public class AbilityModifier implements Serializable {
public String stacking; public String stacking;
public AbilityMixinData[] modifierMixins; public AbilityMixinData[] modifierMixins;
public AbilityModifierProperty properties;
public ElementType elementType; public ElementType elementType;
public DynamicFloat elementDurability = DynamicFloat.ZERO; public DynamicFloat elementDurability = DynamicFloat.ZERO;
@ -264,7 +265,7 @@ public class AbilityModifier implements Serializable {
TurnDirectionToPos, TurnDirectionToPos,
UpdateReactionDamage, UpdateReactionDamage,
UseSkillEliteSet, UseSkillEliteSet,
WidgetSkillStart; WidgetSkillStart
} }
@SerializedName("$type") @SerializedName("$type")
@ -274,18 +275,20 @@ public class AbilityModifier implements Serializable {
@SerializedName( @SerializedName(
value = "amount", value = "amount",
alternate = {"PDLLIFICICJ", "cdRatio"}) alternate = {"LNFMOCKIAGK", "PDLLIFICICJ", "cdRatio"})
public DynamicFloat amount = DynamicFloat.ZERO; public DynamicFloat amount = DynamicFloat.ZERO;
@SerializedName(value = "amountByTargetCurrentHPRatio") @SerializedName(
value = "amountByTargetCurrentHPRatio",
alternate = {"GMFELAKANEF"})
public DynamicFloat amountByCasterAttackRatio = DynamicFloat.ZERO; public DynamicFloat amountByCasterAttackRatio = DynamicFloat.ZERO;
@SerializedName(value = "unused") @SerializedName(value = "unknown2")
public DynamicFloat amountByCasterCurrentHPRatio = DynamicFloat.ZERO; public DynamicFloat amountByCasterCurrentHPRatio = DynamicFloat.ZERO;
@SerializedName( @SerializedName(
value = "unknown", value = "amountByCasterMaxHPRatio",
alternate = {"HFNJHOGGFKB", "GEJGGCIOLKN"}) alternate = {"PKPBLCNMPIG", "HFNJHOGGFKB", "GEJGGCIOLKN"})
public DynamicFloat amountByCasterMaxHPRatio = DynamicFloat.ZERO; public DynamicFloat amountByCasterMaxHPRatio = DynamicFloat.ZERO;
public DynamicFloat amountByGetDamage = DynamicFloat.ZERO; public DynamicFloat amountByGetDamage = DynamicFloat.ZERO;
@ -293,7 +296,7 @@ public class AbilityModifier implements Serializable {
@SerializedName(value = "amountByTargetMaxHPRatio") @SerializedName(value = "amountByTargetMaxHPRatio")
public DynamicFloat amountByTargetCurrentHPRatio = DynamicFloat.ZERO; public DynamicFloat amountByTargetCurrentHPRatio = DynamicFloat.ZERO;
@SerializedName(value = "amountByCasterMaxHPRatio") @SerializedName(value = "unknown1", alternate = "GGLMMJHNGMO")
public DynamicFloat amountByTargetMaxHPRatio = DynamicFloat.ZERO; public DynamicFloat amountByTargetMaxHPRatio = DynamicFloat.ZERO;
public DynamicFloat limboByTargetMaxHPRatio = DynamicFloat.ZERO; public DynamicFloat limboByTargetMaxHPRatio = DynamicFloat.ZERO;
@ -326,6 +329,9 @@ public class AbilityModifier implements Serializable {
public String srcKey, dstKey; public String srcKey, dstKey;
public int skillID; public int skillID;
public int resistanceListID;
public int monsterID;
public int summonTag;
public AbilityModifierAction[] actions; public AbilityModifierAction[] actions;
public AbilityModifierAction[] successActions; public AbilityModifierAction[] successActions;
@ -368,6 +374,11 @@ public class AbilityModifier implements Serializable {
} }
} }
public static class AbilityModifierProperty implements Serializable {
public float Actor_HpThresholdRatio;
// Add more properties here when GC needs them.
}
public enum State { public enum State {
LockHP, LockHP,
Invincible, Invincible,

View File

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

View File

@ -1,10 +1,9 @@
package emu.grasscutter.data.binout; package emu.grasscutter.data.binout;
import javax.annotation.Nullable;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import javax.annotation.Nullable;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class ConfigGadget { public class ConfigGadget {

View File

@ -2,11 +2,10 @@ package emu.grasscutter.data.binout;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.game.world.Position; import emu.grasscutter.game.world.Position;
import java.util.List;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import java.util.List;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class HomeworldDefaultSaveData { public class HomeworldDefaultSaveData {

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