20 Commits

Author SHA1 Message Date
229303f934 Version 1.4.2
Update languages [skip actions]
Fix whitespace [skip actions]
Update README and fil-PH (#1901)
Remove references to old repo
Make Player lazyload correct Account (should fix #1900)
Lombokify Grasscutter.java some more
Update ru-RU.json (#1895)
Extend setConstCommand "all" (#1884)
add Quest command alias (#1891)
Added zh-CN translaton for non-translated strings (#1890)
Updated Polish Translation (#1889)
Added "s" alias to SpawnCommand (closes #1840)
fix: unlocking home bgm doesn't work. (#1886)
Fix edge case on FileUtils::getFilenameWithoutPath
Medicine revival&Login white screen (#1883)
Save avatar in forceConstellationLevel (closes #1881)
Fix IllegalStateException when execute toMap (#1879)
Fix StackOverFlow when execute /give all (#1878)
Version 1.4.2-dev [skip actions]
2022-10-26 12:31:30 +00:00
a9148e1b66 Update languages [skip actions] 2022-10-26 12:31:30 +00:00
d99a50b80f Fix whitespace [skip actions] 2022-10-26 12:31:30 +00:00
877f747d01 Update README and fil-PH (#1901)
* made it more  c l e a r e r

* add .

* Update README.md

* Capitalised HTTPS

* update actions to build

* fixed typo

Fixed the bullet point spacing, removed http://mitm.it as the download page don't exist anymore, added `mitmproxy-ca-cert.cer` and save script into the instruction.

* added additional info about mitmproxy

* minor fixes

* Update README_fil-PH

Synced with the README
Removed bad words, insults like saying the user has skill issues
Added some professionally

* grammar fix
2022-10-26 12:15:08 +10:30
18360a6231 Remove references to old repo 2022-10-26 12:08:51 +10:30
a2c4895c16 Make Player lazyload correct Account (should fix #1900) 2022-10-25 18:31:55 +10:30
a5579368bb Lombokify Grasscutter.java some more 2022-10-25 15:49:14 +10:30
ae51f4c046 Update ru-RU.json (#1895) 2022-10-25 10:54:22 +10:30
5b6698f583 Extend setConstCommand "all" (#1884)
* Extend give command "talent"

* Update src/main/java/emu/grasscutter/data/excels/AvatarSkillDepotData.java

Shorten IntStream for getCombatSkills

Co-authored-by: Luke H-W <Birdulon@users.noreply.github.com>

* Fix setSkillLevel to work during avatar construction
Shortening getCombatSkills

* changeSkillLevel now acts as intermediate operation to fetch skillIds

* setSkillLevel changes to allow out of range levels to be normalized

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

Removing recalcStats since it's redundant

Co-authored-by: Luke H-W <Birdulon@users.noreply.github.com>

* Major changes and cleanup:
- AvatarSkillDepotData: removed getCombatSkills since it's unused
- TalentCommand: shortened /talent all using getSkillsAndEnergySkill
- GiveCommand: changed changeSkillLevel to setSkillLevel
- Avatar: delete changeSkillLevel and moved the operation inside setSkillLevel,updated skillId to Integer to catch special cases from GiveCommand

* Small cleanup:
Removed the special case from Avatar to be handled inside of GiveCommand

* Added "all" parameter to SetConst

* Changed all to [all] int SetConstCommand usage

Co-authored-by: Luke H-W <Birdulon@users.noreply.github.com>

Co-authored-by: Luke H-W <Birdulon@users.noreply.github.com>
2022-10-24 14:28:39 +10:30
496cd671da add Quest command alias (#1891) 2022-10-24 12:32:35 +10:30
fd6ed2f15f Added zh-CN translaton for non-translated strings (#1890)
Added zh-CN translation for non-translated strings
2022-10-24 10:34:51 +10:30
ceed05cd15 Updated Polish Translation (#1889) 2022-10-24 10:33:15 +10:30
7d1a7b501b Added "s" alias to SpawnCommand (closes #1840) 2022-10-24 10:32:10 +10:30
8b520b3883 fix: unlocking home bgm doesn't work. (#1886)
* fix: unlocking home bgm doesn't work.

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

Co-authored-by: Luke H-W <Birdulon@users.noreply.github.com>

Co-authored-by: Luke H-W <Birdulon@users.noreply.github.com>
2022-10-23 15:08:17 +10:30
54ad108a14 Fix edge case on FileUtils::getFilenameWithoutPath 2022-10-22 17:15:43 +10:30
ccf182d692 Medicine revival&Login white screen (#1883)
* Update InventorySystem.java

-:[fix] Medicine revival

* Update GameMainQuest.java

-:[fix] Login white screen
2022-10-22 16:51:33 +10:30
c51f7610b2 Save avatar in forceConstellationLevel (closes #1881) 2022-10-22 12:45:27 +10:30
c331a7f288 Fix IllegalStateException when execute toMap (#1879) 2022-10-21 21:49:48 +10:30
be8fbcbc02 Fix StackOverFlow when execute /give all (#1878)
* Fix StackOverFlow when execute /give all

* Use more proper code
2022-10-20 20:22:10 +10:30
c5d30c44eb Version 1.4.2-dev [skip actions] 2022-10-18 14:56:27 +00:00
40 changed files with 180 additions and 191 deletions

View File

@ -37,13 +37,13 @@
**Note:** If you updated from an older version, delete `config.json` to regenerate it. **Note:** If you updated from an older version, delete `config.json` to regenerate it.
1. Get `grasscutter.jar` 1. Get `grasscutter.jar`
- Download from [actions](https://github.com/Grasscutters/Grasscutter/actions/workflows/build.yml) or [build the server by yourself](#building). - Download from [releases](https://github.com/Grasscutters/Grasscutter/releases/latest) or [actions](https://github.com/Grasscutters/Grasscutter/actions/workflows/build.yml) or [build the server by yourself](#building).
2. Create a `resources` folder in the directory where grasscutter.jar is located and move your `BinOutput, ExcelBinOutput, Readables, Scripts, Subtitle, TextMap` folders there *(Check the [wiki](https://github.com/Grasscutters/Grasscutter/wiki) for more details how to get those.)* 2. Create a `resources` folder in the directory where grasscutter.jar is located and move your `BinOutput, ExcelBinOutput, Readables, Scripts, Subtitle, TextMap` folders there *(Check the [wiki](https://github.com/Grasscutters/Grasscutter/wiki) for more details how to get those.)*
3. Run Grasscutter with `java -jar grasscutter.jar`. **Make sure mongodb service is running as well.** 3. Run Grasscutter with `java -jar grasscutter.jar`. **Make sure mongodb service is running as well.**
### Connecting with the client ### Connecting with the client
½. Create an account using [server console command](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting). ½. Create an account in the server console using this [command](https://github.com/Grasscutters/Grasscutter/wiki/Commands#:~:text=account%20%3Ccreate|delete%3E%20%3Cusername%3E%20[UID]).
1. Redirect traffic: (choose one only) 1. Redirect traffic: (choose one only)
- mitmdump: `mitmdump -s proxy.py -k` - mitmdump: `mitmdump -s proxy.py -k`
@ -58,7 +58,6 @@
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
``` ```
- Fiddler Classic: Run Fiddler Classic, turn on `Decrypt HTTPS traffic` in (Tools -> Options -> HTTPS) and change the default port in (Tools -> Options -> Connections) to anything other than `8888`, load [this script](https://github.com/Grasscutters/Grasscutter/wiki/Resources#fiddler-classic-jscript) (copy and paste the script in the `FiddlerScript` tab) and click the `Save Script` button. - Fiddler Classic: Run Fiddler Classic, turn on `Decrypt HTTPS traffic` in (Tools -> Options -> HTTPS) and change the default port in (Tools -> Options -> Connections) to anything other than `8888`, load [this script](https://github.com/Grasscutters/Grasscutter/wiki/Resources#fiddler-classic-jscript) (copy and paste the script in the `FiddlerScript` tab) and click the `Save Script` button.
- [Hosts file](https://github.com/Grasscutters/Grasscutter/wiki/Resources#hosts-file) - [Hosts file](https://github.com/Grasscutters/Grasscutter/wiki/Resources#hosts-file)
@ -67,7 +66,7 @@
- For mitmproxy: After setting up the network proxy and installing the certificate, check http://mitm.it/ if traffic is passing through mitmproxy. - For mitmproxy: After setting up the network proxy and installing the certificate, check http://mitm.it/ if traffic is passing through mitmproxy.
**You can also use `start.cmd` to start servers and proxy daemons automatically, but you have to set up `JAVA_HOME` enviroment and configure the `start_config.cmd` file.** **You can also use `start.cmd` to start servers and proxy daemons automatically, but you have to set up `JAVA_HOME` environment and configure the `start_config.cmd` file.**
### Building ### Building
@ -102,7 +101,6 @@ You can find the output jar in the root of the project folder.
# Quick Troubleshooting # Quick Troubleshooting
* If compiling wasn't successful, please check your JDK installation (Make sure its JDK 17 or higher and validated JDK's bin PATH variable) * If compiling wasn't successful, please check your JDK installation (Make sure its JDK 17 or higher and validated JDK's bin PATH variable).
* My client doesn't connect, doesn't login, 4206, etc... - Mostly your proxy daemon setup is *the issue*, if using * My client doesn't connect, doesn't login, 4206, etc... - Mostly your proxy daemon setup is *the issue*. If you're using Fiddler, change the default port to anything other than 8888.
Fiddler make sure it running on another port except 8888
* Startup sequence: MongoDB > Grasscutter > Proxy Daemon (mitmdump, fiddler, etc.) > Game * Startup sequence: MongoDB > Grasscutter > Proxy Daemon (mitmdump, fiddler, etc.) > Game

View File

@ -66,7 +66,7 @@ certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
-עריכת [קובץ הHosts](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) -עריכת [קובץ הHosts](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
2. תשנו את שרת בproxy שלכם ל`127.0.0.1:8080` 2. תשנו את שרת בproxy שלכם ל`127.0.0.1:8080`

View File

@ -63,7 +63,7 @@
- Fiddler Classic: Ejecuta Fiddler Classic, activa `Decrypt https traffic` en las opciones y cambia el puerto por defecto ahí (Herramientas -> Opciones -> Conexiones) a alguno que no sea `8888`, y carga [este script](https://github.lunatic.moe/fiddlerscript). - Fiddler Classic: Ejecuta Fiddler Classic, activa `Decrypt https traffic` en las opciones y cambia el puerto por defecto ahí (Herramientas -> Opciones -> Conexiones) a alguno que no sea `8888`, y carga [este script](https://github.lunatic.moe/fiddlerscript).
- [Archivo Hosts](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [Archivo Hosts](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
2. Establece el proxy de red a `127.0.0.1:8080` o el puerto de proxy que pusiste. 2. Establece el proxy de red a `127.0.0.1:8080` o el puerto de proxy que pusiste.

View File

@ -7,11 +7,9 @@
**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).
<b>(Basahin ha, hindi titingin lang)</b> ## Ang mga kasalukuyang features
## Ang mga current features * Logging in
* Login system
* Combat * Combat
* Friends list * Friends list
* Teleportation * Teleportation
@ -22,62 +20,61 @@
## Quick setup guide ## Quick setup guide
**Atensyon:** Kung di mo talaga kaya o hindi mo maintindihan ang wiki, maaari kang sumali sa aming server [Discord](https://discord.gg/T5vZU6UyeG). **Atensyon:** Para sa mga nangangailangan ng suporta, maaari kang sumali sa aming server [Discord](https://discord.gg/T5vZU6UyeG).
### Ang mga kailangan ### Ang mga kailangan
* Java SE - 17 ([link](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)) * [Java SE - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) or higher
**Atensyon:** Kung gusto mo lang **paganahin** ang server, then **jre** is pwede naman. **Atensyon:** Kung gusto mo lang **paganahin** ang server, pwede naman ang **jre**.
* [MongoDB](https://www.mongodb.com/try/download/community) (recommended 4.0+) * [MongoDB](https://www.mongodb.com/try/download/community) (recommended 4.0+)
* Proxy daemon: mitmproxy (mitmdump, recommended), Fiddler Classic, etc. * Proxy Daemon: [mitmproxy](https://mitmproxy.org/) (mitmdump, recommended), [Fiddler Classic](https://telerik-fiddler.s3.amazonaws.com/fiddler/FiddlerSetup.exe), etc.
### Running ### Running
**Atensyon:** Kung nag-update ka galing sa old version, paki-delete ang `config.json` para mag-regenerate ulit. **Atensyon:** Kung nag-update ka galing sa lumang version, paki-delete ang `config.json` para mag-regenerate ulit.
1. Get `grasscutter.jar` 1. Get `grasscutter.jar`
- Download ka from [actions](https://github.com/Grasscutters/Grasscutter/suites/6895963598/artifacts/267483297) - I-download mo sa [releases](https://github.com/Grasscutters/Grasscutter/releases/latest) o sa [actions](https://github.com/Grasscutters/Grasscutter/actions/workflows/build.yml) o [bumuo ng iyong sariling server](#building).
- [Build mo ung jar by yourself](#Building) 2. Gawa ka ng `resources` folder sa directory kung nasaan ang grasscutter.jar at ilagay ang `BinOutput, ExcelBinOutput, Readables, Scripts, Subtitle, TextMap` folders sa loob ng resources folder *(Tingnan mo ang [wiki](https://github.com/Grasscutters/Grasscutter/wiki) para malaman mo kung saan mo makukuha yan)*
2. Gawa ka ng `resources` folder sa directory kung nasaan ang grasscutter.jar at ilagay ang `BinOutput` at `ExcelBinOutput` sa loob ng resources folder *(Check mo ang [wiki](https://github.com/Grasscutters/Grasscutter/wiki) para malaman mo san mo makukuha yan)* 3. Paandarin ang Grasscutter gamit ang command na `java -jar grasscutter.jar`. **Siguraduhin mo na ang mongodb service ay naka-open din.**
3. Paandarin ang Grasscutter gamit ang command na `java -jar grasscutter.jar`. **Make sure na gumagana ang mongodb (Google mo nalang kung pano mo malalaman)**
### Connecting with the client ### Connecting with the client
½. Create ka ng account gamit ang [server console command](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting). ½. Gumawa ng account sa server console gamit ang [command](https://github.com/Grasscutters/Grasscutter/wiki/Commands#:~:text=account%20%3Ccreate|delete%3E%20%3Cusername%3E%20[UID]) na ito.
1. Redirect traffic: (choose one) 1. Redirect traffic: (pumili lang dapat ng isa)
- mitmdump: `mitmdump -s proxy.py -k` - mitmdump: `mitmdump -s proxy.py -k`
Trust CA certificate: - Trust CA certificate:
**Note:** Usually ang CA certificate ay nakalagay sa `%USERPROFILE%\ .mitmproxy`, o pwede mo naman i-download from `http://mitm.it` - Ang CA certificate ay nasa `%USERPROFILE%\.mitmproxy`, i-double click ang `mitmproxy-ca-cert.cer` para ma-[install](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) o...
Double click para ma-[install](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) or ... - Via command line *(kailangan ng administration privileges)*
- Gamit ang command line (cmd.exe)
```shell ```shell
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
``` ```
- Fiddler Classic: Paadarin ang Fiddler Classic, tsaka turn on mo yung `Decrypt https traffic` sa settings at baguhin mo yung default port na nakalagay (Tools -> Options -> Connections) to anything other than `8888`, at saka mo i-load [itong script](https://github.lunatic.moe/fiddlerscript). - Fiddler Classic: Paadarin ang Fiddler Classic, turn on mo yung `Decrypt https traffic` sa (Tools -> Options -> HTTPS) at baguhin mo ang default port na nakalagay (Tools -> Options -> Connections) sa anumang numero maliban sa `8888`, i-load ang [script](https://github.com/Grasscutters/Grasscutter/wiki/Resources#fiddler-classic-jscript) na ito (copy and paste ang script sa `FiddlerScript` tab) at i-click ang `Save Script` button.
- [Hosts file](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [Hosts file](https://github.com/Grasscutters/Grasscutter/wiki/Resources#hosts-file)
2. Set mo ung proxy sa `127.0.0.1:8080` or dun sa proxy port na iyong inilagay. 2. Set mo ung proxy sa `127.0.0.1:8080` or dun sa proxy port na iyong inilagay.
**pwede mo rin gamitin ang `start.cmd` to start the servers and proxy daemons automatically, pero kailagan mong i-setup ang JAVA_HOME enviroment** - Para sa mitmproxy: Pagkatapos mong i-setup ang network proxy at sa pag-install ng certificate, tingnan mo sa http://mitm.it/ kung ang traffic ay dumadaan sa mitmproxy.
**Pwede mo rin gamitin ang `start.cmd` to start the servers and proxy daemons automatically, pero kailagan mong i-setup ang JAVA_HOME environment at i-configure ang `start_config.cmd` file.**
### Building ### Building
Ang Grasscutter ay gumagamit ng gradle for depedencies at building. Ang Grasscutter ay gumagamit ng Gradle para sa depedencies at building.
**Mga kailangan:** **Mga kailangan:**
- [Java SE Development Kits - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) - [Java SE Development Kits - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) or higher
- [Git](https://git-scm.com/downloads) - [Git](https://git-scm.com/downloads)
##### Windows ##### Windows
@ -98,17 +95,12 @@ chmod +x gradlew
./gradlew jar # Compile jar ./gradlew jar # Compile jar
``` ```
Pag-katapos mong i-compile, check mo yung [project](https://github.com/grasscutters/grasscutter) directory at saka makikita mo ung jar na kinompile mo. Usually pag-dev version, ang dapat nakalagay jan ay `grasscutter-<version>-dev.jar`. Bulag ka pag-hindi mo pa yan nakita. Pag-katapos mong i-compile, check mo yung project directory at makikita mo yung jar na kinompile mo. Usually pag-dev version, ang dapat nakalagay diyan ay `grasscutter-<version>-dev.jar`.
### Atensyon: ang mga server commands ay nasa [wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)! ### Ang mga server commands ay nasa [wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands) na!
# Quick Troubleshooting # Quick Troubleshooting
* Kung hindi nag-compile, paki-check ung JDK installation mo (JDK 17 at JDK's bin PATH variable). Pag-hindi mo pa rin na-compile o hindi mo ma-gets, isa lang masasabi ko sayo, may skill issue+reading issue ka. * Kung hindi nag-compile, paki-check ung JDK installation mo (JDK 17 at JDK's bin PATH variable).
* Hindi ako maka-connect, ayaw mag-login, 4206, etc... - `Usually proxy may kasalanan nyan`, ito ung pinaka-malalang skill issue na pwede mong makuha, sa lahat ng problems sa gc. Kung ayaw mo nyan, basahin mo ito. * Hindi ako maka-connect, ayaw mag-login, 4206, etc... - Mostly ang proxy setup mo ang may kasalanan niyan, kung gamit mo ay Fiddler, paki-sigurado na naka-set ung port sa kahit ano except sa 8888.
* Ang pagkakasunud-sunod: MongoDB > Grasscutter > Proxy Daemon (mitmdump, fiddler, etc.) > Game
Kung <b>Fiddler user</b> ka, paki-sigurado na naka-set ung port sa kahit ano except sa `8888`. (8888 port is for hoyoverse spider logs, in case na hindi mo alam)
* Startup sequence: MongoDB > Grasscutter > Proxy daemon o Proxy service (mitmdump, fiddler, etc.)
<b> KUNG HINDI MO TALAGA MAINTINDIHAN, LUMAYAS KA NA DITO.........
PUTANG INA MO, TAGLISH NA NGA YAN. TAS HINDI MO PA MA-GETS LMAO</b>

View File

@ -63,7 +63,7 @@
- Fiddler Classic: Exécutez Fiddler Classic, Activez `Decrypt https traffic` dans les paramètres et changez le port par défaut ici (Tools -> Options -> Connections) à autre chose que `8888`, et chargez [ce script](https://github.lunatic.moe/fiddlerscript). - Fiddler Classic: Exécutez Fiddler Classic, Activez `Decrypt https traffic` dans les paramètres et changez le port par défaut ici (Tools -> Options -> Connections) à autre chose que `8888`, et chargez [ce script](https://github.lunatic.moe/fiddlerscript).
- [Fichier hosts](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [Fichier hosts](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
2. Définissez le proxy du réseau comme `127.0.0.1:8080` ou le port du proxy que vous avez spécifié. 2. Définissez le proxy du réseau comme `127.0.0.1:8080` ou le port du proxy que vous avez spécifié.

View File

@ -63,7 +63,7 @@
- Fiddler Classic: Jalankan Fiddler Classic, nyalakan `Decrypt https traffic` dalam setting dan ubah port default di sana (Tools -> Options -> Connections) ke apa pun selain `8888`, dan muat [skrip ini](https://github.lunatic.moe/fiddlerscript). - Fiddler Classic: Jalankan Fiddler Classic, nyalakan `Decrypt https traffic` dalam setting dan ubah port default di sana (Tools -> Options -> Connections) ke apa pun selain `8888`, dan muat [skrip ini](https://github.lunatic.moe/fiddlerscript).
- [File host](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [File host](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
2. Atur proxy jaringan ke `127.0.0.1:8080` atau port proxy yang anda tentukan. 2. Atur proxy jaringan ke `127.0.0.1:8080` atau port proxy yang anda tentukan.

View File

@ -63,7 +63,7 @@
- Fiddler Classic : Fiddler Classic을 실행한 후, Setting에서 `Decrypt https traffic` 옵션을 켜고, Tools -> Options -> Connections에 있는 기본 포트를 `8888`을 제외한 다른 포트로 지정합니다. 그리고 [이 스크립트](https://github.lunatic.moe/fiddlerscript)를 불러옵니다. - Fiddler Classic : Fiddler Classic을 실행한 후, Setting에서 `Decrypt https traffic` 옵션을 켜고, Tools -> Options -> Connections에 있는 기본 포트를 `8888`을 제외한 다른 포트로 지정합니다. 그리고 [이 스크립트](https://github.lunatic.moe/fiddlerscript)를 불러옵니다.
- [호스트 파일](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [호스트 파일](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
2. 네트워크 프록시를 `127.0.0.1:8080` 로 설정하거나 지정한 프록시 포트로 설정합니다. 2. 네트워크 프록시를 `127.0.0.1:8080` 로 설정하거나 지정한 프록시 포트로 설정합니다.

View File

@ -63,7 +63,7 @@
- Fiddler Classic: Uruchom Fiddler Classic, włącz `Decrypt https traffic` w ustawieniach oraz zmień domyślny port (Tools -> Options -> Connections) na dowolny inny niż `8888`, i wczytaj [ten skrypt](https://github.lunatic.moe/fiddlerscript) (w polu FiddlerScript). - Fiddler Classic: Uruchom Fiddler Classic, włącz `Decrypt https traffic` w ustawieniach oraz zmień domyślny port (Tools -> Options -> Connections) na dowolny inny niż `8888`, i wczytaj [ten skrypt](https://github.lunatic.moe/fiddlerscript) (w polu FiddlerScript).
- [Plik hosts](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [Plik hosts](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
2. Ustaw serwer proxy na `127.0.0.1:8080` albo inny wybrany przez ciebie port. 2. Ustaw serwer proxy na `127.0.0.1:8080` albo inny wybrany przez ciebie port.

View File

@ -63,7 +63,7 @@
- Fiddler Classic: Запустите Fiddler Classic, включите настройку `Decrypt https traffic` в опциях и измените порт по умолчанию (Меню -> Tools -> Options -> Connections) на что-то не равное `8888`, после чего запустите [этот скрипт](https://github.lunatic.moe/fiddlerscript) во вкладке FiddlerSrcipt. - Fiddler Classic: Запустите Fiddler Classic, включите настройку `Decrypt https traffic` в опциях и измените порт по умолчанию (Меню -> Tools -> Options -> Connections) на что-то не равное `8888`, после чего запустите [этот скрипт](https://github.lunatic.moe/fiddlerscript) во вкладке FiddlerSrcipt.
- [Файл hosts](https://github.com/Melledy/Grasscutter/wiki/Running#traffic-route-map) - [Файл hosts](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
2. Установите прокси сети в `127.0.0.1:8080`, либо в тот порт прокси, который вы задали. 2. Установите прокси сети в `127.0.0.1:8080`, либо в тот порт прокси, который вы задали.

View File

@ -43,7 +43,7 @@ sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
group = 'xyz.grasscutters' group = 'xyz.grasscutters'
version = '1.4.1' version = '1.4.2'
sourceCompatibility = 17 sourceCompatibility = 17
targetCompatibility = 17 targetCompatibility = 17

View File

@ -48,27 +48,27 @@ import static emu.grasscutter.config.Configuration.SERVER;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
public final class Grasscutter { public final class Grasscutter {
private static final Logger log = (Logger) LoggerFactory.getLogger(Grasscutter.class); @Getter private static final Logger logger = (Logger) LoggerFactory.getLogger(Grasscutter.class);
private static LineReader consoleLineReader = null; private static LineReader consoleLineReader = null;
private static Language language; @Getter @Setter private static Language language;
public static final File configFile = new File("./config.json"); public static final File configFile = new File("./config.json");
@Setter private static ServerRunMode runModeOverride = null; // Config override for run mode @Setter private static ServerRunMode runModeOverride = null; // Config override for run mode
private static int day; // Current day of week. @Getter private static int currentDayOfWeek;
@Getter @Setter private static String preferredLanguage; @Getter @Setter private static String preferredLanguage;
private static HttpServer httpServer; @Getter private static HttpServer httpServer;
private static GameServer gameServer; @Getter private static GameServer gameServer;
private static PluginManager pluginManager; @Getter private static PluginManager pluginManager;
@Getter private static CommandMap commandMap; @Getter private static CommandMap commandMap;
private static AuthenticationSystem authenticationSystem; @Getter @Setter private static AuthenticationSystem authenticationSystem;
private static PermissionHandler permissionHandler; @Getter @Setter private static PermissionHandler permissionHandler;
public static final Reflections reflector = new Reflections("emu.grasscutter"); public static final Reflections reflector = new Reflections("emu.grasscutter");
public static ConfigContainer config; @Getter public static ConfigContainer config;
static { static {
// Declare logback configuration. // Declare logback configuration.
@ -230,18 +230,6 @@ public final class Grasscutter {
* Getters for the various server components. * Getters for the various server components.
*/ */
public static ConfigContainer getConfig() {
return config;
}
public static Language getLanguage() {
return language;
}
public static void setLanguage(Language language) {
Grasscutter.language = language;
}
public static Language getLanguage(String langCode) { public static Language getLanguage(String langCode) {
return Language.getLanguage(langCode); return Language.getLanguage(langCode);
} }
@ -250,10 +238,6 @@ public final class Grasscutter {
return Grasscutter.runModeOverride != null ? Grasscutter.runModeOverride : SERVER.runMode; return Grasscutter.runModeOverride != null ? Grasscutter.runModeOverride : SERVER.runMode;
} }
public static Logger getLogger() {
return log;
}
public static LineReader getConsole() { public static LineReader getConsole() {
if (consoleLineReader == null) { if (consoleLineReader == null) {
Terminal terminal = null; Terminal terminal = null;
@ -274,38 +258,14 @@ public final class Grasscutter {
return consoleLineReader; return consoleLineReader;
} }
public static HttpServer getHttpServer() {
return httpServer;
}
public static GameServer getGameServer() {
return gameServer;
}
public static PluginManager getPluginManager() {
return pluginManager;
}
public static AuthenticationSystem getAuthenticationSystem() {
return authenticationSystem;
}
public static PermissionHandler getPermissionHandler() {
return permissionHandler;
}
public static int getCurrentDayOfWeek() {
return day;
}
/* /*
* Utility methods. * Utility methods.
*/ */
public static void updateDayOfWeek() { public static void updateDayOfWeek() {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
day = calendar.get(Calendar.DAY_OF_WEEK); Grasscutter.currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
Grasscutter.getLogger().debug("Set day of week to "+day); Grasscutter.getLogger().debug("Set day of week to "+currentDayOfWeek);
} }
public static void startConsole() { public static void startConsole() {
@ -346,24 +306,6 @@ public final class Grasscutter {
} }
} }
/**
* Sets the authentication system for the server.
*
* @param authenticationSystem The authentication system to use.
*/
public static void setAuthenticationSystem(AuthenticationSystem authenticationSystem) {
Grasscutter.authenticationSystem = authenticationSystem;
}
/**
* Sets the permission handler for the server.
*
* @param permissionHandler The permission handler to use.
*/
public static void setPermissionHandler(PermissionHandler permissionHandler) {
Grasscutter.permissionHandler = permissionHandler;
}
/* /*
* Enums for the configuration. * Enums for the configuration.
*/ */

View File

@ -9,7 +9,11 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "quest", usage = {"(add|finish) [<questId>]"}, permission = "player.quest", permissionTargeted = "player.quest.others") @Command(label = "quest",
aliases = {"q"},
usage = {"(add|finish) [<questId>]"},
permission = "player.quest",
permissionTargeted = "player.quest.others")
public final class QuestCommand implements CommandHandler { public final class QuestCommand implements CommandHandler {
@Override @Override

View File

@ -1,10 +1,7 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.AvatarTalentData;
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;
@ -12,14 +9,13 @@ import emu.grasscutter.game.world.Scene;
import emu.grasscutter.game.world.World; import emu.grasscutter.game.world.World;
import emu.grasscutter.server.packet.send.*; import emu.grasscutter.server.packet.send.*;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import java.util.List; import java.util.List;
@Command( @Command(
label = "setConst", label = "setConst",
aliases = {"setconstellation"}, aliases = {"setconstellation"},
usage = {"<constellation level>"}, usage = {"<constellation level> [all]"},
permission = "player.setconstellation", permission = "player.setconstellation",
permissionTargeted = "player.setconstellation.others") permissionTargeted = "player.setconstellation.others")
public final class SetConstCommand implements CommandHandler { public final class SetConstCommand implements CommandHandler {
@ -29,21 +25,28 @@ public final class SetConstCommand implements CommandHandler {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
try { try {
int constLevel = Integer.parseInt(args.get(0)); int constLevel = Integer.parseInt(args.get(0));
// Check if level is out of range
if (constLevel < -1 || constLevel > 6) { if (constLevel < -1 || constLevel > 6) {
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.range_error"); CommandHandler.sendTranslatedMessage(sender, "commands.setConst.range_error");
return; return;
} }
// If it's either empty or anything else other than "all" just do normal setConstellation
if (args.size() == 1) {
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity(); EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
if (entity == null) return; if (entity == null) return;
Avatar avatar = entity.getAvatar(); Avatar avatar = entity.getAvatar();
this.setConstellation(targetPlayer, avatar, constLevel); this.setConstellation(targetPlayer, avatar, constLevel);
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.success", avatar.getAvatarData().getName(), constLevel); CommandHandler.sendTranslatedMessage(sender, "commands.setConst.success", avatar.getAvatarData().getName(), constLevel);
return;
}
// Check if there's an additional argument which is "all", if it does then go setAllConstellation
if (args.size() > 1 && args.get(1).equalsIgnoreCase("all")) {
this.setAllConstellation(targetPlayer, constLevel);
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.successall", constLevel);
}
else sendUsageMessage(sender);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.level_error"); CommandHandler.sendTranslatedMessage(sender, "commands.setConst.level_error");
} }
@ -55,13 +58,7 @@ public final class SetConstCommand implements CommandHandler {
// force player to reload scene when necessary // force player to reload scene when necessary
if (constLevel < currentConstLevel) { if (constLevel < currentConstLevel) {
World world = player.getWorld(); this.reloadScene(player);
Scene scene = player.getScene();
Position pos = player.getPosition();
world.transferPlayerToScene(player, 1, pos);
world.transferPlayerToScene(player, scene.getId(), pos);
scene.broadcastPacket(new PacketSceneEntityAppearNotify(player));
} }
// ensure that all changes are visible to the player // ensure that all changes are visible to the player
@ -69,4 +66,24 @@ public final class SetConstCommand implements CommandHandler {
avatar.recalcStats(true); avatar.recalcStats(true);
avatar.save(); avatar.save();
} }
private void setAllConstellation(Player player, int constLevel) {
player.getAvatars().forEach(avatar -> {
avatar.forceConstellationLevel(constLevel);
avatar.recalcConstellations();
avatar.recalcStats(true);
avatar.save();
});
// Just reload scene once, shorter than having to check for each constLevel < currentConstLevel
this.reloadScene(player);
}
private void reloadScene(Player player) {
World world = player.getWorld();
Scene scene = player.getScene();
Position pos = player.getPosition();
world.transferPlayerToScene(player, 1, pos);
world.transferPlayerToScene(player, scene.getId(), pos);
scene.broadcastPacket(new PacketSceneEntityAppearNotify(player));
}
} }

View File

@ -25,7 +25,7 @@ import static emu.grasscutter.utils.Language.translate;
@Command( @Command(
label = "spawn", label = "spawn",
aliases = {"drop"}, 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>",
"<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>",

View File

@ -809,12 +809,14 @@ public class Avatar {
if (level < 0) { // Special case for resetConst to remove inactive depots too if (level < 0) { // Special case for resetConst to remove inactive depots too
this.talentIdList.clear(); this.talentIdList.clear();
this.recalcStats(); this.recalcStats();
this.save();
return; return;
} }
this.talentIdList.removeAll(this.getTalentIdList()); // Only remove constellations from active depot this.talentIdList.removeAll(this.getTalentIdList()); // Only remove constellations from active depot
for (int i = 0; i < level; i++) for (int i = 0; i < level; i++)
this.unlockConstellation(true); this.unlockConstellation(true);
this.recalcStats(); this.recalcStats();
this.save();
} }
public boolean sendSkillExtraChargeMap() { public boolean sendSkillExtraChargeMap() {

View File

@ -11,6 +11,7 @@ import emu.grasscutter.data.excels.HomeWorldLevelData;
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.packet.send.*; import emu.grasscutter.server.packet.send.*;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@ -20,6 +21,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@Entity(value = "homes", useDiscriminator = false) @Entity(value = "homes", useDiscriminator = false)
@Data @Data
@ -57,6 +59,7 @@ public class GameHome {
.ownerUid(uid) .ownerUid(uid)
.level(1) .level(1)
.sceneMap(new ConcurrentHashMap<>()) .sceneMap(new ConcurrentHashMap<>())
.unlockedHomeBgmList(new HashSet<>())
.build(); .build();
} }
@ -93,7 +96,7 @@ public class GameHome {
} }
public boolean addUnlockedHomeBgm(int homeBgmId) { public boolean addUnlockedHomeBgm(int homeBgmId) {
if (getUnlockedHomeBgmList().add(homeBgmId)) return false; if (!getUnlockedHomeBgmList().add(homeBgmId)) return false;
var player = this.getPlayer(); var player = this.getPlayer();
player.sendPacket(new PacketUnlockHomeBgmNotify(homeBgmId)); player.sendPacket(new PacketUnlockHomeBgmNotify(homeBgmId));
@ -102,20 +105,22 @@ public class GameHome {
return true; return true;
} }
public Set<Integer> getUnlockedHomeBgmListInfo() { public Set<Integer> getUnlockedHomeBgmList() {
if (this.unlockedHomeBgmList == null) { if (this.unlockedHomeBgmList == null) {
this.unlockedHomeBgmList = new HashSet<>(); this.unlockedHomeBgmList = new HashSet<>();
addAllDefaultUnlockedBgmIds(this.unlockedHomeBgmList); }
if (this.unlockedHomeBgmList.addAll(getDefaultUnlockedHomeBgmIds())) {
save(); save();
} }
return this.unlockedHomeBgmList; return this.unlockedHomeBgmList;
} }
private void addAllDefaultUnlockedBgmIds(Set<Integer> list) { private Set<Integer> getDefaultUnlockedHomeBgmIds() {
GameData.getHomeWorldBgmDataMap().forEach((id, data) -> { return GameData.getHomeWorldBgmDataMap().int2ObjectEntrySet().stream()
if (data.isDefaultUnlock()) .filter(e -> e.getValue().isDefaultUnlock())
list.add(id); .map(Int2ObjectMap.Entry::getIntKey)
}); .collect(Collectors.toUnmodifiableSet());
} }
} }

View File

@ -140,7 +140,14 @@ public class Inventory extends BasePlayerManager implements Iterable<GameItem> {
List<GameItem> changedItems = new ArrayList<>(); List<GameItem> changedItems = new ArrayList<>();
for (var item : items) { for (var item : items) {
if (item.getItemId() == 0) continue; if (item.getItemId() == 0) continue;
GameItem result = putItem(item); GameItem result = null;
try {
// putItem might throws exception
// ignore that exception and continue
result = putItem(item);
} catch (Exception e) {
e.printStackTrace();
}
if (result != null) { if (result != null) {
getPlayer().getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM, result.getItemId(), result.getCount()); getPlayer().getBattlePassManager().triggerMission(WatcherTriggerType.TRIGGER_OBTAIN_MATERIAL_NUM, result.getItemId(), result.getCount());
changedItems.add(result); changedItems.add(result);

View File

@ -314,7 +314,7 @@ public class Player {
public Account getAccount() { public Account getAccount() {
if (this.account == null) if (this.account == null)
this.account = DatabaseHelper.getAccountById(Integer.toString(this.id)); this.account = DatabaseHelper.getAccountById(this.accountId);
return this.account; return this.account;
} }

View File

@ -2,6 +2,8 @@ package emu.grasscutter.game.props.ItemUseAction;
import emu.grasscutter.game.props.ItemUseOp; import emu.grasscutter.game.props.ItemUseOp;
import emu.grasscutter.data.GameData;
public class ItemUseGainCostume extends ItemUseInt { public class ItemUseGainCostume extends ItemUseInt {
@Override @Override
public ItemUseOp getItemUseOp() { public ItemUseOp getItemUseOp() {
@ -14,7 +16,9 @@ public class ItemUseGainCostume extends ItemUseInt {
@Override @Override
public boolean useItem(UseItemParams params) { public boolean useItem(UseItemParams params) {
params.player.getInventory().addItem(this.i); // TODO: Currently this returns false for all virtual items - need to have a proper success/fail if (GameData.getAvatarCostumeDataMap().containsKey(this.i)) {
params.player.addCostume(this.i);
}
return true; return true;
} }
} }

View File

@ -2,6 +2,8 @@ package emu.grasscutter.game.props.ItemUseAction;
import emu.grasscutter.game.props.ItemUseOp; import emu.grasscutter.game.props.ItemUseOp;
import emu.grasscutter.data.GameData;
public class ItemUseGainFlycloak extends ItemUseInt { public class ItemUseGainFlycloak extends ItemUseInt {
@Override @Override
public ItemUseOp getItemUseOp() { public ItemUseOp getItemUseOp() {
@ -14,7 +16,9 @@ public class ItemUseGainFlycloak extends ItemUseInt {
@Override @Override
public boolean useItem(UseItemParams params) { public boolean useItem(UseItemParams params) {
params.player.getInventory().addItem(this.i); // TODO: Currently this returns false for all virtual items - need to have a proper success/fail if (GameData.getAvatarFlycloakDataMap().containsKey(this.i)) {
params.player.addFlycloak(this.i);
}
return true; return true;
} }
} }

View File

@ -16,10 +16,13 @@ public class ItemUseOpenRandomChest extends ItemUseInt {
@Override @Override
public boolean useItem(UseItemParams params) { // cash shop material bundles public boolean useItem(UseItemParams params) { // cash shop material bundles
var rewardItems = params.player.getServer().getShopSystem().getShopChestData(this.i).stream().map(GameItem::new).toList(); var data = params.player.getServer().getShopSystem().getShopChestData(this.i);
if (data == null)
return false;
var rewardItems = data.stream().map(GameItem::new).toList();
if (!rewardItems.isEmpty()) { if (!rewardItems.isEmpty()) {
params.player.getInventory().addItems(rewardItems, ActionReason.Shop); params.player.getInventory().addItems(rewardItems, ActionReason.Shop);
} }
return false; return true;
} }
} }

View File

@ -167,7 +167,7 @@ public class GameMainQuest {
boolean didRewind = false; boolean didRewind = false;
for (GameQuest quest : sortedByOrder) { for (GameQuest quest : sortedByOrder) {
int i = sortedByOrder.indexOf(quest); int i = sortedByOrder.indexOf(quest);
if ( i == sortedByOrder.size()) { if ( (i+1) >= sortedByOrder.size()) {
didRewind = quest.rewind(null); didRewind = quest.rewind(null);
} else { } else {
didRewind = quest.rewind(sortedByOrder.get(i+1)); didRewind = quest.rewind(sortedByOrder.get(i+1));

View File

@ -778,7 +778,7 @@ public class InventorySystem extends BaseGameSystem {
} }
int[] satiationParams = itemData.getSatiationParams(); int[] satiationParams = itemData.getSatiationParams();
if (satiationParams != null && target.isPresent()) { if (satiationParams != null && satiationParams.length > 0 && target.isPresent()) {
// Invoke and call player use food event. // Invoke and call player use food event.
var event = new PlayerUseFoodEvent(params.player, itemData, params.targetAvatar.getAsEntity()); event.call(); var event = new PlayerUseFoodEvent(params.player, itemData, params.targetAvatar.getAsEntity()); event.call();
if (event.isCanceled()) return false; if (event.isCanceled()) return false;

View File

@ -62,7 +62,7 @@ public class SceneBlock {
// Set groups // Set groups
this.groups = ScriptLoader.getSerializer().toList(SceneGroup.class, bindings.get("groups")).stream() this.groups = ScriptLoader.getSerializer().toList(SceneGroup.class, bindings.get("groups")).stream()
.collect(Collectors.toMap(x -> x.id, y -> y)); .collect(Collectors.toMap(x -> x.id, y -> y, (a, b) -> a));
this.groups.values().forEach(g -> g.block_id = this.id); this.groups.values().forEach(g -> g.block_id = this.id);
this.sceneGroupIndex = SceneIndexManager.buildIndex(3, this.groups.values(), g -> g.pos.toPoint()); this.sceneGroupIndex = SceneIndexManager.buildIndex(3, this.groups.values(), g -> g.pos.toPoint());

View File

@ -96,20 +96,20 @@ public class SceneGroup {
// Set // Set
this.monsters = ScriptLoader.getSerializer().toList(SceneMonster.class, this.bindings.get("monsters")).stream() this.monsters = ScriptLoader.getSerializer().toList(SceneMonster.class, this.bindings.get("monsters")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y)); .collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.monsters.values().forEach(m -> m.group = this); this.monsters.values().forEach(m -> m.group = this);
this.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, this.bindings.get("gadgets")).stream() this.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, this.bindings.get("gadgets")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y)); .collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.gadgets.values().forEach(m -> m.group = this); this.gadgets.values().forEach(m -> m.group = this);
this.triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, this.bindings.get("triggers")).stream() this.triggers = ScriptLoader.getSerializer().toList(SceneTrigger.class, this.bindings.get("triggers")).stream()
.collect(Collectors.toMap(x -> x.name, y -> y)); .collect(Collectors.toMap(x -> x.name, y -> y, (a, b) -> a));
this.triggers.values().forEach(t -> t.currentGroup = this); this.triggers.values().forEach(t -> t.currentGroup = this);
this.suites = ScriptLoader.getSerializer().toList(SceneSuite.class, this.bindings.get("suites")); this.suites = ScriptLoader.getSerializer().toList(SceneSuite.class, this.bindings.get("suites"));
this.regions = ScriptLoader.getSerializer().toList(SceneRegion.class, this.bindings.get("regions")).stream() this.regions = ScriptLoader.getSerializer().toList(SceneRegion.class, this.bindings.get("regions")).stream()
.collect(Collectors.toMap(x -> x.config_id, y -> y)); .collect(Collectors.toMap(x -> x.config_id, y -> y, (a, b) -> a));
this.regions.values().forEach(m -> m.group = this); this.regions.values().forEach(m -> m.group = this);
this.init_config = ScriptLoader.getSerializer().toObject(SceneInitConfig.class, this.bindings.get("init_config")); this.init_config = ScriptLoader.getSerializer().toObject(SceneInitConfig.class, this.bindings.get("init_config"));

View File

@ -60,7 +60,7 @@ public class SceneMeta {
} }
this.blocks = blocks.stream().collect(Collectors.toMap(b -> b.id, b -> b)); this.blocks = blocks.stream().collect(Collectors.toMap(b -> b.id, b -> b, (a, b) -> a));
this.sceneBlockIndex = SceneIndexManager.buildIndex(2, blocks, SceneBlock::toRectangle); this.sceneBlockIndex = SceneIndexManager.buildIndex(2, blocks, SceneBlock::toRectangle);
} catch (ScriptException exception) { } catch (ScriptException exception) {

View File

@ -17,7 +17,6 @@ public class HandlerChangeHomeBgmReq extends PacketHandler {
int homeBgmId = req.getUnk2700BJHAMKKECEI(); int homeBgmId = req.getUnk2700BJHAMKKECEI();
var home = session.getPlayer().getHome(); var home = session.getPlayer().getHome();
home.addUnlockedHomeBgm(homeBgmId); // Not sure if this is sane
home.getHomeSceneItem(session.getPlayer().getSceneId()).setHomeBgmId(homeBgmId); home.getHomeSceneItem(session.getPlayer().getSceneId()).setHomeBgmId(homeBgmId);
home.save(); home.save();

View File

@ -76,7 +76,7 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
mailBuilder.mail.mailContent.title = welcomeMail.title; mailBuilder.mail.mailContent.title = welcomeMail.title;
mailBuilder.mail.mailContent.sender = welcomeMail.sender; mailBuilder.mail.mailContent.sender = welcomeMail.sender;
// Please credit Grasscutter if changing something here. We don't condone commercial use of the project. // Please credit Grasscutter if changing something here. We don't condone commercial use of the project.
mailBuilder.mail.mailContent.content = welcomeMail.content + "\n<type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>"; mailBuilder.mail.mailContent.content = welcomeMail.content + "\n<type=\"browser\" text=\"GitHub\" href=\"https://github.com/Grasscutters/Grasscutter\"/>";
mailBuilder.mail.itemList.addAll(Arrays.asList(welcomeMail.items)); mailBuilder.mail.itemList.addAll(Arrays.asList(welcomeMail.items));
mailBuilder.mail.importance = 1; mailBuilder.mail.importance = 1;
player.sendMail(mailBuilder.mail); player.sendMail(mailBuilder.mail);

View File

@ -13,7 +13,7 @@ public class PacketUnlockedHomeBgmNotify extends BasePacket {
return; return;
} }
var unlocked = player.getHome().getUnlockedHomeBgmListInfo(); var unlocked = player.getHome().getUnlockedHomeBgmList();
var notify = Unk2700LOHBMOKOPLHServerNotify.Unk2700_LOHBMOKOPLH_ServerNotify.newBuilder() var notify = Unk2700LOHBMOKOPLHServerNotify.Unk2700_LOHBMOKOPLH_ServerNotify.newBuilder()
.addAllUnk2700KMEKMNONMGE(unlocked) .addAllUnk2700KMEKMNONMGE(unlocked)

View File

@ -167,9 +167,11 @@ public final class FileUtils {
} }
} }
@Deprecated // No current uses of this anyway
public static String getFilenameWithoutPath(String fileName) { public static String getFilenameWithoutPath(String fileName) {
if (fileName.indexOf(".") > 0) { int i = fileName.lastIndexOf(".");
return fileName.substring(0, fileName.lastIndexOf(".")); if (i > 0) {
return fileName.substring(0, i);
} else { } else {
return fileName; return fileName;
} }

View File

@ -264,6 +264,7 @@
"fail": "Failed to set constellation.", "fail": "Failed to set constellation.",
"failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.", "failed_success": "Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "Constellations for %s have been set to %s.", "success": "Constellations for %s have been set to %s.",
"successall": "Constellations for all characters have been set to %s.",
"description": "Sets constellation level for your current active character" "description": "Sets constellation level for your current active character"
}, },
"setFetterLevel": { "setFetterLevel": {

View File

@ -264,6 +264,7 @@
"fail": "Error al establecer la constelación.", "fail": "Error al establecer la constelación.",
"failed_success": "Las constelaciones de %s han sido establecidas a %s. Por favor reinicia el escenario para ver los cambios.", "failed_success": "Las constelaciones de %s han sido establecidas a %s. Por favor reinicia el escenario para ver los cambios.",
"success": "Las constelaciones de %s han sido establecidas a %s.", "success": "Las constelaciones de %s han sido establecidas a %s.",
"successall": "🇺🇸Constellations for all characters have been set to %s.",
"description": "Establece el nivel de constelación para tu personaje actual" "description": "Establece el nivel de constelación para tu personaje actual"
}, },
"setFetterLevel": { "setFetterLevel": {

View File

@ -264,6 +264,7 @@
"fail": "🇺🇸Failed to set constellation.", "fail": "🇺🇸Failed to set constellation.",
"failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.", "failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "🇺🇸Constellations for %s have been set to %s.", "success": "🇺🇸Constellations for %s have been set to %s.",
"successall": "🇺🇸Constellations for all characters have been set to %s.",
"description": "🇺🇸Sets constellation level for your current active character" "description": "🇺🇸Sets constellation level for your current active character"
}, },
"setFetterLevel": { "setFetterLevel": {

View File

@ -264,6 +264,7 @@
"fail": "星座の設定に失敗しました。", "fail": "星座の設定に失敗しました。",
"failed_success": "%s の星座は %s に設定されました。 シーンをリロードして変更を確認してください。", "failed_success": "%s の星座は %s に設定されました。 シーンをリロードして変更を確認してください。",
"success": "%s の星座は %s に設定されました。", "success": "%s の星座は %s に設定されました。",
"successall": "🇺🇸Constellations for all characters have been set to %s.",
"description": "現在アクティブなキャラクターの星座レベルを設定します" "description": "現在アクティブなキャラクターの星座レベルを設定します"
}, },
"setFetterLevel": { "setFetterLevel": {

View File

@ -264,6 +264,7 @@
"fail": "🇺🇸Failed to set constellation.", "fail": "🇺🇸Failed to set constellation.",
"failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.", "failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "🇺🇸Constellations for %s have been set to %s.", "success": "🇺🇸Constellations for %s have been set to %s.",
"successall": "🇺🇸Constellations for all characters have been set to %s.",
"description": "🇺🇸Sets constellation level for your current active character" "description": "🇺🇸Sets constellation level for your current active character"
}, },
"setFetterLevel": { "setFetterLevel": {

View File

@ -1,7 +1,7 @@
{ {
"messages": { "messages": {
"game": { "game": {
"address_bind": "🇺🇸Game Server started at \u001b[1m\u001b[33m%s:%s\u001b[0m", "address_bind": "Serwer gry został uruchomiony na \u001b[1m\u001b[33m%s:%s\u001b[0m",
"port_bind": "Serwer gry został uruchomiony na porcie %s.", "port_bind": "Serwer gry został uruchomiony na porcie %s.",
"connect": "Klient połączył się z %s.", "connect": "Klient połączył się z %s.",
"disconnect": "Klient rozłączył się z %s.", "disconnect": "Klient rozłączył się z %s.",
@ -9,7 +9,7 @@
"command_error": "Błąd komendy: " "command_error": "Błąd komendy: "
}, },
"dispatch": { "dispatch": {
"address_bind": "🇺🇸[Dispatch] Dispatch server started at \u001b[1m\u001b[33m%s:%s\u001b[0m", "address_bind": "[Dispatch] Serwer Dispatch został uruchomiony na \u001b[1m\u001b[33m%s:%s\u001b[0m",
"port_bind": "[Dispatch] Serwer Dispatch został uruchomiony na porcie %s.", "port_bind": "[Dispatch] Serwer Dispatch został uruchomiony na porcie %s.",
"request": "[Dispatch] Żądanie klienta %s (metoda %s): %s", "request": "[Dispatch] Żądanie klienta %s (metoda %s): %s",
"keystore": { "keystore": {
@ -264,6 +264,7 @@
"fail": "Nie udało się ustawić konstelacji.", "fail": "Nie udało się ustawić konstelacji.",
"failed_success": "Konstelacje dla %s zostały ustawione na %s. Proszę przeładować scenę aby zobaczyć zmiany.", "failed_success": "Konstelacje dla %s zostały ustawione na %s. Proszę przeładować scenę aby zobaczyć zmiany.",
"success": "Konstelacje dla %s zostały ustawione na %s.", "success": "Konstelacje dla %s zostały ustawione na %s.",
"successall": "🇺🇸Constellations for all characters have been set to %s.",
"description": "Ustawia poziom konstelacji dla aktywnej postaci" "description": "Ustawia poziom konstelacji dla aktywnej postaci"
}, },
"setFetterLevel": { "setFetterLevel": {
@ -292,8 +293,8 @@
"description": "Zatrzymaj serwer." "description": "Zatrzymaj serwer."
}, },
"talent": { "talent": {
"out_of_range": "🇺🇸Invalid talent level. Level should be in range of 1-15.", "out_of_range": "Nieprawidłowy poziom talentu. Poziom powinien mieścić się w zakresie 1-15.",
"set_id": "🇺🇸Set talent %s - \"%s\" to %s.", "set_id": "Ustawiono talent %s - \"%s\" to %s.",
"id_desc": "🇺🇸Talent %s - \"%s\" - \"%s\"", "id_desc": "🇺🇸Talent %s - \"%s\" - \"%s\"",
"invalid_skill_id": "Błędne ID umiejętności.", "invalid_skill_id": "Błędne ID umiejętności.",
"invalid_level": "Błędny poziom talentu.", "invalid_level": "Błędny poziom talentu.",
@ -384,19 +385,19 @@
} }
}, },
"plugin": { "plugin": {
"directory_failed": "🇺🇸Failed to create plugins directory: ", "directory_failed": "Nie udało się utworzyć lokalizacji z pluginami: ",
"unable_to_load": "🇺🇸Unable to load plugin.", "unable_to_load": "Nie udało się załadować pluginów.",
"invalid_config": "🇺🇸Plugin %s has an invalid config file.", "invalid_config": "Plugin %s ma nieprawidłową konfigurację.",
"invalid_main_class": "🇺🇸Plugin %s has an invalid main class.", "invalid_main_class": "Plugin %s ma nieprawidłową główną klasę.",
"missing_config": "🇺🇸Plugin %s lacks a valid config file.", "missing_config": "Pluginowi %s brakuje poprawnego pliku konfiguracji.",
"failed_to_load_plugin": "🇺🇸Failed to load plugin: %s", "failed_to_load_plugin": "Niepowodzenie w załadowaniu pluginu: %s",
"failed_to_load": "🇺🇸Failed to load a plugin.", "failed_to_load": "Niepowodzenie w załadowaniu pluginu.",
"failed_to_load_dependencies": "🇺🇸Failed to load plugins with dependencies.", "failed_to_load_dependencies": "Niepowodzenie w załadowaniu pluginu z zależnościami.",
"loading_plugin": "🇺🇸Loading plugin: %s", "loading_plugin": "Ładowanie pluginu: %s",
"failed_add_id": "🇺🇸Failed to add plugin identifier: %s", "failed_add_id": "Niepowodzenie w dodawaniu identyfikatora pluginu: %s",
"enabling_plugin": "🇺🇸Enabling plugin: %s", "enabling_plugin": "Włączanie pluginu: %s",
"enabling_failed": "🇺🇸Failed to enable plugin: %s", "enabling_failed": "Nie udało się załączyć pluginu: %s",
"disabling_plugin": "🇺🇸Disabling plugin: %s", "disabling_plugin": "Wyłączanie pluginu: %s",
"disabling_failed": "🇺🇸Failed to disable plugin: %s" "disabling_failed": "Nie udało się wyłączyć pluginu: %s"
} }
} }

View File

@ -264,6 +264,7 @@
"fail": "🇺🇸Failed to set constellation.", "fail": "🇺🇸Failed to set constellation.",
"failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.", "failed_success": "🇺🇸Constellations for %s have been set to %s. Please reload scene to see changes.",
"success": "🇺🇸Constellations for %s have been set to %s.", "success": "🇺🇸Constellations for %s have been set to %s.",
"successall": "🇺🇸Constellations for all characters have been set to %s.",
"description": "🇺🇸Sets constellation level for your current active character" "description": "🇺🇸Sets constellation level for your current active character"
}, },
"setFetterLevel": { "setFetterLevel": {

View File

@ -264,6 +264,7 @@
"fail": "Не удалось установить уровень созвездия.", "fail": "Не удалось установить уровень созвездия.",
"failed_success": "Созвездия для %s установлены на %s. Перезайдите чтобы изменения вступили в силу.", "failed_success": "Созвездия для %s установлены на %s. Перезайдите чтобы изменения вступили в силу.",
"success": "Созвездия для %s были установлены на %s.", "success": "Созвездия для %s были установлены на %s.",
"successall": "Созвездия для всех персонажей были установлены на %s.",
"description": "Задает уровень созвездия для активного персонажа" "description": "Задает уровень созвездия для активного персонажа"
}, },
"setFetterLevel": { "setFetterLevel": {

View File

@ -264,6 +264,7 @@
"fail": "命之座等级设置失败。", "fail": "命之座等级设置失败。",
"failed_success": "命之座 %s 已设置为 %s。", "failed_success": "命之座 %s 已设置为 %s。",
"success": "命之座 %s 已设置为 %s。", "success": "命之座 %s 已设置为 %s。",
"successall": "🇺🇸Constellations for all characters have been set to %s.",
"description": "为当前活跃角色设置命座等级" "description": "为当前活跃角色设置命座等级"
}, },
"setFetterLevel": { "setFetterLevel": {
@ -292,7 +293,7 @@
"description": "停止服务器" "description": "停止服务器"
}, },
"talent": { "talent": {
"out_of_range": "🇺🇸Invalid talent level. Level should be in range of 1-15.", "out_of_range": "无效的天赋等级。天赋等级必须在 1-15 之间。",
"set_id": "修改技能 %s - \"%s\" 至 %s。", "set_id": "修改技能 %s - \"%s\" 至 %s。",
"id_desc": "技能 %s - \"%s\" - \"%s\"", "id_desc": "技能 %s - \"%s\" - \"%s\"",
"invalid_skill_id": "无效的技能ID。", "invalid_skill_id": "无效的技能ID。",

View File

@ -264,6 +264,7 @@
"fail": "設定命座失敗。", "fail": "設定命座失敗。",
"failed_success": "%s的命之座已設定為成%s重新登入後將會生效。", "failed_success": "%s的命之座已設定為成%s重新登入後將會生效。",
"success": "%s的命之座已設定為成%s。", "success": "%s的命之座已設定為成%s。",
"successall": "🇺🇸Constellations for all characters have been set to %s.",
"description": "設定當前角色的命之座。" "description": "設定當前角色的命之座。"
}, },
"setFetterLevel": { "setFetterLevel": {