mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-07-04 05:53:42 +00:00
Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
175e7f5f09 | |||
665263d9ba | |||
a4ad781d61 | |||
465582b8da | |||
4320bc7d29 | |||
98fbc4e512 | |||
f3277dee9f | |||
0005fcf96f | |||
f065b2b16f | |||
e9d68936f6 | |||
47971dc931 | |||
fe169398ec | |||
ddc082fc97 | |||
0b806e21cf | |||
49ba0e55e8 | |||
ae2ab20b5b | |||
27d495742d | |||
f17339f1b6 | |||
f0775f70f3 | |||
fecf83cfa4 | |||
dfbe4022f3 | |||
e859d87ae3 | |||
acb3575c77 | |||
f725d9203d | |||
d62394e35e | |||
a4d5de06d1 | |||
73acfa1178 | |||
0d71d29932 | |||
d0a4da8a1f | |||
d332861ed8 | |||
47186a47b2 | |||
5090b17b80 | |||
5b9508d7a4 | |||
df7941bc1b | |||
9cac0953fa | |||
7cdb774b1f | |||
f40cdfd23d | |||
4e71a15479 | |||
6afa1bf276 |
14
build.gradle
14
build.gradle
@ -57,7 +57,7 @@ sourceCompatibility = JavaVersion.VERSION_17
|
|||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
|
||||||
group = 'io.grasscutter'
|
group = 'io.grasscutter'
|
||||||
version = '1.6.1'
|
version = '1.6.2'
|
||||||
|
|
||||||
java {
|
java {
|
||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
@ -335,10 +335,16 @@ tasks.register('generateHandbook') {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolve the NPM command.
|
||||||
|
var npm = 'npm'
|
||||||
|
if (Os.isFamily(Os.FAMILY_WINDOWS))
|
||||||
|
npm = 'npm.cmd'
|
||||||
|
|
||||||
def npmVersion = {
|
def npmVersion = {
|
||||||
try {
|
try {
|
||||||
return 'npm --version'.execute().text.trim()
|
return "${npm} --version".execute()
|
||||||
} catch (ignored) {
|
} catch (ignored) {
|
||||||
|
ignored.printStackTrace()
|
||||||
return 'NPM_NOT_FOUND'
|
return 'NPM_NOT_FOUND'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,10 +384,6 @@ tasks.register('generateHandbook') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build the handbook.
|
// Build the handbook.
|
||||||
var npm = 'npm'
|
|
||||||
if (Os.isFamily(Os.FAMILY_WINDOWS))
|
|
||||||
npm = 'npm.cmd'
|
|
||||||
|
|
||||||
exec {
|
exec {
|
||||||
workingDir 'src/handbook'
|
workingDir 'src/handbook'
|
||||||
commandLine npm, 'run', 'build'
|
commandLine npm, 'run', 'build'
|
||||||
|
@ -18,90 +18,57 @@
|
|||||||
* Apparition de monstres via la console
|
* Apparition de monstres via la console
|
||||||
* Inventaire (obtention d'objets/de personnages, amélioration d'objets/personnages, etc)
|
* Inventaire (obtention d'objets/de personnages, amélioration d'objets/personnages, etc)
|
||||||
|
|
||||||
## Guide de démarrage rapide
|
## Guide d'installation rapide
|
||||||
|
|
||||||
**Note:** Pour obtenir un support, rejoignez notre serveur [Discord](https://discord.gg/T5vZU6UyeG) (en anglais).
|
**Note:** Pour obtenir un support, rejoignez notre serveur [Discord](https://discord.gg/T5vZU6UyeG) (en anglais).
|
||||||
|
|
||||||
### Logiciels requis
|
### Démarage rapide (Automatique)
|
||||||
|
|
||||||
* Java SE - 17 ([link](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html))
|
- Téléchargez Java 17: https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
|
||||||
|
- Téléchargez [MongoDB Community Server](https://www.mongodb.com/try/download/community)
|
||||||
|
- Téléchargez la version du jeu REL3.7 (Le client de jeut peut être obtenu ici si vous ne l'avez pas): https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md
|
||||||
|
|
||||||
**Note:** Si vous voulez juste **l'exécuter**, Alors vous pouvez télécharger seulement le **jre**
|
- Téléchargez la [dernière version de Cultivation](https://github.com/Grasscutters/Cultivation/releases/latest). Ulilisez l'installateur en `.msi`.
|
||||||
|
- Après avoir ouvert Cultivation (en administrateur), appuyez sur le bouton de téléchargement en haut a droite.
|
||||||
|
- Cliquez sur le bouton `Téléchargez tout-en-un`
|
||||||
|
- Cliquez sur l'engrenage dans le coin en haut a droite.
|
||||||
|
- Définisez l'emplacement d'installation du jeu.
|
||||||
|
- Définisez le chemin Java personnalisé à `C:\Program Files\Java\jdk-17\bin\java.exe`
|
||||||
|
- Laissez tous les autres paramètes par défauts
|
||||||
|
|
||||||
* MongoDB (4.0+ recommandé)
|
- Appuyez sur le bouton a coté de Lancer.
|
||||||
|
- Appuyez sur le bouton Lancer.
|
||||||
|
- Connectez vous avec le nom d'utilisateur que vous voulez. Le mot de passe n'a pas d'importance.
|
||||||
|
|
||||||
* Proxy daemon: mitmproxy (mitmdump, recommended), Fiddler Classic, etc.
|
### Compilation
|
||||||
|
|
||||||
### Lancement
|
Grasscutter utilise Gradle pour la gestion des dépendances et la compilation.
|
||||||
|
|
||||||
**Note:** Si vous avez mis à jour depuis une ancienne version, supprimez `config.json` pour le regénérer.
|
**Prérequis**
|
||||||
|
|
||||||
1. Obtenez `grasscutter.jar`
|
- [Java SE Development Kits - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) ou plus récent
|
||||||
- Téléchargez le depuis les [actions](https://github.com/Grasscutters/Grasscutter/suites/6895963598/artifacts/267483297)
|
|
||||||
- [Buildez le par vous-même](#Building)
|
|
||||||
2. Créez un dossier `resources` dans le dossier où grasscutter.jar est situé et déplacez vos dossiers `BinOutput` et `ExcelBinOutput` ici *(Vérifiez le [wiki](https://github.com/Grasscutters/Grasscutter/wiki) pour plus de détails sur comment les obtenir.)*
|
|
||||||
3. Exécutez Grasscutter avec `java -jar grasscutter.jar`. **Soyez sûr que le service MongoDB est en cours d'exécution.**
|
|
||||||
|
|
||||||
### Connection avec le client
|
|
||||||
|
|
||||||
½. Créez un compte avec la [console de commande du serveur](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting).
|
|
||||||
|
|
||||||
1. Redirection du traffic: (Choisissez-en un)
|
|
||||||
- mitmdump: `mitmdump -s proxy.py -k`
|
|
||||||
|
|
||||||
Approuvez le certificat CA:
|
|
||||||
|
|
||||||
**Note:**Le certificat CA est généralement stocké sous `%USERPROFILE%\ .mitmproxy`, ou vous pouvez le télécharger depuis `http://mitm.it`
|
|
||||||
|
|
||||||
Double-cliquez pour [installer](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) oo ...
|
|
||||||
|
|
||||||
- Via la ligne de commande
|
|
||||||
|
|
||||||
```shell
|
|
||||||
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
|
||||||
```
|
|
||||||
|
|
||||||
- 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/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é.
|
|
||||||
|
|
||||||
**Vous pouvez aussi utiliser `start.cmd` to démarrer les serveurs et le proxy automatiquement, mais vous devez mettre en place la variable d'environnement JAVA_HOME**
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
Grasscutter utilise Gradle pour gérer les dépendances et la construction.
|
|
||||||
|
|
||||||
**Logiciels requis:**
|
|
||||||
|
|
||||||
- [Java SE Development Kits - 17](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
|
||||||
- [Git](https://git-scm.com/downloads)
|
- [Git](https://git-scm.com/downloads)
|
||||||
|
|
||||||
##### Windows
|
##### Windows
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git clone https://github.com/Grasscutters/Grasscutter.git
|
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
|
||||||
cd Grasscutter
|
cd Grasscutter
|
||||||
.\gradlew.bat # Mettre en place l'environnement
|
.\gradlew.bat # Setting up environments
|
||||||
.\gradlew jar # Compiler
|
.\gradlew jar # Compile
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Linux
|
##### Linux (GNU)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/Grasscutters/Grasscutter.git
|
git clone --recurse-submodules https://github.com/Grasscutters/Grasscutter.git
|
||||||
cd Grasscutter
|
cd Grasscutter
|
||||||
chmod +x gradlew
|
chmod +x gradlew
|
||||||
./gradlew jar # Compiler
|
./gradlew jar # Compile
|
||||||
```
|
```
|
||||||
|
|
||||||
Vous trouverez le fichier jar compilé à la racine du dossier du projet.
|
Vous pouvez trouver le jar de sortie dans la racine du dossier du projet.
|
||||||
|
|
||||||
### Les commandes ont été déplacé vers le [wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)! (en anglais)
|
### Dépanage
|
||||||
|
|
||||||
# Dépannage rapide
|
Pour une liste des problèmes communs et leur solution et pour demander de l'aide, veuillez rejoindre [notre serveur Discord](https://discord.gg/T5vZU6UyeG) (en anglais) et dirigez vous vers le salon de support.
|
||||||
|
|
||||||
* Si la compilation a échoué, veuillez vérifier votre installation de votre JDK (JDK 17 et le bon dossier bin du JDK dans la variable PATH)
|
|
||||||
* Mon client ne se connecte pas au serveur, impossible de se connecter a mon compte, 4206, etc... - La plupart du temps, *le problème* vient de la configuration de votre proxy. Si vous utilisez Fiddler, vérifiez s'il est exécuté sur un port autre que 8888
|
|
||||||
* Séquence de démarrage : MongoDB > Grasscutter > Proxy (mitmdump, fiddler, etc...) > Jeu
|
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
[EN](../README.md) | [简中](README_zh-CN.md) | [繁中](README_zh-TW.md) | [FR](README_fr-FR.md) | [ES](README_es-ES.md) | [HE](README_HE.md) | [RU](README_ru-RU.md) | [PL](README_pl-PL.md) | [ID](README_id-ID.md) | [KR](README_ko-KR.md) | [FIL/PH](README_fil-PH.md) | [NL](README_NL.md) | [JP](README_ja-JP.md) | [IT](README_it-IT.md) | [VI](README_vi-VN.md)
|
[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)
|
||||||
|
|
||||||
**Attenzione:** Diamo sempre il benvenuto ai contributori del progetto. Prima di aggiungere il tuo contributo, 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).
|
||||||
|
|
||||||
## Funzionalità attuali
|
## Funzionalità attuali
|
||||||
|
|
||||||
@ -15,12 +15,12 @@
|
|||||||
* Teletrasporto
|
* Teletrasporto
|
||||||
* Sistema Gacha
|
* Sistema Gacha
|
||||||
* Cooperativa *parzialmente* funzionale
|
* Cooperativa *parzialmente* funzionale
|
||||||
* Evoca mostri dalla console
|
* Evocazione nemici usando la console
|
||||||
* Funzionalità dell'inventario (ricevi oggetti/personaggi, aggiorna oggetti/personaggi, ecc.)
|
* Inventario (ricevi e aggiorna oggetti/personaggi, ecc.)
|
||||||
|
|
||||||
## Guida rapida all'installazione
|
## Guida rapida all'installazione
|
||||||
|
|
||||||
**Nota:** Per il supporto, unisciti al nostro [Discord](https://discord.gg/T5vZU6UyeG).
|
**Nota:** Se hai bisogno di aiuto, unisciti al nostro [Discord](https://discord.gg/T5vZU6UyeG).
|
||||||
|
|
||||||
### Requisiti
|
### Requisiti
|
||||||
|
|
||||||
@ -30,30 +30,30 @@
|
|||||||
|
|
||||||
* [MongoDB](https://www.mongodb.com/try/download/community) (consigliato 4.0+)
|
* [MongoDB](https://www.mongodb.com/try/download/community) (consigliato 4.0+)
|
||||||
|
|
||||||
* Servizio proxy: mitmproxy (mitmdump, consigliato), Fiddler Classic, ecc.
|
* Servizi proxy: mitmproxy (mitmdump, consigliato), Fiddler Classic, ecc.
|
||||||
|
|
||||||
### Esecuzione
|
### Esecuzione
|
||||||
|
|
||||||
**Nota:** Se hai eseguito l'aggiornamento da una versione precedente, rimuovi `config.json` in modo che venga generato di nuovo.
|
**Nota:** Se hai aggiornato da una versione precedente, elimina `config.json` in modo che venga generato di nuovo.
|
||||||
|
|
||||||
1. Ottieni "grasscutter.jar".
|
1. Ottieni "grasscutter.jar".
|
||||||
- Scarica da [azioni](https://github.com/Grasscutters/Grasscutter/suites/6895963598/artifacts/267483297)
|
- Scarica da [azioni](https://github.com/Grasscutters/Grasscutter/suites/6895963598/artifacts/267483297)
|
||||||
- [Compilalo tu stesso](#Compilazione)
|
- [Compilalo tu stesso](#Compilazione)
|
||||||
2. Crea una cartella `resources` nella directory in cui si trova grasscutter.jar e sposta lì le cartelle `BinOutput` ed `ExcelBinOutput` *(Vedi il [wiki](https://github.com/Grasscutters/Grasscutter/wiki ) per maggiori dettagli su come ottenerli.)*
|
2. Crea una cartella chiamata `resources` nella directory in cui si trova grasscutter.jar e sposta lì le cartelle `BinOutput` ed `ExcelBinOutput` *(Vedi il [wiki](https://github.com/Grasscutters/Grasscutter/wiki ) per maggiori dettagli su come ottenerli.)*
|
||||||
3. Eseguire Grasscutter con `java -jar grasscutter.jar`. **Assicurati che il servizio mongodb sia attivo.**
|
3. Esegui Grasscutter con `java -jar grasscutter.jar`. **Assicurati che il servizio mongodb sia attivo.**
|
||||||
|
|
||||||
### Connessione client
|
### Connessione al client
|
||||||
|
|
||||||
½. Crea un account usando [il comando corrispondente nella console del server](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting).
|
½. Crea un account usando [il comando corrispondente nella console del server](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting).
|
||||||
|
|
||||||
1. Reindirizza il traffico: (scegli uno)
|
1. Reindirizza il traffico: (scegli uno)
|
||||||
- mitmdump: `mitmdump -s proxy.py -k`
|
- Con mitmdump: `mitmdump -s proxy.py -k`
|
||||||
|
|
||||||
Autorizza il certificato CA:
|
Autorizza il certificato CA:
|
||||||
|
|
||||||
**Nota:**Il certificato CA si trova solitamente in `%USERPROFILE%\ .mitmproxy`, oppure puoi scaricarlo da `http://mitm.it`
|
**Nota:**Il certificato CA si trova solitamente in `%USERPROFILE%\ .mitmproxy`, oppure puoi scaricarlo da `http://mitm.it`
|
||||||
|
|
||||||
Fare doppio clic su [installa](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) o ...
|
Fai doppio clic su [installa](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate) o ...
|
||||||
|
|
||||||
- Con riga di comando
|
- Con riga di comando
|
||||||
|
|
||||||
@ -61,11 +61,11 @@
|
|||||||
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
||||||
```
|
```
|
||||||
|
|
||||||
- Fiddler Classic: esegui Fiddler Classic, abilita `Decrypt https traffic` nelle opzioni e cambia la porta predefinita in (Strumenti -> Opzioni -> Connessioni) in qualcosa di diverso da `8888`, e carica [questo script](https :/ /github.lunatic.moe/fiddlerscript).
|
- Con Fiddler Classic: esegui Fiddler Classic, abilita `Decrypt https traffic` nelle opzioni e cambia la porta predefinita in (Strumenti -> Opzioni -> Connessioni) in qualcosa di diverso da `8888`, e carica [questo script](https://github.lunatic.moe/fiddlerscript).
|
||||||
|
|
||||||
- [File host](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
|
- [File host](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
|
||||||
|
|
||||||
2. Impostare il proxy di rete su `127.0.0.1:8080` o la porta proxy impostata.
|
2. Imposta il proxy di rete a `127.0.0.1:8080` o la porta proxy impostata.
|
||||||
|
|
||||||
**Puoi anche usare `start.cmd` per avviare automaticamente il server e il servizio proxy, ma devi impostare l'ambiente JAVA_HOME**
|
**Puoi anche usare `start.cmd` per avviare automaticamente il server e il servizio proxy, ma devi impostare l'ambiente JAVA_HOME**
|
||||||
|
|
||||||
@ -98,11 +98,11 @@ chmod +x gradlew
|
|||||||
|
|
||||||
Puoi trovare il jar generato nella cartella principale del progetto.
|
Puoi trovare il jar generato nella cartella principale del progetto.
|
||||||
|
|
||||||
### I comandi sono stati spostati nel [wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)!
|
### I comandi sono stati spostati al [wiki](https://github.com/Grasscutters/Grasscutter/wiki/Commands)!
|
||||||
|
|
||||||
# Soluzioni agli errori comuni
|
# Soluzioni agli errori comuni
|
||||||
|
|
||||||
* Se la compilazione non riesce, controlla l'installazione di JDK (JDK 17 e convalida la variabile JDK bin PATH)
|
* Se la compilazione non riesce, controlla l'installazione di JDK (JDK 17 e convalida la variabile JDK bin PATH)
|
||||||
* Il mio client non si connette, non accede, 4206, ecc... - Probabilmente le tue impostazioni proxy sono *il problema*, se usi
|
* Se il tuo client non si connette, non accede, da errore 4206, ecc... - Probabilmente *il problema* sono le tue impostazioni proxy, se usi
|
||||||
Fiddler assicurati di utilizzare una porta diversa da 8888
|
Fiddler assicurati di utilizzare una porta diversa da 8888
|
||||||
* Sequenza di avvio: MongoDB > Grasscutter > Servizio proxy (mitmdump, fiddler, ecc.) > Gioco
|
* Sequenza di avvio: MongoDB > Grasscutter > Servizio proxy (mitmdump, fiddler, ecc.) > Gioco
|
||||||
|
@ -22,52 +22,23 @@
|
|||||||
|
|
||||||
**注意:** 如需幫助請加入 [Discord](https://discord.gg/T5vZU6UyeG)
|
**注意:** 如需幫助請加入 [Discord](https://discord.gg/T5vZU6UyeG)
|
||||||
|
|
||||||
### 環境需求
|
### 快速開始(全自動)
|
||||||
|
|
||||||
* Java SE - 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 社區伺服器](https://www.mongodb.com/try/download/community)
|
||||||
|
- 下載遊戲版本 REL3.7(如果你沒有的話,可以在[這裡](https://github.com/MAnggiarMustofa/GI-Download-Library/blob/main/GenshinImpact/Client/3.7.0.md)找到 3.7 客戶端)
|
||||||
|
|
||||||
**注意:** 如果僅想**執行服務端**, 使用 **jre** 即可
|
- 下載 [最新的 Cultivation 版本](https://github.com/Grasscutters/Cultivation/releases/latest)。使用 `.msi` 安裝程式。
|
||||||
|
- 以管理員身分打開 Culivation,按右上角的下載按鈕。
|
||||||
|
- 點擊 `Download All-in-One`
|
||||||
|
- 點擊右上角的齒輪
|
||||||
|
- 將遊戲安裝路徑設置為你的遊戲所在的位置。
|
||||||
|
- 將自定義 Java 路徑設置為 `C:\Program Files\Java\jdk-17\bin\java.exe`
|
||||||
|
- 其他設置保持預設
|
||||||
|
|
||||||
* [MongoDB](https://www.mongodb.com/try/download/community) (推薦 4.0+)
|
- 點擊啟動旁邊的小按鈕。
|
||||||
|
- 點擊啟動按鈕。
|
||||||
* 代理程式: mitmproxy (推薦 mitmdump), Fiddler Classic 等
|
- 用你想要的用戶名登錄,密碼無所謂。
|
||||||
|
|
||||||
### 執行
|
|
||||||
|
|
||||||
**注意:** 從舊版本升級到新版本, 需要刪除 `config.json`
|
|
||||||
|
|
||||||
1. 獲取 `grasscutter.jar`
|
|
||||||
- 從 [actions](https://github.com/Grasscutters/Grasscutter/suites/6895963598/artifacts/267483297) 下載
|
|
||||||
- [自行編譯](#編譯)
|
|
||||||
2. 在 JAR 檔案根目錄中建立 `resources` 資料夾並複製 `BinOutput` 和 `ExcelBinOutput` *(查看 [wiki](https://github.com/Grasscutters/Grasscutter/wiki) 瞭解更多)*
|
|
||||||
3. 命令列 `java -jar grasscutter.jar` 執行 Grasscutter。**在此之前請確認 MongoDB 服務執行正常**
|
|
||||||
|
|
||||||
### 客戶端連線
|
|
||||||
|
|
||||||
½. 在伺服器控制台[建立賬戶](https://github.com/Grasscutters/Grasscutter/wiki/Commands#targeting)
|
|
||||||
|
|
||||||
1. 重定向流量: (選擇其中一個)
|
|
||||||
- mitmdump: `mitmdump -s proxy.py -k`
|
|
||||||
|
|
||||||
信任 CA 證書:
|
|
||||||
|
|
||||||
**注意:** mitmproxy 的 CA 證書通常存放在 `%USERPROFILE%\ .mitmproxy`, 或者在 `http://mitm.it` 下載證書
|
|
||||||
|
|
||||||
雙擊[安裝根證書](https://docs.microsoft.com/en-us/skype-sdk/sdn/articles/installing-the-trusted-root-certificate#installing-a-trusted-root-certificate)或者...
|
|
||||||
|
|
||||||
- 使用命令列
|
|
||||||
|
|
||||||
```shell
|
|
||||||
certutil -addstore root %USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer
|
|
||||||
```
|
|
||||||
|
|
||||||
- Fiddler Classic: 執行 Fiddler Classic, 在設定中開啟 `解密 https 通訊` 並將通訊埠設為除 `8888` 以外的任意通訊埠 (工具 -> 選項 -> 連線) 並載入[此指令碼](https://github.lunatic.moe/fiddlerscript)
|
|
||||||
|
|
||||||
- [Hosts 檔案](https://github.com/Grasscutters/Grasscutter/wiki/Running#traffic-route-map)
|
|
||||||
|
|
||||||
2. 設定代理為 `127.0.0.1:8080` 或你設定的通訊埠
|
|
||||||
|
|
||||||
**也可直接執行 `start.cmd` 一鍵啟動服務端並設定代理, 但必須設定 `JAVA_HOME` 環境變數**
|
|
||||||
|
|
||||||
### 編譯
|
### 編譯
|
||||||
|
|
||||||
|
@ -25,23 +25,23 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
int getAvatarId();
|
int getAvatarId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>uint32 unfinish_count = 15;</code>
|
* <code>uint32 finish_count = 15;</code>
|
||||||
* @return The unfinishCount.
|
|
||||||
*/
|
|
||||||
int getUnfinishCount();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <code>uint32 next_finish_timestamp = 13;</code>
|
|
||||||
* @return The nextFinishTimestamp.
|
|
||||||
*/
|
|
||||||
int getNextFinishTimestamp();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <code>uint32 finish_count = 4;</code>
|
|
||||||
* @return The finishCount.
|
* @return The finishCount.
|
||||||
*/
|
*/
|
||||||
int getFinishCount();
|
int getFinishCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>uint32 total_finish_timestamp = 13;</code>
|
||||||
|
* @return The totalFinishTimestamp.
|
||||||
|
*/
|
||||||
|
int getTotalFinishTimestamp();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>uint32 queue_id = 4;</code>
|
||||||
|
* @return The queueId.
|
||||||
|
*/
|
||||||
|
int getQueueId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>uint32 forge_id = 1;</code>
|
* <code>uint32 forge_id = 1;</code>
|
||||||
* @return The forgeId.
|
* @return The forgeId.
|
||||||
@ -49,16 +49,16 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
int getForgeId();
|
int getForgeId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>uint32 total_finish_timestamp = 8;</code>
|
* <code>uint32 next_finish_timestamp = 8;</code>
|
||||||
* @return The totalFinishTimestamp.
|
* @return The nextFinishTimestamp.
|
||||||
*/
|
*/
|
||||||
int getTotalFinishTimestamp();
|
int getNextFinishTimestamp();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>uint32 queue_id = 9;</code>
|
* <code>uint32 unfinish_count = 9;</code>
|
||||||
* @return The queueId.
|
* @return The unfinishCount.
|
||||||
*/
|
*/
|
||||||
int getQueueId();
|
int getUnfinishCount();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
@ -116,22 +116,22 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
}
|
}
|
||||||
case 32: {
|
case 32: {
|
||||||
|
|
||||||
finishCount_ = input.readUInt32();
|
queueId_ = input.readUInt32();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 64: {
|
case 64: {
|
||||||
|
|
||||||
totalFinishTimestamp_ = input.readUInt32();
|
nextFinishTimestamp_ = input.readUInt32();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 72: {
|
case 72: {
|
||||||
|
|
||||||
queueId_ = input.readUInt32();
|
unfinishCount_ = input.readUInt32();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 104: {
|
case 104: {
|
||||||
|
|
||||||
nextFinishTimestamp_ = input.readUInt32();
|
totalFinishTimestamp_ = input.readUInt32();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 112: {
|
case 112: {
|
||||||
@ -141,7 +141,7 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
}
|
}
|
||||||
case 120: {
|
case 120: {
|
||||||
|
|
||||||
unfinishCount_ = input.readUInt32();
|
finishCount_ = input.readUInt32();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -187,32 +187,10 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
return avatarId_;
|
return avatarId_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int UNFINISH_COUNT_FIELD_NUMBER = 15;
|
public static final int FINISH_COUNT_FIELD_NUMBER = 15;
|
||||||
private int unfinishCount_;
|
|
||||||
/**
|
|
||||||
* <code>uint32 unfinish_count = 15;</code>
|
|
||||||
* @return The unfinishCount.
|
|
||||||
*/
|
|
||||||
@java.lang.Override
|
|
||||||
public int getUnfinishCount() {
|
|
||||||
return unfinishCount_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int NEXT_FINISH_TIMESTAMP_FIELD_NUMBER = 13;
|
|
||||||
private int nextFinishTimestamp_;
|
|
||||||
/**
|
|
||||||
* <code>uint32 next_finish_timestamp = 13;</code>
|
|
||||||
* @return The nextFinishTimestamp.
|
|
||||||
*/
|
|
||||||
@java.lang.Override
|
|
||||||
public int getNextFinishTimestamp() {
|
|
||||||
return nextFinishTimestamp_;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int FINISH_COUNT_FIELD_NUMBER = 4;
|
|
||||||
private int finishCount_;
|
private int finishCount_;
|
||||||
/**
|
/**
|
||||||
* <code>uint32 finish_count = 4;</code>
|
* <code>uint32 finish_count = 15;</code>
|
||||||
* @return The finishCount.
|
* @return The finishCount.
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
@ -220,6 +198,28 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
return finishCount_;
|
return finishCount_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final int TOTAL_FINISH_TIMESTAMP_FIELD_NUMBER = 13;
|
||||||
|
private int totalFinishTimestamp_;
|
||||||
|
/**
|
||||||
|
* <code>uint32 total_finish_timestamp = 13;</code>
|
||||||
|
* @return The totalFinishTimestamp.
|
||||||
|
*/
|
||||||
|
@java.lang.Override
|
||||||
|
public int getTotalFinishTimestamp() {
|
||||||
|
return totalFinishTimestamp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int QUEUE_ID_FIELD_NUMBER = 4;
|
||||||
|
private int queueId_;
|
||||||
|
/**
|
||||||
|
* <code>uint32 queue_id = 4;</code>
|
||||||
|
* @return The queueId.
|
||||||
|
*/
|
||||||
|
@java.lang.Override
|
||||||
|
public int getQueueId() {
|
||||||
|
return queueId_;
|
||||||
|
}
|
||||||
|
|
||||||
public static final int FORGE_ID_FIELD_NUMBER = 1;
|
public static final int FORGE_ID_FIELD_NUMBER = 1;
|
||||||
private int forgeId_;
|
private int forgeId_;
|
||||||
/**
|
/**
|
||||||
@ -231,26 +231,26 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
return forgeId_;
|
return forgeId_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int TOTAL_FINISH_TIMESTAMP_FIELD_NUMBER = 8;
|
public static final int NEXT_FINISH_TIMESTAMP_FIELD_NUMBER = 8;
|
||||||
private int totalFinishTimestamp_;
|
private int nextFinishTimestamp_;
|
||||||
/**
|
/**
|
||||||
* <code>uint32 total_finish_timestamp = 8;</code>
|
* <code>uint32 next_finish_timestamp = 8;</code>
|
||||||
* @return The totalFinishTimestamp.
|
* @return The nextFinishTimestamp.
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
public int getTotalFinishTimestamp() {
|
public int getNextFinishTimestamp() {
|
||||||
return totalFinishTimestamp_;
|
return nextFinishTimestamp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int QUEUE_ID_FIELD_NUMBER = 9;
|
public static final int UNFINISH_COUNT_FIELD_NUMBER = 9;
|
||||||
private int queueId_;
|
private int unfinishCount_;
|
||||||
/**
|
/**
|
||||||
* <code>uint32 queue_id = 9;</code>
|
* <code>uint32 unfinish_count = 9;</code>
|
||||||
* @return The queueId.
|
* @return The unfinishCount.
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
public int getQueueId() {
|
public int getUnfinishCount() {
|
||||||
return queueId_;
|
return unfinishCount_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte memoizedIsInitialized = -1;
|
private byte memoizedIsInitialized = -1;
|
||||||
@ -270,23 +270,23 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
if (forgeId_ != 0) {
|
if (forgeId_ != 0) {
|
||||||
output.writeUInt32(1, forgeId_);
|
output.writeUInt32(1, forgeId_);
|
||||||
}
|
}
|
||||||
if (finishCount_ != 0) {
|
|
||||||
output.writeUInt32(4, finishCount_);
|
|
||||||
}
|
|
||||||
if (totalFinishTimestamp_ != 0) {
|
|
||||||
output.writeUInt32(8, totalFinishTimestamp_);
|
|
||||||
}
|
|
||||||
if (queueId_ != 0) {
|
if (queueId_ != 0) {
|
||||||
output.writeUInt32(9, queueId_);
|
output.writeUInt32(4, queueId_);
|
||||||
}
|
}
|
||||||
if (nextFinishTimestamp_ != 0) {
|
if (nextFinishTimestamp_ != 0) {
|
||||||
output.writeUInt32(13, nextFinishTimestamp_);
|
output.writeUInt32(8, nextFinishTimestamp_);
|
||||||
|
}
|
||||||
|
if (unfinishCount_ != 0) {
|
||||||
|
output.writeUInt32(9, unfinishCount_);
|
||||||
|
}
|
||||||
|
if (totalFinishTimestamp_ != 0) {
|
||||||
|
output.writeUInt32(13, totalFinishTimestamp_);
|
||||||
}
|
}
|
||||||
if (avatarId_ != 0) {
|
if (avatarId_ != 0) {
|
||||||
output.writeUInt32(14, avatarId_);
|
output.writeUInt32(14, avatarId_);
|
||||||
}
|
}
|
||||||
if (unfinishCount_ != 0) {
|
if (finishCount_ != 0) {
|
||||||
output.writeUInt32(15, unfinishCount_);
|
output.writeUInt32(15, finishCount_);
|
||||||
}
|
}
|
||||||
unknownFields.writeTo(output);
|
unknownFields.writeTo(output);
|
||||||
}
|
}
|
||||||
@ -301,29 +301,29 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
.computeUInt32Size(1, forgeId_);
|
.computeUInt32Size(1, forgeId_);
|
||||||
}
|
}
|
||||||
if (finishCount_ != 0) {
|
|
||||||
size += com.google.protobuf.CodedOutputStream
|
|
||||||
.computeUInt32Size(4, finishCount_);
|
|
||||||
}
|
|
||||||
if (totalFinishTimestamp_ != 0) {
|
|
||||||
size += com.google.protobuf.CodedOutputStream
|
|
||||||
.computeUInt32Size(8, totalFinishTimestamp_);
|
|
||||||
}
|
|
||||||
if (queueId_ != 0) {
|
if (queueId_ != 0) {
|
||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
.computeUInt32Size(9, queueId_);
|
.computeUInt32Size(4, queueId_);
|
||||||
}
|
}
|
||||||
if (nextFinishTimestamp_ != 0) {
|
if (nextFinishTimestamp_ != 0) {
|
||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
.computeUInt32Size(13, nextFinishTimestamp_);
|
.computeUInt32Size(8, nextFinishTimestamp_);
|
||||||
|
}
|
||||||
|
if (unfinishCount_ != 0) {
|
||||||
|
size += com.google.protobuf.CodedOutputStream
|
||||||
|
.computeUInt32Size(9, unfinishCount_);
|
||||||
|
}
|
||||||
|
if (totalFinishTimestamp_ != 0) {
|
||||||
|
size += com.google.protobuf.CodedOutputStream
|
||||||
|
.computeUInt32Size(13, totalFinishTimestamp_);
|
||||||
}
|
}
|
||||||
if (avatarId_ != 0) {
|
if (avatarId_ != 0) {
|
||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
.computeUInt32Size(14, avatarId_);
|
.computeUInt32Size(14, avatarId_);
|
||||||
}
|
}
|
||||||
if (unfinishCount_ != 0) {
|
if (finishCount_ != 0) {
|
||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
.computeUInt32Size(15, unfinishCount_);
|
.computeUInt32Size(15, finishCount_);
|
||||||
}
|
}
|
||||||
size += unknownFields.getSerializedSize();
|
size += unknownFields.getSerializedSize();
|
||||||
memoizedSize = size;
|
memoizedSize = size;
|
||||||
@ -342,18 +342,18 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
|
|
||||||
if (getAvatarId()
|
if (getAvatarId()
|
||||||
!= other.getAvatarId()) return false;
|
!= other.getAvatarId()) return false;
|
||||||
if (getUnfinishCount()
|
|
||||||
!= other.getUnfinishCount()) return false;
|
|
||||||
if (getNextFinishTimestamp()
|
|
||||||
!= other.getNextFinishTimestamp()) return false;
|
|
||||||
if (getFinishCount()
|
if (getFinishCount()
|
||||||
!= other.getFinishCount()) return false;
|
!= other.getFinishCount()) return false;
|
||||||
if (getForgeId()
|
|
||||||
!= other.getForgeId()) return false;
|
|
||||||
if (getTotalFinishTimestamp()
|
if (getTotalFinishTimestamp()
|
||||||
!= other.getTotalFinishTimestamp()) return false;
|
!= other.getTotalFinishTimestamp()) return false;
|
||||||
if (getQueueId()
|
if (getQueueId()
|
||||||
!= other.getQueueId()) return false;
|
!= other.getQueueId()) return false;
|
||||||
|
if (getForgeId()
|
||||||
|
!= other.getForgeId()) return false;
|
||||||
|
if (getNextFinishTimestamp()
|
||||||
|
!= other.getNextFinishTimestamp()) return false;
|
||||||
|
if (getUnfinishCount()
|
||||||
|
!= other.getUnfinishCount()) return false;
|
||||||
if (!unknownFields.equals(other.unknownFields)) return false;
|
if (!unknownFields.equals(other.unknownFields)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -367,18 +367,18 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
hash = (19 * hash) + getDescriptor().hashCode();
|
hash = (19 * hash) + getDescriptor().hashCode();
|
||||||
hash = (37 * hash) + AVATAR_ID_FIELD_NUMBER;
|
hash = (37 * hash) + AVATAR_ID_FIELD_NUMBER;
|
||||||
hash = (53 * hash) + getAvatarId();
|
hash = (53 * hash) + getAvatarId();
|
||||||
hash = (37 * hash) + UNFINISH_COUNT_FIELD_NUMBER;
|
|
||||||
hash = (53 * hash) + getUnfinishCount();
|
|
||||||
hash = (37 * hash) + NEXT_FINISH_TIMESTAMP_FIELD_NUMBER;
|
|
||||||
hash = (53 * hash) + getNextFinishTimestamp();
|
|
||||||
hash = (37 * hash) + FINISH_COUNT_FIELD_NUMBER;
|
hash = (37 * hash) + FINISH_COUNT_FIELD_NUMBER;
|
||||||
hash = (53 * hash) + getFinishCount();
|
hash = (53 * hash) + getFinishCount();
|
||||||
hash = (37 * hash) + FORGE_ID_FIELD_NUMBER;
|
|
||||||
hash = (53 * hash) + getForgeId();
|
|
||||||
hash = (37 * hash) + TOTAL_FINISH_TIMESTAMP_FIELD_NUMBER;
|
hash = (37 * hash) + TOTAL_FINISH_TIMESTAMP_FIELD_NUMBER;
|
||||||
hash = (53 * hash) + getTotalFinishTimestamp();
|
hash = (53 * hash) + getTotalFinishTimestamp();
|
||||||
hash = (37 * hash) + QUEUE_ID_FIELD_NUMBER;
|
hash = (37 * hash) + QUEUE_ID_FIELD_NUMBER;
|
||||||
hash = (53 * hash) + getQueueId();
|
hash = (53 * hash) + getQueueId();
|
||||||
|
hash = (37 * hash) + FORGE_ID_FIELD_NUMBER;
|
||||||
|
hash = (53 * hash) + getForgeId();
|
||||||
|
hash = (37 * hash) + NEXT_FINISH_TIMESTAMP_FIELD_NUMBER;
|
||||||
|
hash = (53 * hash) + getNextFinishTimestamp();
|
||||||
|
hash = (37 * hash) + UNFINISH_COUNT_FIELD_NUMBER;
|
||||||
|
hash = (53 * hash) + getUnfinishCount();
|
||||||
hash = (29 * hash) + unknownFields.hashCode();
|
hash = (29 * hash) + unknownFields.hashCode();
|
||||||
memoizedHashCode = hash;
|
memoizedHashCode = hash;
|
||||||
return hash;
|
return hash;
|
||||||
@ -518,18 +518,18 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
super.clear();
|
super.clear();
|
||||||
avatarId_ = 0;
|
avatarId_ = 0;
|
||||||
|
|
||||||
unfinishCount_ = 0;
|
|
||||||
|
|
||||||
nextFinishTimestamp_ = 0;
|
|
||||||
|
|
||||||
finishCount_ = 0;
|
finishCount_ = 0;
|
||||||
|
|
||||||
forgeId_ = 0;
|
|
||||||
|
|
||||||
totalFinishTimestamp_ = 0;
|
totalFinishTimestamp_ = 0;
|
||||||
|
|
||||||
queueId_ = 0;
|
queueId_ = 0;
|
||||||
|
|
||||||
|
forgeId_ = 0;
|
||||||
|
|
||||||
|
nextFinishTimestamp_ = 0;
|
||||||
|
|
||||||
|
unfinishCount_ = 0;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,12 +557,12 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
public emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData buildPartial() {
|
public emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData buildPartial() {
|
||||||
emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData result = new emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData(this);
|
emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData result = new emu.grasscutter.net.proto.ForgeQueueDataOuterClass.ForgeQueueData(this);
|
||||||
result.avatarId_ = avatarId_;
|
result.avatarId_ = avatarId_;
|
||||||
result.unfinishCount_ = unfinishCount_;
|
|
||||||
result.nextFinishTimestamp_ = nextFinishTimestamp_;
|
|
||||||
result.finishCount_ = finishCount_;
|
result.finishCount_ = finishCount_;
|
||||||
result.forgeId_ = forgeId_;
|
|
||||||
result.totalFinishTimestamp_ = totalFinishTimestamp_;
|
result.totalFinishTimestamp_ = totalFinishTimestamp_;
|
||||||
result.queueId_ = queueId_;
|
result.queueId_ = queueId_;
|
||||||
|
result.forgeId_ = forgeId_;
|
||||||
|
result.nextFinishTimestamp_ = nextFinishTimestamp_;
|
||||||
|
result.unfinishCount_ = unfinishCount_;
|
||||||
onBuilt();
|
onBuilt();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -614,24 +614,24 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
if (other.getAvatarId() != 0) {
|
if (other.getAvatarId() != 0) {
|
||||||
setAvatarId(other.getAvatarId());
|
setAvatarId(other.getAvatarId());
|
||||||
}
|
}
|
||||||
if (other.getUnfinishCount() != 0) {
|
|
||||||
setUnfinishCount(other.getUnfinishCount());
|
|
||||||
}
|
|
||||||
if (other.getNextFinishTimestamp() != 0) {
|
|
||||||
setNextFinishTimestamp(other.getNextFinishTimestamp());
|
|
||||||
}
|
|
||||||
if (other.getFinishCount() != 0) {
|
if (other.getFinishCount() != 0) {
|
||||||
setFinishCount(other.getFinishCount());
|
setFinishCount(other.getFinishCount());
|
||||||
}
|
}
|
||||||
if (other.getForgeId() != 0) {
|
|
||||||
setForgeId(other.getForgeId());
|
|
||||||
}
|
|
||||||
if (other.getTotalFinishTimestamp() != 0) {
|
if (other.getTotalFinishTimestamp() != 0) {
|
||||||
setTotalFinishTimestamp(other.getTotalFinishTimestamp());
|
setTotalFinishTimestamp(other.getTotalFinishTimestamp());
|
||||||
}
|
}
|
||||||
if (other.getQueueId() != 0) {
|
if (other.getQueueId() != 0) {
|
||||||
setQueueId(other.getQueueId());
|
setQueueId(other.getQueueId());
|
||||||
}
|
}
|
||||||
|
if (other.getForgeId() != 0) {
|
||||||
|
setForgeId(other.getForgeId());
|
||||||
|
}
|
||||||
|
if (other.getNextFinishTimestamp() != 0) {
|
||||||
|
setNextFinishTimestamp(other.getNextFinishTimestamp());
|
||||||
|
}
|
||||||
|
if (other.getUnfinishCount() != 0) {
|
||||||
|
setUnfinishCount(other.getUnfinishCount());
|
||||||
|
}
|
||||||
this.mergeUnknownFields(other.unknownFields);
|
this.mergeUnknownFields(other.unknownFields);
|
||||||
onChanged();
|
onChanged();
|
||||||
return this;
|
return this;
|
||||||
@ -692,71 +692,9 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int unfinishCount_ ;
|
|
||||||
/**
|
|
||||||
* <code>uint32 unfinish_count = 15;</code>
|
|
||||||
* @return The unfinishCount.
|
|
||||||
*/
|
|
||||||
@java.lang.Override
|
|
||||||
public int getUnfinishCount() {
|
|
||||||
return unfinishCount_;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* <code>uint32 unfinish_count = 15;</code>
|
|
||||||
* @param value The unfinishCount to set.
|
|
||||||
* @return This builder for chaining.
|
|
||||||
*/
|
|
||||||
public Builder setUnfinishCount(int value) {
|
|
||||||
|
|
||||||
unfinishCount_ = value;
|
|
||||||
onChanged();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* <code>uint32 unfinish_count = 15;</code>
|
|
||||||
* @return This builder for chaining.
|
|
||||||
*/
|
|
||||||
public Builder clearUnfinishCount() {
|
|
||||||
|
|
||||||
unfinishCount_ = 0;
|
|
||||||
onChanged();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int nextFinishTimestamp_ ;
|
|
||||||
/**
|
|
||||||
* <code>uint32 next_finish_timestamp = 13;</code>
|
|
||||||
* @return The nextFinishTimestamp.
|
|
||||||
*/
|
|
||||||
@java.lang.Override
|
|
||||||
public int getNextFinishTimestamp() {
|
|
||||||
return nextFinishTimestamp_;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* <code>uint32 next_finish_timestamp = 13;</code>
|
|
||||||
* @param value The nextFinishTimestamp to set.
|
|
||||||
* @return This builder for chaining.
|
|
||||||
*/
|
|
||||||
public Builder setNextFinishTimestamp(int value) {
|
|
||||||
|
|
||||||
nextFinishTimestamp_ = value;
|
|
||||||
onChanged();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* <code>uint32 next_finish_timestamp = 13;</code>
|
|
||||||
* @return This builder for chaining.
|
|
||||||
*/
|
|
||||||
public Builder clearNextFinishTimestamp() {
|
|
||||||
|
|
||||||
nextFinishTimestamp_ = 0;
|
|
||||||
onChanged();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int finishCount_ ;
|
private int finishCount_ ;
|
||||||
/**
|
/**
|
||||||
* <code>uint32 finish_count = 4;</code>
|
* <code>uint32 finish_count = 15;</code>
|
||||||
* @return The finishCount.
|
* @return The finishCount.
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
@ -764,7 +702,7 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
return finishCount_;
|
return finishCount_;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>uint32 finish_count = 4;</code>
|
* <code>uint32 finish_count = 15;</code>
|
||||||
* @param value The finishCount to set.
|
* @param value The finishCount to set.
|
||||||
* @return This builder for chaining.
|
* @return This builder for chaining.
|
||||||
*/
|
*/
|
||||||
@ -775,7 +713,7 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>uint32 finish_count = 4;</code>
|
* <code>uint32 finish_count = 15;</code>
|
||||||
* @return This builder for chaining.
|
* @return This builder for chaining.
|
||||||
*/
|
*/
|
||||||
public Builder clearFinishCount() {
|
public Builder clearFinishCount() {
|
||||||
@ -785,6 +723,68 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int totalFinishTimestamp_ ;
|
||||||
|
/**
|
||||||
|
* <code>uint32 total_finish_timestamp = 13;</code>
|
||||||
|
* @return The totalFinishTimestamp.
|
||||||
|
*/
|
||||||
|
@java.lang.Override
|
||||||
|
public int getTotalFinishTimestamp() {
|
||||||
|
return totalFinishTimestamp_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>uint32 total_finish_timestamp = 13;</code>
|
||||||
|
* @param value The totalFinishTimestamp to set.
|
||||||
|
* @return This builder for chaining.
|
||||||
|
*/
|
||||||
|
public Builder setTotalFinishTimestamp(int value) {
|
||||||
|
|
||||||
|
totalFinishTimestamp_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>uint32 total_finish_timestamp = 13;</code>
|
||||||
|
* @return This builder for chaining.
|
||||||
|
*/
|
||||||
|
public Builder clearTotalFinishTimestamp() {
|
||||||
|
|
||||||
|
totalFinishTimestamp_ = 0;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int queueId_ ;
|
||||||
|
/**
|
||||||
|
* <code>uint32 queue_id = 4;</code>
|
||||||
|
* @return The queueId.
|
||||||
|
*/
|
||||||
|
@java.lang.Override
|
||||||
|
public int getQueueId() {
|
||||||
|
return queueId_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>uint32 queue_id = 4;</code>
|
||||||
|
* @param value The queueId to set.
|
||||||
|
* @return This builder for chaining.
|
||||||
|
*/
|
||||||
|
public Builder setQueueId(int value) {
|
||||||
|
|
||||||
|
queueId_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>uint32 queue_id = 4;</code>
|
||||||
|
* @return This builder for chaining.
|
||||||
|
*/
|
||||||
|
public Builder clearQueueId() {
|
||||||
|
|
||||||
|
queueId_ = 0;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private int forgeId_ ;
|
private int forgeId_ ;
|
||||||
/**
|
/**
|
||||||
* <code>uint32 forge_id = 1;</code>
|
* <code>uint32 forge_id = 1;</code>
|
||||||
@ -816,64 +816,64 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int totalFinishTimestamp_ ;
|
private int nextFinishTimestamp_ ;
|
||||||
/**
|
/**
|
||||||
* <code>uint32 total_finish_timestamp = 8;</code>
|
* <code>uint32 next_finish_timestamp = 8;</code>
|
||||||
* @return The totalFinishTimestamp.
|
* @return The nextFinishTimestamp.
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
public int getTotalFinishTimestamp() {
|
public int getNextFinishTimestamp() {
|
||||||
return totalFinishTimestamp_;
|
return nextFinishTimestamp_;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>uint32 total_finish_timestamp = 8;</code>
|
* <code>uint32 next_finish_timestamp = 8;</code>
|
||||||
* @param value The totalFinishTimestamp to set.
|
* @param value The nextFinishTimestamp to set.
|
||||||
* @return This builder for chaining.
|
* @return This builder for chaining.
|
||||||
*/
|
*/
|
||||||
public Builder setTotalFinishTimestamp(int value) {
|
public Builder setNextFinishTimestamp(int value) {
|
||||||
|
|
||||||
totalFinishTimestamp_ = value;
|
nextFinishTimestamp_ = value;
|
||||||
onChanged();
|
onChanged();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>uint32 total_finish_timestamp = 8;</code>
|
* <code>uint32 next_finish_timestamp = 8;</code>
|
||||||
* @return This builder for chaining.
|
* @return This builder for chaining.
|
||||||
*/
|
*/
|
||||||
public Builder clearTotalFinishTimestamp() {
|
public Builder clearNextFinishTimestamp() {
|
||||||
|
|
||||||
totalFinishTimestamp_ = 0;
|
nextFinishTimestamp_ = 0;
|
||||||
onChanged();
|
onChanged();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int queueId_ ;
|
private int unfinishCount_ ;
|
||||||
/**
|
/**
|
||||||
* <code>uint32 queue_id = 9;</code>
|
* <code>uint32 unfinish_count = 9;</code>
|
||||||
* @return The queueId.
|
* @return The unfinishCount.
|
||||||
*/
|
*/
|
||||||
@java.lang.Override
|
@java.lang.Override
|
||||||
public int getQueueId() {
|
public int getUnfinishCount() {
|
||||||
return queueId_;
|
return unfinishCount_;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>uint32 queue_id = 9;</code>
|
* <code>uint32 unfinish_count = 9;</code>
|
||||||
* @param value The queueId to set.
|
* @param value The unfinishCount to set.
|
||||||
* @return This builder for chaining.
|
* @return This builder for chaining.
|
||||||
*/
|
*/
|
||||||
public Builder setQueueId(int value) {
|
public Builder setUnfinishCount(int value) {
|
||||||
|
|
||||||
queueId_ = value;
|
unfinishCount_ = value;
|
||||||
onChanged();
|
onChanged();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>uint32 queue_id = 9;</code>
|
* <code>uint32 unfinish_count = 9;</code>
|
||||||
* @return This builder for chaining.
|
* @return This builder for chaining.
|
||||||
*/
|
*/
|
||||||
public Builder clearQueueId() {
|
public Builder clearUnfinishCount() {
|
||||||
|
|
||||||
queueId_ = 0;
|
unfinishCount_ = 0;
|
||||||
onChanged();
|
onChanged();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -945,10 +945,10 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
static {
|
static {
|
||||||
java.lang.String[] descriptorData = {
|
java.lang.String[] descriptorData = {
|
||||||
"\n\024ForgeQueueData.proto\"\264\001\n\016ForgeQueueDat" +
|
"\n\024ForgeQueueData.proto\"\264\001\n\016ForgeQueueDat" +
|
||||||
"a\022\021\n\tavatar_id\030\016 \001(\r\022\026\n\016unfinish_count\030\017" +
|
"a\022\021\n\tavatar_id\030\016 \001(\r\022\024\n\014finish_count\030\017 \001" +
|
||||||
" \001(\r\022\035\n\025next_finish_timestamp\030\r \001(\r\022\024\n\014f" +
|
"(\r\022\036\n\026total_finish_timestamp\030\r \001(\r\022\020\n\010qu" +
|
||||||
"inish_count\030\004 \001(\r\022\020\n\010forge_id\030\001 \001(\r\022\036\n\026t" +
|
"eue_id\030\004 \001(\r\022\020\n\010forge_id\030\001 \001(\r\022\035\n\025next_f" +
|
||||||
"otal_finish_timestamp\030\010 \001(\r\022\020\n\010queue_id\030" +
|
"inish_timestamp\030\010 \001(\r\022\026\n\016unfinish_count\030" +
|
||||||
"\t \001(\rB\033\n\031emu.grasscutter.net.protob\006prot" +
|
"\t \001(\rB\033\n\031emu.grasscutter.net.protob\006prot" +
|
||||||
"o3"
|
"o3"
|
||||||
};
|
};
|
||||||
@ -961,7 +961,7 @@ public final class ForgeQueueDataOuterClass {
|
|||||||
internal_static_ForgeQueueData_fieldAccessorTable = new
|
internal_static_ForgeQueueData_fieldAccessorTable = new
|
||||||
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
|
||||||
internal_static_ForgeQueueData_descriptor,
|
internal_static_ForgeQueueData_descriptor,
|
||||||
new java.lang.String[] { "AvatarId", "UnfinishCount", "NextFinishTimestamp", "FinishCount", "ForgeId", "TotalFinishTimestamp", "QueueId", });
|
new java.lang.String[] { "AvatarId", "FinishCount", "TotalFinishTimestamp", "QueueId", "ForgeId", "NextFinishTimestamp", "UnfinishCount", });
|
||||||
}
|
}
|
||||||
|
|
||||||
// @@protoc_insertion_point(outer_class_scope)
|
// @@protoc_insertion_point(outer_class_scope)
|
||||||
|
@ -4,11 +4,9 @@ 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.Command;
|
import emu.grasscutter.command.*;
|
||||||
import emu.grasscutter.command.CommandHandler;
|
|
||||||
import emu.grasscutter.config.Configuration;
|
import emu.grasscutter.config.Configuration;
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.*;
|
||||||
import emu.grasscutter.database.DatabaseManager;
|
|
||||||
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;
|
||||||
@ -31,17 +29,17 @@ public final class AccountCommand implements CommandHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.size() < 2) {
|
|
||||||
sendUsageMessage(sender);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String action = args.get(0);
|
String action = args.get(0);
|
||||||
String username = args.get(1);
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
default -> this.sendUsageMessage(sender);
|
default -> this.sendUsageMessage(sender);
|
||||||
case "create" -> {
|
case "create" -> {
|
||||||
|
if (args.size() < 2) {
|
||||||
|
this.sendUsageMessage(sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var username = args.get(1);
|
||||||
|
|
||||||
int uid = 0;
|
int uid = 0;
|
||||||
String password = "";
|
String password = "";
|
||||||
if (Configuration.ACCOUNT.EXPERIMENTAL_RealPassword) {
|
if (Configuration.ACCOUNT.EXPERIMENTAL_RealPassword) {
|
||||||
@ -94,6 +92,12 @@ public final class AccountCommand implements CommandHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "delete" -> {
|
case "delete" -> {
|
||||||
|
if (args.size() < 2) {
|
||||||
|
this.sendUsageMessage(sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var username = args.get(1);
|
||||||
|
|
||||||
// Get the account we want to delete.
|
// Get the account we want to delete.
|
||||||
Account toDelete = DatabaseHelper.getAccountByName(username);
|
Account toDelete = DatabaseHelper.getAccountByName(username);
|
||||||
if (toDelete == null) {
|
if (toDelete == null) {
|
||||||
@ -104,6 +108,12 @@ public final class AccountCommand implements CommandHandler {
|
|||||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.delete"));
|
CommandHandler.sendMessage(sender, translate(sender, "commands.account.delete"));
|
||||||
}
|
}
|
||||||
case "resetpass" -> {
|
case "resetpass" -> {
|
||||||
|
if (args.size() < 2) {
|
||||||
|
this.sendUsageMessage(sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var username = args.get(1);
|
||||||
|
|
||||||
if (!Configuration.ACCOUNT.EXPERIMENTAL_RealPassword) {
|
if (!Configuration.ACCOUNT.EXPERIMENTAL_RealPassword) {
|
||||||
CommandHandler.sendMessage(
|
CommandHandler.sendMessage(
|
||||||
sender, "resetpass requires EXPERIMENTAL_RealPassword to be true.");
|
sender, "resetpass requires EXPERIMENTAL_RealPassword to be true.");
|
||||||
|
@ -9,6 +9,7 @@ import emu.grasscutter.Grasscutter;
|
|||||||
import emu.grasscutter.data.binout.*;
|
import emu.grasscutter.data.binout.*;
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||||
import emu.grasscutter.data.binout.config.*;
|
import emu.grasscutter.data.binout.config.*;
|
||||||
|
import emu.grasscutter.data.binout.routes.*;
|
||||||
import emu.grasscutter.data.common.PointData;
|
import emu.grasscutter.data.common.PointData;
|
||||||
import emu.grasscutter.data.custom.*;
|
import emu.grasscutter.data.custom.*;
|
||||||
import emu.grasscutter.data.excels.trial.TrialAvatarActivityDataData;
|
import emu.grasscutter.data.excels.trial.TrialAvatarActivityDataData;
|
||||||
@ -107,6 +108,7 @@ public final class ResourceLoader {
|
|||||||
// Load default home layout
|
// Load default home layout
|
||||||
loadHomeworldDefaultSaveData();
|
loadHomeworldDefaultSaveData();
|
||||||
loadNpcBornData();
|
loadNpcBornData();
|
||||||
|
loadRoutes();
|
||||||
loadBlossomResources();
|
loadBlossomResources();
|
||||||
cacheTalentLevelSets();
|
cacheTalentLevelSets();
|
||||||
// Load activities.
|
// Load activities.
|
||||||
@ -264,6 +266,32 @@ public final class ResourceLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void loadRoutes() {
|
||||||
|
try {
|
||||||
|
Files.newDirectoryStream(getResourcePath("BinOutput/LevelDesign/Routes/"), "*.json")
|
||||||
|
.forEach(
|
||||||
|
path -> {
|
||||||
|
try {
|
||||||
|
val data = JsonUtils.loadToClass(path, SceneRoutes.class);
|
||||||
|
val routesArray = data.getRoutes();
|
||||||
|
if (routesArray == null) return;
|
||||||
|
val routesMap =
|
||||||
|
GameData.getSceneRouteData()
|
||||||
|
.getOrDefault(data.getSceneId(), new Int2ObjectOpenHashMap<>());
|
||||||
|
for (Route route : routesArray) {
|
||||||
|
routesMap.put(route.getLocalId(), route);
|
||||||
|
}
|
||||||
|
GameData.getSceneRouteData().put(data.getSceneId(), routesMap);
|
||||||
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneRouteDatas.");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Grasscutter.getLogger().error("Failed to load SceneRouteData folder.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void cacheTalentLevelSets() {
|
private static void cacheTalentLevelSets() {
|
||||||
// All known levels, keyed by proudSkillGroupId
|
// All known levels, keyed by proudSkillGroupId
|
||||||
GameData.getProudSkillDataMap()
|
GameData.getProudSkillDataMap()
|
||||||
|
@ -11,38 +11,58 @@ import lombok.experimental.FieldDefaults;
|
|||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public class HomeworldDefaultSaveData {
|
public class HomeworldDefaultSaveData {
|
||||||
|
|
||||||
@SerializedName(value = "KFHBFNPDJBE", alternate = "PKACPHDGGEI")
|
@SerializedName(
|
||||||
|
value = "KFHBFNPDJBE",
|
||||||
|
alternate = {"PKACPHDGGEI", "AKOLOBLHDFK"})
|
||||||
List<HomeBlock> homeBlockLists;
|
List<HomeBlock> homeBlockLists;
|
||||||
|
|
||||||
@SerializedName(value = "IJNPADKGNKE", alternate = "MINCKHBNING")
|
@SerializedName(
|
||||||
|
value = "IJNPADKGNKE",
|
||||||
|
alternate = {"MINCKHBNING", "MBICDPDEKDM"})
|
||||||
Position bornPos;
|
Position bornPos;
|
||||||
|
|
||||||
@SerializedName("IPIIGEMFLHK")
|
@SerializedName(
|
||||||
|
value = "IPIIGEMFLHK",
|
||||||
|
alternate = {"EJJIOJKFKCO"})
|
||||||
Position bornRot;
|
Position bornRot;
|
||||||
|
|
||||||
@SerializedName("HHOLBNPIHEM")
|
@SerializedName(
|
||||||
|
value = "HHOLBNPIHEM",
|
||||||
|
alternate = {"CJAKHCIFHNP"})
|
||||||
Position djinPos;
|
Position djinPos;
|
||||||
|
|
||||||
@SerializedName("KNHCJKHCOAN")
|
@SerializedName(
|
||||||
|
value = "KNHCJKHCOAN",
|
||||||
|
alternate = {"AMDNOHPGKMI"})
|
||||||
HomeFurniture mainhouse;
|
HomeFurniture mainhouse;
|
||||||
|
|
||||||
@SerializedName("NIHOJFEKFPG")
|
@SerializedName(
|
||||||
|
value = "NIHOJFEKFPG",
|
||||||
|
alternate = {"BHCPEAOPIDC"})
|
||||||
List<HomeFurniture> doorLists;
|
List<HomeFurniture> doorLists;
|
||||||
|
|
||||||
@SerializedName("EPGELGEFJFK")
|
@SerializedName(
|
||||||
|
value = "EPGELGEFJFK",
|
||||||
|
alternate = {"AABEPENIFLN"})
|
||||||
List<HomeFurniture> stairLists;
|
List<HomeFurniture> stairLists;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public static class HomeBlock {
|
public static class HomeBlock {
|
||||||
|
|
||||||
@SerializedName(value = "FGIJCELCGFI", alternate = "PGDPDIDJEEL")
|
@SerializedName(
|
||||||
|
value = "FGIJCELCGFI",
|
||||||
|
alternate = {"PGDPDIDJEEL", "ANICBLBOBKD"})
|
||||||
int blockId;
|
int blockId;
|
||||||
|
|
||||||
@SerializedName("BEAPOFELABD")
|
@SerializedName(
|
||||||
|
value = "BEAPOFELABD",
|
||||||
|
alternate = {"NCIMIKKFLOH"})
|
||||||
List<HomeFurniture> furnitures;
|
List<HomeFurniture> furnitures;
|
||||||
|
|
||||||
@SerializedName("MLIODLGDFHJ")
|
@SerializedName(
|
||||||
|
value = "MLIODLGDFHJ",
|
||||||
|
alternate = {"GJGNLIINBGB"})
|
||||||
List<HomeFurniture> persistentFurnitures;
|
List<HomeFurniture> persistentFurnitures;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,10 +70,14 @@ public class HomeworldDefaultSaveData {
|
|||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
public static class HomeFurniture {
|
public static class HomeFurniture {
|
||||||
|
|
||||||
@SerializedName(value = "ENHNGKJBJAB", alternate = "KMAAJJHPNBA")
|
@SerializedName(
|
||||||
|
value = "ENHNGKJBJAB",
|
||||||
|
alternate = {"KMAAJJHPNBA", "FFLCGFGGGND"})
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
@SerializedName(value = "NGIEEIOLPPO", alternate = "JFKAHNCPDME")
|
@SerializedName(
|
||||||
|
value = "NGIEEIOLPPO",
|
||||||
|
alternate = {"JFKAHNCPDME", "BPCGGBKIAMG"})
|
||||||
Position pos;
|
Position pos;
|
||||||
// @SerializedName(value = "HEOCEHKEBFM", alternate = "LKCKOOGFDBM")
|
// @SerializedName(value = "HEOCEHKEBFM", alternate = "LKCKOOGFDBM")
|
||||||
Position rot;
|
Position rot;
|
||||||
|
@ -89,7 +89,14 @@ public class ItemData extends GameResource {
|
|||||||
|
|
||||||
@SerializedName(
|
@SerializedName(
|
||||||
value = "roomSceneId",
|
value = "roomSceneId",
|
||||||
alternate = {"BMEPAMCNABE", "DANFGGLKLNO", "JFDLJGDFIGL", "OHIANNAEEAK", "MFGACDIOHGF"})
|
alternate = {
|
||||||
|
"BMEPAMCNABE",
|
||||||
|
"DANFGGLKLNO",
|
||||||
|
"JFDLJGDFIGL",
|
||||||
|
"OHIANNAEEAK",
|
||||||
|
"MFGACDIOHGF",
|
||||||
|
"roomSceneID"
|
||||||
|
})
|
||||||
private int roomSceneId;
|
private int roomSceneId;
|
||||||
|
|
||||||
// Custom
|
// Custom
|
||||||
|
@ -39,7 +39,7 @@ public final class TalkConfigData extends GameResource {
|
|||||||
|
|
||||||
if (this.questId <= 0) {
|
if (this.questId <= 0) {
|
||||||
var id = String.valueOf(this.getId());
|
var id = String.valueOf(this.getId());
|
||||||
this.questId = Integer.parseInt(id.length() < 5 ? "0" : id.substring(0, 3));
|
this.questId = Integer.parseInt(id.length() < 5 ? "0" : id.substring(0, id.length() - 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,13 @@ import emu.grasscutter.game.dungeons.enums.DungeonPassConditionType;
|
|||||||
import emu.grasscutter.game.quest.enums.LogicType;
|
import emu.grasscutter.game.quest.enums.LogicType;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
@ResourceType(name = "DungeonPassExcelConfigData.json")
|
@ResourceType(name = "DungeonPassExcelConfigData.json")
|
||||||
public class DungeonPassConfigData extends GameResource {
|
public class DungeonPassConfigData extends GameResource {
|
||||||
@Getter private int id;
|
@Getter private int id;
|
||||||
@Getter private LogicType logicType;
|
@Getter private LogicType logicType;
|
||||||
@Getter private List<DungeonPassCondition> conds;
|
@Getter @Setter private List<DungeonPassCondition> conds;
|
||||||
|
|
||||||
public static class DungeonPassCondition {
|
public static class DungeonPassCondition {
|
||||||
@Getter private DungeonPassConditionType condType;
|
@Getter private DungeonPassConditionType condType;
|
||||||
|
@ -15,7 +15,7 @@ public class UnknownActivityConditionHandler extends ActivityConditionBaseHandle
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
PlayerActivityData activityData, ActivityConfigItem activityConfig, int... params) {
|
||||||
Grasscutter.getLogger().error("Called unknown condition handler {}.", conditions.name());
|
Grasscutter.getLogger().debug("Called unknown condition handler {}.", conditions.name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,13 @@ public final class DungeonManager {
|
|||||||
public DungeonManager(@NonNull Scene scene, @NonNull DungeonData dungeonData) {
|
public DungeonManager(@NonNull Scene scene, @NonNull DungeonData dungeonData) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.dungeonData = dungeonData;
|
this.dungeonData = dungeonData;
|
||||||
|
if (dungeonData.getPassCond() == 0) {
|
||||||
|
this.passConfigData = new DungeonPassConfigData();
|
||||||
|
this.passConfigData.setConds(new ArrayList<>());
|
||||||
|
} else {
|
||||||
this.passConfigData = GameData.getDungeonPassConfigDataMap().get(dungeonData.getPassCond());
|
this.passConfigData = GameData.getDungeonPassConfigDataMap().get(dungeonData.getPassCond());
|
||||||
this.finishedConditions = new int[passConfigData.getConds().size()];
|
}
|
||||||
|
this.finishedConditions = new int[this.passConfigData.getConds().size()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void triggerEvent(DungeonPassConditionType conditionType, int... params) {
|
public void triggerEvent(DungeonPassConditionType conditionType, int... params) {
|
||||||
@ -76,6 +81,7 @@ public final class DungeonManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFinishedSuccessfully() {
|
public boolean isFinishedSuccessfully() {
|
||||||
|
if (passConfigData.getLogicType() == null) return false;
|
||||||
return LogicType.calculate(passConfigData.getLogicType(), finishedConditions);
|
return LogicType.calculate(passConfigData.getLogicType(), finishedConditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public abstract class EntityBaseGadget extends GameEntity {
|
|||||||
getGadgetId())
|
getGadgetId())
|
||||||
.setSourceEntityId(getId())
|
.setSourceEntityId(getId())
|
||||||
.setParam3((int) this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP))
|
.setParam3((int) this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP))
|
||||||
.setEventSource(Integer.toString(getConfigId())));
|
.setEventSource(getConfigId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void fillFightProps(ConfigEntityGadget configGadget) {
|
protected void fillFightProps(ConfigEntityGadget configGadget) {
|
||||||
|
@ -7,6 +7,7 @@ import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
|
|||||||
import emu.grasscutter.data.excels.GadgetData;
|
import emu.grasscutter.data.excels.GadgetData;
|
||||||
import emu.grasscutter.game.entity.gadget.*;
|
import emu.grasscutter.game.entity.gadget.*;
|
||||||
import emu.grasscutter.game.entity.gadget.platform.BaseRoute;
|
import emu.grasscutter.game.entity.gadget.platform.BaseRoute;
|
||||||
|
import emu.grasscutter.game.entity.gadget.platform.ConfigRoute;
|
||||||
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.*;
|
||||||
@ -246,6 +247,62 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
if (routeConfig.isStarted()) {
|
if (routeConfig.isStarted()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (routeConfig instanceof ConfigRoute configRoute) {
|
||||||
|
var route = this.getScene().getSceneRouteById(configRoute.getRouteId());
|
||||||
|
if (route != null) {
|
||||||
|
var points = route.getPoints();
|
||||||
|
val currIndex = configRoute.getStartIndex();
|
||||||
|
|
||||||
|
Position prevpos;
|
||||||
|
if (currIndex == 0) {
|
||||||
|
prevpos = getPosition();
|
||||||
|
this.getScene()
|
||||||
|
.getScriptManager()
|
||||||
|
.callEvent(
|
||||||
|
new ScriptArgs(
|
||||||
|
this.getGroupId(),
|
||||||
|
EventType.EVENT_PLATFORM_REACH_POINT,
|
||||||
|
this.getConfigId(),
|
||||||
|
configRoute.getRouteId())
|
||||||
|
.setParam3(0)
|
||||||
|
.setEventSource(this.getConfigId()));
|
||||||
|
} else {
|
||||||
|
prevpos = points[currIndex].getPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
double time = 0;
|
||||||
|
for (var i = currIndex; i < points.length; ++i) {
|
||||||
|
time += points[i].getPos().computeDistance(prevpos) / points[i].getTargetVelocity();
|
||||||
|
prevpos = points[i].getPos();
|
||||||
|
val I = i;
|
||||||
|
configRoute
|
||||||
|
.getScheduledIndexes()
|
||||||
|
.add(
|
||||||
|
this.getScene()
|
||||||
|
.getScheduler()
|
||||||
|
.scheduleDelayedTask(
|
||||||
|
() -> {
|
||||||
|
if (points[I].isHasReachEvent() && I > currIndex) {
|
||||||
|
this.getScene()
|
||||||
|
.getScriptManager()
|
||||||
|
.callEvent(
|
||||||
|
new ScriptArgs(
|
||||||
|
this.getGroupId(),
|
||||||
|
EventType.EVENT_PLATFORM_REACH_POINT,
|
||||||
|
this.getConfigId(),
|
||||||
|
configRoute.getRouteId())
|
||||||
|
.setParam3(I)
|
||||||
|
.setEventSource(this.getConfigId()));
|
||||||
|
}
|
||||||
|
configRoute.setStartIndex(I);
|
||||||
|
this.position.set(points[I].getPos());
|
||||||
|
},
|
||||||
|
(int) time));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getScene().broadcastPacket(new PacketSceneTimeNotify(getScene()));
|
getScene().broadcastPacket(new PacketSceneTimeNotify(getScene()));
|
||||||
routeConfig.startRoute(getScene());
|
routeConfig.startRoute(getScene());
|
||||||
getScene().broadcastPacket(new PacketPlatformStartRouteNotify(this));
|
getScene().broadcastPacket(new PacketPlatformStartRouteNotify(this));
|
||||||
@ -261,6 +318,14 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
if (!routeConfig.isStarted()) {
|
if (!routeConfig.isStarted()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (routeConfig instanceof ConfigRoute configRoute) {
|
||||||
|
for (var task : configRoute.getScheduledIndexes()) {
|
||||||
|
this.getScene().getScheduler().cancelTask(task);
|
||||||
|
}
|
||||||
|
configRoute.getScheduledIndexes().clear();
|
||||||
|
}
|
||||||
|
|
||||||
routeConfig.stopRoute(getScene());
|
routeConfig.stopRoute(getScene());
|
||||||
getScene().broadcastPacket(new PacketPlatformStopRouteNotify(this));
|
getScene().broadcastPacket(new PacketPlatformStopRouteNotify(this));
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ public class EntityMonster extends GameEntity {
|
|||||||
getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EVENT_SPECIFIC_MONSTER_HP_CHANGE, getConfigId(), monsterData.getId())
|
getScene().getScriptManager().callEvent(new ScriptArgs(this.getGroupId(), EVENT_SPECIFIC_MONSTER_HP_CHANGE, getConfigId(), monsterData.getId())
|
||||||
.setSourceEntityId(getId())
|
.setSourceEntityId(getId())
|
||||||
.setParam3((int) this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP))
|
.setParam3((int) this.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP))
|
||||||
.setEventSource(Integer.toString(getConfigId())));
|
.setEventSource(getConfigId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,12 +59,12 @@ public final class GadgetGatherObject extends GadgetContent {
|
|||||||
GameItem item = new GameItem(itemData, 1);
|
GameItem item = new GameItem(itemData, 1);
|
||||||
player.getInventory().addItem(item, ActionReason.Gather);
|
player.getInventory().addItem(item, ActionReason.Gather);
|
||||||
|
|
||||||
getGadget()
|
var ScriptArgs =
|
||||||
.getScene()
|
new ScriptArgs(getGadget().getGroupId(), EventType.EVENT_GATHER, getGadget().getConfigId());
|
||||||
.getScriptManager()
|
if (getGadget().getMetaGadget() != null) {
|
||||||
.callEvent(
|
ScriptArgs.setEventSource(getGadget().getMetaGadget().config_id);
|
||||||
new ScriptArgs(
|
}
|
||||||
getGadget().getGroupId(), EventType.EVENT_GATHER, getGadget().getConfigId()));
|
getGadget().getScene().getScriptManager().callEvent(ScriptArgs);
|
||||||
|
|
||||||
getGadget()
|
getGadget()
|
||||||
.getScene()
|
.getScene()
|
||||||
|
@ -1,20 +1,56 @@
|
|||||||
package emu.grasscutter.game.entity.gadget;
|
package emu.grasscutter.game.entity.gadget;
|
||||||
|
|
||||||
|
import emu.grasscutter.data.GameData;
|
||||||
|
import emu.grasscutter.data.excels.GatherData;
|
||||||
|
import emu.grasscutter.data.excels.ItemData;
|
||||||
import emu.grasscutter.game.entity.EntityGadget;
|
import emu.grasscutter.game.entity.EntityGadget;
|
||||||
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
|
import emu.grasscutter.game.props.ActionReason;
|
||||||
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass;
|
import emu.grasscutter.net.proto.GadgetInteractReqOuterClass;
|
||||||
|
import emu.grasscutter.net.proto.InteractTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass;
|
||||||
|
import emu.grasscutter.scripts.constants.EventType;
|
||||||
|
import emu.grasscutter.scripts.data.ScriptArgs;
|
||||||
|
import emu.grasscutter.server.packet.send.PacketGadgetInteractRsp;
|
||||||
|
|
||||||
public class GadgetObject extends GadgetContent {
|
public class GadgetObject extends GadgetContent {
|
||||||
|
private int itemId;
|
||||||
|
|
||||||
public GadgetObject(EntityGadget gadget) {
|
public GadgetObject(EntityGadget gadget) {
|
||||||
super(gadget);
|
super(gadget);
|
||||||
|
GatherData gatherData = GameData.getGatherDataMap().get(gadget.getPointType());
|
||||||
|
if (gatherData != null) {
|
||||||
|
this.itemId = gatherData.getItemId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onInteract(Player player, GadgetInteractReqOuterClass.GadgetInteractReq req) {
|
public boolean onInteract(Player player, GadgetInteractReqOuterClass.GadgetInteractReq req) {
|
||||||
|
// This is a workaround until a proper gadget interaction system can be put in place.
|
||||||
|
ItemData itemData = GameData.getItemDataMap().get(this.itemId);
|
||||||
|
if (itemData == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GameItem item = new GameItem(itemData, 1);
|
||||||
|
player.getInventory().addItem(item, ActionReason.Gather);
|
||||||
|
|
||||||
|
var ScriptArgs =
|
||||||
|
new ScriptArgs(getGadget().getGroupId(), EventType.EVENT_GATHER, getGadget().getConfigId());
|
||||||
|
if (getGadget().getMetaGadget() != null) {
|
||||||
|
ScriptArgs.setEventSource(getGadget().getMetaGadget().config_id);
|
||||||
|
}
|
||||||
|
getGadget().getScene().getScriptManager().callEvent(ScriptArgs);
|
||||||
|
|
||||||
|
getGadget()
|
||||||
|
.getScene()
|
||||||
|
.broadcastPacket(
|
||||||
|
new PacketGadgetInteractRsp(
|
||||||
|
getGadget(), InteractTypeOuterClass.InteractType.INTERACT_TYPE_GATHER));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBuildProto(SceneGadgetInfoOuterClass.SceneGadgetInfo.Builder gadgetInfo) {}
|
public void onBuildProto(SceneGadgetInfoOuterClass.SceneGadgetInfo.Builder gadgetInfo) {}
|
||||||
}
|
}
|
||||||
|
@ -4,27 +4,36 @@ import emu.grasscutter.game.world.Position;
|
|||||||
import emu.grasscutter.net.proto.MovingPlatformTypeOuterClass;
|
import emu.grasscutter.net.proto.MovingPlatformTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.PlatformInfoOuterClass;
|
import emu.grasscutter.net.proto.PlatformInfoOuterClass;
|
||||||
import emu.grasscutter.scripts.data.SceneGadget;
|
import emu.grasscutter.scripts.data.SceneGadget;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
public class ConfigRoute extends BaseRoute {
|
public class ConfigRoute extends BaseRoute {
|
||||||
|
|
||||||
@Getter @Setter private int routeId;
|
@Getter @Setter private int routeId;
|
||||||
|
@Getter @Setter private int startIndex;
|
||||||
|
@Getter @Setter private List<Integer> scheduledIndexes;
|
||||||
|
|
||||||
public ConfigRoute(SceneGadget gadget) {
|
public ConfigRoute(SceneGadget gadget) {
|
||||||
super(gadget);
|
super(gadget);
|
||||||
this.routeId = gadget.route_id;
|
this.routeId = gadget.route_id;
|
||||||
|
this.startIndex = 0;
|
||||||
|
this.scheduledIndexes = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigRoute(Position startRot, boolean startRoute, boolean isActive, int routeId) {
|
public ConfigRoute(Position startRot, boolean startRoute, boolean isActive, int routeId) {
|
||||||
super(startRot, startRoute, isActive);
|
super(startRot, startRoute, isActive);
|
||||||
this.routeId = routeId;
|
this.routeId = routeId;
|
||||||
|
this.startIndex = 0;
|
||||||
|
this.scheduledIndexes = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlatformInfoOuterClass.PlatformInfo.Builder toProto() {
|
public PlatformInfoOuterClass.PlatformInfo.Builder toProto() {
|
||||||
return super.toProto()
|
return super.toProto()
|
||||||
.setRouteId(routeId)
|
.setRouteId(this.routeId)
|
||||||
|
.setStartIndex(this.startIndex)
|
||||||
.setMovingPlatformType(
|
.setMovingPlatformType(
|
||||||
MovingPlatformTypeOuterClass.MovingPlatformType.MOVING_PLATFORM_TYPE_USE_CONFIG);
|
MovingPlatformTypeOuterClass.MovingPlatformType.MOVING_PLATFORM_TYPE_USE_CONFIG);
|
||||||
}
|
}
|
||||||
|
@ -1536,6 +1536,12 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof Player otherPlayer &&
|
||||||
|
this.id == otherPlayer.getUid();
|
||||||
|
}
|
||||||
|
|
||||||
public enum SceneLoadState {
|
public enum SceneLoadState {
|
||||||
NONE(0), LOADING(1), INIT(2), LOADED(3);
|
NONE(0), LOADING(1), INIT(2), LOADED(3);
|
||||||
|
|
||||||
@ -1546,5 +1552,4 @@ public class Player implements PlayerHook, FieldFetch {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,6 @@ public class ContentLeaveScene extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
return quest.getOwner().getScene().getPrevScene() == params[0];
|
return condition.getParam()[0] == params[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,11 @@ public class ContentQuestStateEqual extends BaseContent {
|
|||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(condition.getParam()[0]);
|
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(condition.getParam()[0]);
|
||||||
|
|
||||||
if (checkQuest == null) {
|
if (checkQuest == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return checkQuest.getState().getValue() == params[1];
|
|
||||||
|
return checkQuest.getState().getValue() == condition.getParam()[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@ public class ContentQuestStateNotEqual extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(params[0]);
|
GameQuest checkQuest = quest.getOwner().getQuestManager().getQuestById(condition.getParam()[0]);
|
||||||
|
|
||||||
if (checkQuest != null) {
|
|
||||||
return checkQuest.getState().getValue() != params[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (checkQuest == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return checkQuest.getState().getValue() != condition.getParam()[1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ public class ContentQuestVarEqual extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
int questVarValue = quest.getMainQuest().getQuestVars()[condition.getParam()[0]];
|
||||||
Grasscutter.getLogger().debug("questVar {} : {}", params[0], questVarValue);
|
Grasscutter.getLogger().debug("questVar {} : {}", condition.getParam()[0], questVarValue);
|
||||||
return questVarValue == params[1];
|
return questVarValue == condition.getParam()[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ public class ContentQuestVarGreater extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
int questVarValue = quest.getMainQuest().getQuestVars()[condition.getParam()[0]];
|
||||||
Grasscutter.getLogger().debug("questVar {} : {}", params[0], questVarValue);
|
Grasscutter.getLogger().debug("questVar {} : {}", condition.getParam()[0], questVarValue);
|
||||||
return questVarValue > params[1];
|
return questVarValue > condition.getParam()[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ public class ContentQuestVarLess extends BaseContent {
|
|||||||
@Override
|
@Override
|
||||||
public boolean execute(
|
public boolean execute(
|
||||||
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
GameQuest quest, QuestData.QuestContentCondition condition, String paramStr, int... params) {
|
||||||
int questVarValue = quest.getMainQuest().getQuestVars()[params[0]];
|
int questVarValue = quest.getMainQuest().getQuestVars()[condition.getParam()[0]];
|
||||||
Grasscutter.getLogger().debug("questVar {} : {}", params[0], questVarValue);
|
Grasscutter.getLogger().debug("questVar {} : {}", condition.getParam()[0], questVarValue);
|
||||||
return questVarValue < params[1];
|
return questVarValue < condition.getParam()[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import emu.grasscutter.scripts.data.*;
|
|||||||
import emu.grasscutter.server.event.entity.EntityCreationEvent;
|
import emu.grasscutter.server.event.entity.EntityCreationEvent;
|
||||||
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
import emu.grasscutter.server.event.player.PlayerTeleportEvent;
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
|
import emu.grasscutter.server.scheduler.ServerTaskScheduler;
|
||||||
import emu.grasscutter.utils.objects.KahnsSort;
|
import emu.grasscutter.utils.objects.KahnsSort;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -51,7 +52,6 @@ public final class Scene {
|
|||||||
@Getter private final Set<SceneGroup> loadedGroups;
|
@Getter private final Set<SceneGroup> loadedGroups;
|
||||||
@Getter private final BlossomManager blossomManager;
|
@Getter private final BlossomManager blossomManager;
|
||||||
private final HashSet<Integer> unlockedForces;
|
private final HashSet<Integer> unlockedForces;
|
||||||
private final List<Runnable> afterLoadedCallbacks = new ArrayList<>();
|
|
||||||
private final long startWorldTime;
|
private final long startWorldTime;
|
||||||
@Getter @Setter DungeonManager dungeonManager;
|
@Getter @Setter DungeonManager dungeonManager;
|
||||||
@Getter Int2ObjectMap<Route> sceneRoutes;
|
@Getter Int2ObjectMap<Route> sceneRoutes;
|
||||||
@ -68,7 +68,11 @@ public final class Scene {
|
|||||||
@Getter private int tickCount = 0;
|
@Getter private int tickCount = 0;
|
||||||
@Getter private boolean isPaused = false;
|
@Getter private boolean isPaused = false;
|
||||||
|
|
||||||
|
private final List<Runnable> afterLoadedCallbacks = new ArrayList<>();
|
||||||
|
private final List<Runnable> afterHostInitCallbacks = new ArrayList<>();
|
||||||
|
|
||||||
@Getter private GameEntity sceneEntity;
|
@Getter private GameEntity sceneEntity;
|
||||||
|
@Getter private final ServerTaskScheduler scheduler;
|
||||||
|
|
||||||
public Scene(World world, SceneData sceneData) {
|
public Scene(World world, SceneData sceneData) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
@ -92,6 +96,7 @@ public final class Scene {
|
|||||||
this.blossomManager = new BlossomManager(this);
|
this.blossomManager = new BlossomManager(this);
|
||||||
this.unlockedForces = new HashSet<>();
|
this.unlockedForces = new HashSet<>();
|
||||||
this.sceneEntity = new EntityScene(this);
|
this.sceneEntity = new EntityScene(this);
|
||||||
|
this.scheduler = new ServerTaskScheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
@ -106,6 +111,13 @@ public final class Scene {
|
|||||||
return this.getPlayers().size();
|
return this.getPlayers().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The scene's world's host.
|
||||||
|
*/
|
||||||
|
public Player getHost() {
|
||||||
|
return this.getWorld().getHost();
|
||||||
|
}
|
||||||
|
|
||||||
public GameEntity getEntityById(int id) {
|
public GameEntity getEntityById(int id) {
|
||||||
// Check if the scene's entity ID is referenced.
|
// Check if the scene's entity ID is referenced.
|
||||||
if (id == 0x13800001) return this.sceneEntity;
|
if (id == 0x13800001) return this.sceneEntity;
|
||||||
@ -524,6 +536,10 @@ public final class Scene {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isPaused) {
|
||||||
|
this.getScheduler().runTasks();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.getScriptManager().isInit()) {
|
if (this.getScriptManager().isInit()) {
|
||||||
// this.checkBlocks();
|
// this.checkBlocks();
|
||||||
this.checkGroups();
|
this.checkGroups();
|
||||||
@ -678,6 +694,29 @@ public final class Scene {
|
|||||||
this.afterLoadedCallbacks.add(runnable);
|
this.afterLoadedCallbacks.add(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when a player initializes loading the scene.
|
||||||
|
*
|
||||||
|
* @param player The player that initialized loading the scene.
|
||||||
|
*/
|
||||||
|
public void playerSceneInitialized(Player player) {
|
||||||
|
// Check if the player is the host.
|
||||||
|
if (!player.equals(this.getHost())) return;
|
||||||
|
|
||||||
|
// Run all callbacks.
|
||||||
|
this.afterHostInitCallbacks.forEach(Runnable::run);
|
||||||
|
this.afterHostInitCallbacks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a callback when the host initializes loading the scene.
|
||||||
|
*
|
||||||
|
* @param runnable The callback to be executed.
|
||||||
|
*/
|
||||||
|
public void runWhenHostInitialized(Runnable runnable) {
|
||||||
|
this.afterHostInitCallbacks.add(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
public int getEntityLevel(int baseLevel, int worldLevelOverride) {
|
public int getEntityLevel(int baseLevel, int worldLevelOverride) {
|
||||||
int level = worldLevelOverride > 0 ? worldLevelOverride + baseLevel - 22 : baseLevel;
|
int level = worldLevelOverride > 0 ? worldLevelOverride + baseLevel - 22 : baseLevel;
|
||||||
level = Math.min(level, 100);
|
level = Math.min(level, 100);
|
||||||
|
@ -10,7 +10,7 @@ import emu.grasscutter.data.server.Grid;
|
|||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.entity.*;
|
import emu.grasscutter.game.entity.*;
|
||||||
import emu.grasscutter.game.entity.gadget.platform.BaseRoute;
|
import emu.grasscutter.game.entity.gadget.platform.BaseRoute;
|
||||||
import emu.grasscutter.game.props.EntityType;
|
import emu.grasscutter.game.props.EntityIdType;
|
||||||
import emu.grasscutter.game.quest.*;
|
import emu.grasscutter.game.quest.*;
|
||||||
import emu.grasscutter.game.world.*;
|
import emu.grasscutter.game.world.*;
|
||||||
import emu.grasscutter.net.proto.VisionTypeOuterClass;
|
import emu.grasscutter.net.proto.VisionTypeOuterClass;
|
||||||
@ -99,7 +99,13 @@ public class SceneScriptManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SceneConfig getConfig() {
|
public SceneConfig getConfig() {
|
||||||
return this.isInit ? this.meta.config : null;
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
if (this.isInit) {
|
||||||
|
return this.meta.config;
|
||||||
|
}
|
||||||
|
Utils.sleep(100);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, SceneBlock> getBlocks() {
|
public Map<Integer, SceneBlock> getBlocks() {
|
||||||
@ -209,8 +215,15 @@ public class SceneScriptManager {
|
|||||||
var suiteData = group.getSuiteByIndex(suiteIndex);
|
var suiteData = group.getSuiteByIndex(suiteIndex);
|
||||||
if (suiteData == null) {
|
if (suiteData == null) {
|
||||||
Grasscutter.getLogger().warn("Group {} suite {} not found", group.id, suiteIndex);
|
Grasscutter.getLogger().warn("Group {} suite {} not found", group.id, suiteIndex);
|
||||||
|
group.setLoaded(false);
|
||||||
|
group.load(this.scene.getId());
|
||||||
|
suiteData = group.getSuiteByIndex(suiteIndex);
|
||||||
|
if (suiteData == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Grasscutter.getLogger()
|
||||||
|
.error("Group {} suite {} nvm, I found it. This is BAD", group.id, suiteIndex);
|
||||||
|
}
|
||||||
|
|
||||||
int prevSuiteIndex = groupInstance.getActiveSuiteId();
|
int prevSuiteIndex = groupInstance.getActiveSuiteId();
|
||||||
boolean waitForOne = false;
|
boolean waitForOne = false;
|
||||||
@ -627,28 +640,25 @@ public class SceneScriptManager {
|
|||||||
// add other types of entity
|
// add other types of entity
|
||||||
var entities =
|
var entities =
|
||||||
getScene().getEntities().values().stream()
|
getScene().getEntities().values().stream()
|
||||||
.filter(
|
.filter(e -> region.getMetaRegion().contains(e.getPosition()))
|
||||||
e ->
|
|
||||||
e.getEntityType() == EntityType.Avatar
|
|
||||||
&& region.getMetaRegion().contains(e.getPosition()))
|
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
var entitiesIds = entities.stream().map(GameEntity::getId).toList();
|
||||||
|
var enterEntities =
|
||||||
|
entitiesIds.stream().filter(e -> !region.getEntities().contains(e)).toList();
|
||||||
|
var leaveEntities =
|
||||||
|
region.getEntities().stream().filter(e -> !entitiesIds.contains(e)).toList();
|
||||||
|
|
||||||
entities.forEach(region::addEntity);
|
entities.forEach(region::addEntity);
|
||||||
|
|
||||||
var targetId = 0;
|
for (var targetId : enterEntities) {
|
||||||
if (entities.size() > 0) {
|
|
||||||
targetId = entities.get(0).getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (region.entityHasEntered()) {
|
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.trace("Call EVENT_ENTER_REGION_{}", region.getMetaRegion().config_id);
|
.trace("Call EVENT_ENTER_REGION_{}", region.getMetaRegion().config_id);
|
||||||
this.callEvent(
|
this.callEvent(
|
||||||
new ScriptArgs(region.getGroupId(), EventType.EVENT_ENTER_REGION, region.getConfigId())
|
new ScriptArgs(region.getGroupId(), EventType.EVENT_ENTER_REGION, region.getConfigId())
|
||||||
.setEventSource(EntityType.Avatar.getValue())
|
.setEventSource(EntityIdType.toEntityType(targetId >> 24).getValue())
|
||||||
.setSourceEntityId(region.getId())
|
.setSourceEntityId(region.getId())
|
||||||
.setTargetEntityId(targetId));
|
.setTargetEntityId(targetId));
|
||||||
|
|
||||||
region.resetNewEntities();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var entityId : region.getEntities()) {
|
for (var entityId : region.getEntities()) {
|
||||||
@ -658,14 +668,12 @@ public class SceneScriptManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region.entityHasLeft()) {
|
for (var targetId : leaveEntities) {
|
||||||
this.callEvent(
|
this.callEvent(
|
||||||
new ScriptArgs(region.getGroupId(), EventType.EVENT_LEAVE_REGION, region.getConfigId())
|
new ScriptArgs(region.getGroupId(), EventType.EVENT_LEAVE_REGION, region.getConfigId())
|
||||||
.setEventSource(EntityType.Avatar.getValue())
|
.setEventSource(EntityIdType.toEntityType(targetId >> 24).getValue())
|
||||||
.setSourceEntityId(region.getId())
|
.setSourceEntityId(region.getId())
|
||||||
.setTargetEntityId(region.getFirstEntityId()));
|
.setTargetEntityId(targetId));
|
||||||
|
|
||||||
region.resetNewEntities();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -893,7 +901,6 @@ public class SceneScriptManager {
|
|||||||
.toList()
|
.toList()
|
||||||
.get(0);
|
.get(0);
|
||||||
this.getScene().getPlayers().forEach(p -> p.onEnterRegion(region.getMetaRegion()));
|
this.getScene().getPlayers().forEach(p -> p.onEnterRegion(region.getMetaRegion()));
|
||||||
this.deregisterRegion(region.getMetaRegion());
|
|
||||||
} else if (trigger.getEvent() == EventType.EVENT_LEAVE_REGION) {
|
} else if (trigger.getEvent() == EventType.EVENT_LEAVE_REGION) {
|
||||||
var region =
|
var region =
|
||||||
this.regions.values().stream()
|
this.regions.values().stream()
|
||||||
@ -901,7 +908,6 @@ public class SceneScriptManager {
|
|||||||
.toList()
|
.toList()
|
||||||
.get(0);
|
.get(0);
|
||||||
this.getScene().getPlayers().forEach(p -> p.onLeaveRegion(region.getMetaRegion()));
|
this.getScene().getPlayers().forEach(p -> p.onLeaveRegion(region.getMetaRegion()));
|
||||||
this.deregisterRegion(region.getMetaRegion());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trigger.getEvent() == EVENT_TIMER_EVENT) {
|
if (trigger.getEvent() == EVENT_TIMER_EVENT) {
|
||||||
|
@ -8,37 +8,25 @@ import emu.grasscutter.game.dungeons.challenge.enums.FatherChallengeProperty;
|
|||||||
import emu.grasscutter.game.dungeons.challenge.factory.ChallengeFactory;
|
import emu.grasscutter.game.dungeons.challenge.factory.ChallengeFactory;
|
||||||
import emu.grasscutter.game.entity.*;
|
import emu.grasscutter.game.entity.*;
|
||||||
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
import emu.grasscutter.game.entity.gadget.GadgetWorktop;
|
||||||
import emu.grasscutter.game.entity.gadget.platform.ConfigRoute;
|
import emu.grasscutter.game.entity.gadget.platform.*;
|
||||||
import emu.grasscutter.game.entity.gadget.platform.PointArrayRoute;
|
import emu.grasscutter.game.props.*;
|
||||||
import emu.grasscutter.game.props.ClimateType;
|
import emu.grasscutter.game.quest.enums.*;
|
||||||
import emu.grasscutter.game.props.EntityIdType;
|
import emu.grasscutter.game.world.*;
|
||||||
import emu.grasscutter.game.props.EntityType;
|
|
||||||
import emu.grasscutter.game.quest.enums.QuestCond;
|
|
||||||
import emu.grasscutter.game.quest.enums.QuestContent;
|
|
||||||
import emu.grasscutter.game.quest.enums.QuestState;
|
|
||||||
import emu.grasscutter.game.world.SceneGroupInstance;
|
|
||||||
import emu.grasscutter.net.proto.EnterTypeOuterClass;
|
import emu.grasscutter.net.proto.EnterTypeOuterClass;
|
||||||
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
|
||||||
import emu.grasscutter.scripts.constants.EventType;
|
import emu.grasscutter.scripts.constants.*;
|
||||||
import emu.grasscutter.scripts.constants.GroupKillPolicy;
|
import emu.grasscutter.scripts.data.*;
|
||||||
import emu.grasscutter.scripts.data.SceneGroup;
|
|
||||||
import emu.grasscutter.scripts.data.SceneObject;
|
|
||||||
import emu.grasscutter.scripts.data.ScriptArgs;
|
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
import emu.grasscutter.game.world.Position;
|
|
||||||
import io.netty.util.concurrent.FastThreadLocal;
|
import io.netty.util.concurrent.FastThreadLocal;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.luaj.vm2.LuaTable;
|
import org.luaj.vm2.*;
|
||||||
import org.luaj.vm2.LuaValue;
|
import org.slf4j.*;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static emu.grasscutter.game.props.EnterReason.Lua;
|
import static emu.grasscutter.game.props.EnterReason.Lua;
|
||||||
import static emu.grasscutter.scripts.ScriptUtils.luaToPos;
|
import static emu.grasscutter.scripts.ScriptUtils.*;
|
||||||
import static emu.grasscutter.scripts.ScriptUtils.posToLua;
|
|
||||||
import static emu.grasscutter.scripts.constants.GroupKillPolicy.*;
|
import static emu.grasscutter.scripts.constants.GroupKillPolicy.*;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -256,12 +244,6 @@ public class ScriptLib {
|
|||||||
Grasscutter.getLogger().warn("trying to get suite that doesn't exist: {} {}", groupId, suite);
|
Grasscutter.getLogger().warn("trying to get suite that doesn't exist: {} {}", groupId, suite);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// avoid spawn wrong monster
|
|
||||||
if(getSceneScriptManager().getScene().getChallenge() != null)
|
|
||||||
if(!getSceneScriptManager().getScene().getChallenge().inProgress() ||
|
|
||||||
getSceneScriptManager().getScene().getChallenge().getGroup().id != groupId){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
this.getSceneScriptManager().addGroupSuite(groupInstance, suiteData);
|
this.getSceneScriptManager().addGroupSuite(groupInstance, suiteData);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -398,7 +380,7 @@ public class ScriptLib {
|
|||||||
logger.debug("[LUA] Call SetGroupVariableValue with {},{}",
|
logger.debug("[LUA] Call SetGroupVariableValue with {},{}",
|
||||||
var, value);
|
var, value);
|
||||||
|
|
||||||
val groupId= currentGroup.get().id;
|
val groupId = currentGroup.get().id;
|
||||||
val variables = getSceneScriptManager().getVariables(groupId);
|
val variables = getSceneScriptManager().getVariables(groupId);
|
||||||
|
|
||||||
val old = variables.getOrDefault(var, value);
|
val old = variables.getOrDefault(var, value);
|
||||||
@ -411,17 +393,46 @@ public class ScriptLib {
|
|||||||
logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}",
|
logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}",
|
||||||
var, value);
|
var, value);
|
||||||
|
|
||||||
val groupId= currentGroup.get().id;
|
val groupId = currentGroup.get().id;
|
||||||
val variables = getSceneScriptManager().getVariables(groupId);
|
val variables = getSceneScriptManager().getVariables(groupId);
|
||||||
|
|
||||||
val old = variables.getOrDefault(var, 0);
|
val old = variables.getOrDefault(var, 0);
|
||||||
variables.put(var, old + value);
|
variables.put(var, old + value);
|
||||||
logger.debug("[LUA] Call ChangeGroupVariableValue with {},{}",
|
|
||||||
old, old+value);
|
|
||||||
getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, old+value, old).setEventSource(var));
|
getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, old+value, old).setEventSource(var));
|
||||||
return LuaValue.ZERO;
|
return LuaValue.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetGroupVariableValueByGroup(String var, int groupId){
|
||||||
|
logger.debug("[LUA] Call GetGroupVariableValueByGroup with {},{}",
|
||||||
|
var,groupId);
|
||||||
|
|
||||||
|
return getSceneScriptManager().getVariables(groupId).getOrDefault(var, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SetGroupVariableValueByGroup(String var, int value, int groupId){
|
||||||
|
logger.debug("[LUA] Call SetGroupVariableValueByGroup with {},{},{}",
|
||||||
|
var,value,groupId);
|
||||||
|
|
||||||
|
val variables = getSceneScriptManager().getVariables(groupId);
|
||||||
|
|
||||||
|
val old = variables.getOrDefault(var, value);
|
||||||
|
variables.put(var, value);
|
||||||
|
getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, value, old).setEventSource(var));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ChangeGroupVariableValueByGroup(String var, int value, int groupId){
|
||||||
|
logger.debug("[LUA] Call ChangeGroupVariableValueByGroup with {},{}",
|
||||||
|
var,groupId);
|
||||||
|
|
||||||
|
val variables = getSceneScriptManager().getVariables(groupId);
|
||||||
|
|
||||||
|
val old = variables.getOrDefault(var, 0);
|
||||||
|
variables.put(var, old + value);
|
||||||
|
getSceneScriptManager().callEvent(new ScriptArgs(groupId, EventType.EVENT_VARIABLE_CHANGE, old+value, old).setEventSource(var));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the actions and triggers to designated group
|
* Set the actions and triggers to designated group
|
||||||
*/
|
*/
|
||||||
@ -532,22 +543,22 @@ public class ScriptLib {
|
|||||||
var entity = scene.getEntityByConfigId(cfgId);
|
var entity = scene.getEntityByConfigId(cfgId);
|
||||||
if (entity == null) return 2;
|
if (entity == null) return 2;
|
||||||
|
|
||||||
scene.broadcastPacket(
|
scene.runWhenHostInitialized(() -> scene.broadcastPacket(
|
||||||
new PacketServerGlobalValueChangeNotify(entity, sgvName, value));
|
new PacketServerGlobalValueChangeNotify(entity, sgvName, value)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetGroupVariableValueByGroup(String name, int groupId){
|
public int SetEntityServerGlobalValueByEntityId(int entityId, String sgvName, int value) {
|
||||||
logger.debug("[LUA] Call GetGroupVariableValueByGroup with {},{}",
|
logger.debug("[LUA] Call SetEntityServerGlobalValueByEntityId with {}, {}, {}",
|
||||||
name,groupId);
|
entityId, sgvName, value);
|
||||||
|
|
||||||
return getSceneScriptManager().getVariables(groupId).getOrDefault(name, 0);
|
var scriptManager = this.getSceneScriptManager();
|
||||||
}
|
if (scriptManager == null) return 1;
|
||||||
public int ChangeGroupVariableValueByGroup(String name, int value, int groupId){
|
|
||||||
logger.debug("[LUA] Call ChangeGroupVariableValueByGroup with {},{}",
|
var scene = scriptManager.getScene();
|
||||||
name,groupId);
|
|
||||||
//TODO test
|
scene.runWhenHostInitialized(() -> scene.broadcastPacket(
|
||||||
getSceneScriptManager().getVariables(groupId).put(name, value);
|
new PacketServerGlobalValueChangeNotify(entityId, sgvName, value)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,14 +586,6 @@ public class ScriptLib {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int SetGroupVariableValueByGroup(String key, int value, int groupId){
|
|
||||||
logger.debug("[LUA] Call SetGroupVariableValueByGroup with {},{},{}",
|
|
||||||
key,value,groupId);
|
|
||||||
|
|
||||||
getSceneScriptManager().getVariables(groupId).put(key, value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int CreateMonster(LuaTable table){
|
public int CreateMonster(LuaTable table){
|
||||||
logger.debug("[LUA] Call CreateMonster with {}",
|
logger.debug("[LUA] Call CreateMonster with {}",
|
||||||
printTable(table));
|
printTable(table));
|
||||||
@ -959,7 +962,7 @@ public class ScriptLib {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
public int EndTimeAxis(String var1){
|
public int EndTimeAxis(String var1){
|
||||||
logger.warn("[LUA] Call unimplemented EndTimeAxis with {} {} {}", var1);
|
logger.warn("[LUA] Call unimplemented EndTimeAxis with {}", var1);
|
||||||
//TODO implement var1 == name?
|
//TODO implement var1 == name?
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1075,6 +1078,12 @@ public class ScriptLib {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int ClearPlayerEyePoint(int var1){
|
||||||
|
logger.warn("[LUA] Call unimplemented ClearPlayerEyePoint with {}", var1);
|
||||||
|
//TODO implement
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public int MoveAvatarByPointArray(int uid, int targetId, LuaTable var3, String var4){
|
public int MoveAvatarByPointArray(int uid, int targetId, LuaTable var3, String var4){
|
||||||
logger.warn("[LUA] Call unimplemented MoveAvatarByPointArray with {} {} {} {}", uid, targetId, printTable(var3), var4);
|
logger.warn("[LUA] Call unimplemented MoveAvatarByPointArray with {} {} {} {}", uid, targetId, printTable(var3), var4);
|
||||||
//TODO implement var3 contains int speed, var4 is a json string
|
//TODO implement var3 contains int speed, var4 is a json string
|
||||||
@ -1133,7 +1142,7 @@ public class ScriptLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int PlayCutSceneWithParam(int cutsceneId, int var2, LuaTable var3){
|
public int PlayCutSceneWithParam(int cutsceneId, int var2, LuaTable var3){
|
||||||
logger.warn("[LUA] Call unimplemented PlayCutScene with {} {}", cutsceneId, var2, var3);
|
logger.warn("[LUA] Call unimplemented PlayCutScene with {} {} {}", cutsceneId, var2, var3);
|
||||||
//TODO implement
|
//TODO implement
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1310,6 +1319,13 @@ public class ScriptLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
configRoute.setRouteId(routeId);
|
configRoute.setRouteId(routeId);
|
||||||
|
configRoute.setStartIndex(0);
|
||||||
|
configRoute.setStarted(false);
|
||||||
|
for(var task : configRoute.getScheduledIndexes()) {
|
||||||
|
sceneScriptManager.get().getScene().getScheduler().cancelTask(task);
|
||||||
|
}
|
||||||
|
configRoute.getScheduledIndexes().clear();
|
||||||
|
|
||||||
sceneScriptManager.get().getScene().broadcastPacket(new PacketPlatformChangeRouteNotify(entityGadget));
|
sceneScriptManager.get().getScene().broadcastPacket(new PacketPlatformChangeRouteNotify(entityGadget));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,10 @@ public class ScriptArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ScriptArgs(int groupId, int eventType, int param1, int param2) {
|
public ScriptArgs(int groupId, int eventType, int param1, int param2) {
|
||||||
|
this.group_id = groupId;
|
||||||
this.type = eventType;
|
this.type = eventType;
|
||||||
this.param1 = param1;
|
this.param1 = param1;
|
||||||
this.param2 = param2;
|
this.param2 = param2;
|
||||||
this.group_id = groupId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getParam1() {
|
public int getParam1() {
|
||||||
|
@ -113,6 +113,7 @@ public final class HttpServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
serverConnector.setPort(HTTP_INFO.bindPort);
|
serverConnector.setPort(HTTP_INFO.bindPort);
|
||||||
|
serverConnector.setHost(HTTP_INFO.bindAddress);
|
||||||
server.setConnectors(new ServerConnector[]{serverConnector});
|
server.setConnectors(new ServerConnector[]{serverConnector});
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
|
@ -13,42 +13,41 @@ public class HandlerEnterSceneDoneReq extends PacketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
|
var player = session.getPlayer();
|
||||||
|
|
||||||
// Finished loading
|
// Finished loading
|
||||||
session.getPlayer().setSceneLoadState(SceneLoadState.LOADED);
|
player.setSceneLoadState(SceneLoadState.LOADED);
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
|
|
||||||
session.send(new PacketPlayerTimeNotify(session.getPlayer())); // Probably not the right place
|
session.send(new PacketPlayerTimeNotify(player)); // Probably not the right place
|
||||||
|
|
||||||
// Spawn player in world
|
// Spawn player in world
|
||||||
session.getPlayer().getScene().spawnPlayer(session.getPlayer());
|
player.getScene().spawnPlayer(player);
|
||||||
|
|
||||||
// Spawn other entites already in world
|
// Spawn other entites already in world
|
||||||
session.getPlayer().getScene().showOtherEntities(session.getPlayer());
|
player.getScene().showOtherEntities(player);
|
||||||
|
|
||||||
// Locations
|
// Locations
|
||||||
session.send(new PacketWorldPlayerLocationNotify(session.getPlayer().getWorld()));
|
session.send(new PacketWorldPlayerLocationNotify(player.getWorld()));
|
||||||
session.send(new PacketScenePlayerLocationNotify(session.getPlayer().getScene()));
|
session.send(new PacketScenePlayerLocationNotify(player.getScene()));
|
||||||
session.send(new PacketWorldPlayerRTTNotify(session.getPlayer().getWorld()));
|
session.send(new PacketWorldPlayerRTTNotify(player.getWorld()));
|
||||||
|
|
||||||
// spawn NPC
|
// spawn NPC
|
||||||
session.getPlayer().getScene().loadNpcForPlayerEnter(session.getPlayer());
|
player.getScene().loadNpcForPlayerEnter(player);
|
||||||
|
|
||||||
// notify client to load the npc for quest
|
// notify client to load the npc for quest
|
||||||
var questGroupSuites =
|
var questGroupSuites = player.getQuestManager().getSceneGroupSuite(player.getSceneId());
|
||||||
session.getPlayer().getQuestManager().getSceneGroupSuite(session.getPlayer().getSceneId());
|
|
||||||
|
|
||||||
session.getPlayer().getScene().loadGroupForQuest(questGroupSuites);
|
player.getScene().loadGroupForQuest(questGroupSuites);
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.trace(
|
.trace("Loaded Scene {} Quest(s) Groupsuite(s): {}", player.getSceneId(), questGroupSuites);
|
||||||
"Loaded Scene {} Quest(s) Groupsuite(s): {}",
|
|
||||||
session.getPlayer().getSceneId(),
|
|
||||||
questGroupSuites);
|
|
||||||
session.send(new PacketGroupSuiteNotify(questGroupSuites));
|
session.send(new PacketGroupSuiteNotify(questGroupSuites));
|
||||||
|
|
||||||
// Reset timer for sending player locations
|
// Reset timer for sending player locations
|
||||||
session.getPlayer().resetSendPlayerLocTime();
|
player.resetSendPlayerLocTime();
|
||||||
|
|
||||||
// Rsp
|
// Rsp
|
||||||
session.send(new PacketEnterSceneDoneRsp(session.getPlayer()));
|
session.send(new PacketEnterSceneDoneRsp(player));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ public class HandlerPostEnterSceneReq extends PacketHandler {
|
|||||||
if (dungeonManager != null) dungeonManager.startDungeon();
|
if (dungeonManager != null) dungeonManager.startDungeon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
questManager.queueEvent(QuestContent.QUEST_CONTENT_LEAVE_SCENE, scene.getPrevScene());
|
||||||
|
|
||||||
session.send(new PacketPostEnterSceneRsp(session.getPlayer()));
|
session.send(new PacketPostEnterSceneRsp(session.getPlayer()));
|
||||||
}
|
}
|
||||||
|
@ -13,28 +13,33 @@ public class HandlerSceneInitFinishReq extends PacketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
|
var player = session.getPlayer();
|
||||||
|
var world = player.getWorld();
|
||||||
|
|
||||||
// Info packets
|
// Info packets
|
||||||
session.send(new PacketServerTimeNotify());
|
session.send(new PacketServerTimeNotify());
|
||||||
session.send(new PacketWorldPlayerInfoNotify(session.getPlayer().getWorld()));
|
session.send(new PacketWorldPlayerInfoNotify(world));
|
||||||
session.send(new PacketWorldDataNotify(session.getPlayer().getWorld()));
|
session.send(new PacketWorldDataNotify(world));
|
||||||
session.send(new PacketPlayerWorldSceneInfoListNotify());
|
session.send(new PacketPlayerWorldSceneInfoListNotify());
|
||||||
session.send(new BasePacket(PacketOpcodes.SceneForceUnlockNotify));
|
session.send(new BasePacket(PacketOpcodes.SceneForceUnlockNotify));
|
||||||
session.send(new PacketHostPlayerNotify(session.getPlayer().getWorld()));
|
session.send(new PacketHostPlayerNotify(world));
|
||||||
|
|
||||||
session.send(new PacketSceneTimeNotify(session.getPlayer()));
|
session.send(new PacketSceneTimeNotify(player));
|
||||||
session.send(new PacketPlayerGameTimeNotify(session.getPlayer()));
|
session.send(new PacketPlayerGameTimeNotify(player));
|
||||||
session.send(new PacketPlayerEnterSceneInfoNotify(session.getPlayer()));
|
session.send(new PacketPlayerEnterSceneInfoNotify(player));
|
||||||
session.send(new PacketSceneAreaWeatherNotify(session.getPlayer()));
|
session.send(new PacketSceneAreaWeatherNotify(player));
|
||||||
session.send(new PacketScenePlayerInfoNotify(session.getPlayer().getWorld()));
|
session.send(new PacketScenePlayerInfoNotify(world));
|
||||||
session.send(new PacketSceneTeamUpdateNotify(session.getPlayer()));
|
session.send(new PacketSceneTeamUpdateNotify(player));
|
||||||
|
|
||||||
session.send(new PacketSyncTeamEntityNotify(session.getPlayer()));
|
session.send(new PacketSyncTeamEntityNotify(player));
|
||||||
session.send(new PacketSyncScenePlayTeamEntityNotify(session.getPlayer()));
|
session.send(new PacketSyncScenePlayTeamEntityNotify(player));
|
||||||
|
|
||||||
// Done Packet
|
// Done Packet
|
||||||
session.send(new PacketSceneInitFinishRsp(session.getPlayer()));
|
session.send(new PacketSceneInitFinishRsp(player));
|
||||||
|
|
||||||
// Set state
|
// Set scene load state.
|
||||||
session.getPlayer().setSceneLoadState(SceneLoadState.INIT);
|
player.setSceneLoadState(SceneLoadState.INIT);
|
||||||
|
// Run scene initialization.
|
||||||
|
player.getScene().playerSceneInitialized(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ public class HandlerUnlockPersonalLineReq extends PacketHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
session.getPlayer().getQuestManager().addQuest(data.getStartQuestId());
|
|
||||||
session.getPlayer().addPersonalLine(data.getId());
|
session.getPlayer().addPersonalLine(data.getId());
|
||||||
session.getPlayer().useLegendaryKey(1);
|
session.getPlayer().useLegendaryKey(1);
|
||||||
|
|
||||||
|
@ -16,4 +16,14 @@ public final class PacketServerGlobalValueChangeNotify extends BasePacket {
|
|||||||
.setValue(value)
|
.setValue(value)
|
||||||
.setKeyHash(Utils.abilityHash(abilityHash)));
|
.setKeyHash(Utils.abilityHash(abilityHash)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketServerGlobalValueChangeNotify(int entityId, String abilityHash, int value) {
|
||||||
|
super(PacketOpcodes.ServerGlobalValueChangeNotify);
|
||||||
|
|
||||||
|
this.setData(
|
||||||
|
ServerGlobalValueChangeNotify.newBuilder()
|
||||||
|
.setEntityId(entityId)
|
||||||
|
.setValue(value)
|
||||||
|
.setKeyHash(Utils.abilityHash(abilityHash)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public final class ServerTask implements Runnable {
|
|||||||
*/
|
*/
|
||||||
public boolean shouldRun() {
|
public boolean shouldRun() {
|
||||||
// Increase tick count.
|
// Increase tick count.
|
||||||
var ticks = this.ticks++;
|
++this.ticks;
|
||||||
if (this.delay != -1 && this.considerDelay) {
|
if (this.delay != -1 && this.considerDelay) {
|
||||||
// Check if the task should run.
|
// Check if the task should run.
|
||||||
var shouldRun = ticks >= this.delay;
|
var shouldRun = ticks >= this.delay;
|
||||||
|
@ -64,9 +64,9 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"loading": "Chargement des ressources...",
|
"loading": "Chargement des ressources...",
|
||||||
"finish": "Chargement des ressources terminé.",
|
"finish": "Chargement des ressources terminé.",
|
||||||
"custom": "🇺🇸Find additional resources at: 'Anime-Game-Servers/CustomGCResources'.",
|
"custom": "Obtenez des ressources additionelles à: 'Anime-Game-Servers/CustomGCResources'.",
|
||||||
"missing_server": "🇺🇸To fully use questing, it is recommended to add the 'Server' folder.",
|
"missing_server": "Pour utiliser pleinement les quetes, il est recommendé d'ajouter le dossier 'Server'.",
|
||||||
"missing_scenes": "🇺🇸To fully use questing, it is recommended to add the 'ScriptSceneData' folder."
|
"missing_scenes": "Pour utiliser pleinement les quetes, il est recommendé d'ajouter le dossier 'ScriptSceneData'."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -87,7 +87,7 @@
|
|||||||
"artifactId": "ID de l'artéfact invalide.",
|
"artifactId": "ID de l'artéfact invalide.",
|
||||||
"avatarId": "ID de l'avatar invalide.",
|
"avatarId": "ID de l'avatar invalide.",
|
||||||
"avatarLevel": "avatarLevel invalide.",
|
"avatarLevel": "avatarLevel invalide.",
|
||||||
"cfgId": "🇺🇸Invalid cfg ID.",
|
"cfgId": "ID de cfg invalide.",
|
||||||
"entityId": "ID de l'entité invalide.",
|
"entityId": "ID de l'entité invalide.",
|
||||||
"itemId": "ID de l'objet invalide.",
|
"itemId": "ID de l'objet invalide.",
|
||||||
"itemLevel": "Niveau de l'objet invalide.",
|
"itemLevel": "Niveau de l'objet invalide.",
|
||||||
@ -171,8 +171,8 @@
|
|||||||
"description": "Entrer dans un donjon"
|
"description": "Entrer dans un donjon"
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
"description": "🇺🇸Modify an existing entity's properties",
|
"description": "Modifie les propriétés d'une entité existante",
|
||||||
"not_found_error": "🇺🇸Entity does not exist"
|
"not_found_error": "L'entité n'existe pas"
|
||||||
},
|
},
|
||||||
"give": {
|
"give": {
|
||||||
"usage_relic": "Utilisation: give <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<level 0-20>]",
|
"usage_relic": "Utilisation: give <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<level 0-20>]",
|
||||||
@ -239,31 +239,31 @@
|
|||||||
"not_found": "Quête introuvable.",
|
"not_found": "Quête introuvable.",
|
||||||
"invalid_id": "ID de la quête invalide.",
|
"invalid_id": "ID de la quête invalide.",
|
||||||
"description": "Ajoute ou termine une quête",
|
"description": "Ajoute ou termine une quête",
|
||||||
"running": "🇺🇸Quest %s is %s (%s).",
|
"running": "La quête %s est %s (%s).",
|
||||||
"talking": "🇺🇸Talk %s is %s for main quest %s (%s).",
|
"talking": "Le dialogue %s est %s pour la quête principale %s (%s).",
|
||||||
"state": {
|
"state": {
|
||||||
"none": "🇺🇸unknown (none)",
|
"none": "Inconnu (none)",
|
||||||
"unstarted": "🇺🇸unfinished (not started, not completed)",
|
"unstarted": "Pas finie (pas démarée, pas complêtée)",
|
||||||
"unfinished": "🇺🇸unfinished (started, not completed)",
|
"unfinished": "Pas finie (Démarée, pas complêtée)",
|
||||||
"finished": "🇺🇸finished (completed)",
|
"finished": "Terminée (complêtée)",
|
||||||
"failed": "🇺🇸finished (completed, but failed)",
|
"failed": "Terminée (complêtée, mais échouée)",
|
||||||
"exists": "🇺🇸found",
|
"exists": "Trouvée",
|
||||||
"not_exists": "🇺🇸not found"
|
"not_exists": "Introuvable"
|
||||||
},
|
},
|
||||||
"enabled": "Quêtes activées."
|
"enabled": "Quêtes activées."
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"invalid_groupid": "🇺🇸Invalid group ID.",
|
"invalid_groupid": "ID de groupe invalide.",
|
||||||
"invalid_suiteid": "🇺🇸Invalid suite ID.",
|
"invalid_suiteid": "ID de suite invalide.",
|
||||||
"group_not_found": "🇺🇸Group not found.",
|
"group_not_found": "Groupe introuvable",
|
||||||
"description": "🇺🇸Alter group loading",
|
"description": "Altère le chargement de groupe",
|
||||||
"refreshed": "🇺🇸Group %s refreshed."
|
"refreshed": "Groupe %s actualisé"
|
||||||
},
|
},
|
||||||
"cutscene": {
|
"cutscene": {
|
||||||
"description": "Joue une cinématique"
|
"description": "Joue une cinématique"
|
||||||
},
|
},
|
||||||
"sound": {
|
"sound": {
|
||||||
"description": "🇺🇸Plays a sound"
|
"description": "Joue un son"
|
||||||
},
|
},
|
||||||
"reload": {
|
"reload": {
|
||||||
"reload_start": "Rechargement de la configuration.",
|
"reload_start": "Rechargement de la configuration.",
|
||||||
@ -408,7 +408,7 @@
|
|||||||
"description": "Retire le bannissement d'un joueur"
|
"description": "Retire le bannissement d'un joueur"
|
||||||
},
|
},
|
||||||
"troubleshoot": {
|
"troubleshoot": {
|
||||||
"description": "🇺🇸Generate debugging information for troubleshooting."
|
"description": "Génère des informations de déboguage pour le dépannage."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gacha": {
|
"gacha": {
|
||||||
@ -462,9 +462,9 @@
|
|||||||
"disabling_plugin": "Désactivation du plugin %s",
|
"disabling_plugin": "Désactivation du plugin %s",
|
||||||
"disabling_failed": "Impossible de désactiver le plugin %s",
|
"disabling_failed": "Impossible de désactiver le plugin %s",
|
||||||
"invalid_api": {
|
"invalid_api": {
|
||||||
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
"not_present": "Le plugin %s ne spécifie pas de version d'API.",
|
||||||
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s.",
|
"lower": "Le plugin %s utilise la version %s de l'API, alors que le serveur utilise la version %s.",
|
||||||
"outdated": "🇺🇸Plugin %s is using an outdated API method."
|
"outdated": "Le plugin %s utilise une fonction obsolète de l'API."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
"request": "[Dispatch] Client %s %s richiesta: %s",
|
"request": "[Dispatch] Client %s %s richiesta: %s",
|
||||||
"keystore": {
|
"keystore": {
|
||||||
"general_error": "[Dispatch] Errore nel caricamento di keystore!",
|
"general_error": "[Dispatch] Errore nel caricamento di keystore!",
|
||||||
"password_error": "[Dispatch] Impossibile caricare il keystore. Provando passwrd di default keystore...",
|
"password_error": "[Dispatch] Impossibile caricare il keystore. Provando password di default keystore...",
|
||||||
"no_keystore_error": "[Dispatch] Nessun cert SSL trovato! Ritorno ad un server HTTP.",
|
"no_keystore_error": "[Dispatch] Nessun cert SSL trovato! Ritornando ad un server HTTP.",
|
||||||
"default_password": "[Dispatch] La password di default del keystore è stata caricata con successo. Considera di impostare la password a 123456 in config.json."
|
"default_password": "[Dispatch] La password di default del keystore è stata caricata con successo. Prova ad impostare la password a 123456 in config.json."
|
||||||
},
|
},
|
||||||
"authentication": {
|
"authentication": {
|
||||||
"default_unable_to_verify": "[Authentication] [Autenticazione] Qualcosa ha chiamato metodo VerifyUser che non è disponibile nel gestore di autenticazione predefinito."
|
"default_unable_to_verify": "[Authentication] [Autenticazione] Qualcosa ha chiamato metodo VerifyUser che non è disponibile nel gestore di autenticazione predefinito."
|
||||||
@ -24,8 +24,8 @@
|
|||||||
"no_commands_error": "I comandi non sono supportati in modalità solo dispatch.",
|
"no_commands_error": "I comandi non sono supportati in modalità solo dispatch.",
|
||||||
"unhandled_request_error": "[Dispatch] Potenziali %s richieste non gestite: %s.",
|
"unhandled_request_error": "[Dispatch] Potenziali %s richieste non gestite: %s.",
|
||||||
"account": {
|
"account": {
|
||||||
"login_attempt": "[Dispatch] Il client %s sta provando a fare il login.",
|
"login_attempt": "[Dispatch] Il client %s sta provando ad accedere.",
|
||||||
"login_success": "[Dispatch] Client %s loggato come %s.",
|
"login_success": "[Dispatch] Client %s ha accesso come %s.",
|
||||||
"login_max_player_limit": "[Dispatch] Client %s non è riuscito ad accedere: Il numero di giocatori online ha raggiunto il limite",
|
"login_max_player_limit": "[Dispatch] Client %s non è riuscito ad accedere: Il numero di giocatori online ha raggiunto il limite",
|
||||||
"login_token_attempt": "[Dispatch] Il client %s sta tentando di accedere tramite token.",
|
"login_token_attempt": "[Dispatch] Il client %s sta tentando di accedere tramite token.",
|
||||||
"login_token_error": "[Dispatch] Client %s non è riuscito ad accedere tramite token.",
|
"login_token_error": "[Dispatch] Client %s non è riuscito ad accedere tramite token.",
|
||||||
@ -49,24 +49,24 @@
|
|||||||
"router_error": "[Dispatch] Impossibile collegare il router."
|
"router_error": "[Dispatch] Impossibile collegare il router."
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"free_software": "Grasscutter è un software GRATUITO. Se hai pagato per questo, potresti essere stato truffato. Homepage: https://github.com/Grasscutters/Grasscutter",
|
"free_software": "Grasscutter è un software GRATUITO. Se lo hai pagato, potresti essere stato truffato. Homepage: https://github.com/Grasscutters/Grasscutter",
|
||||||
"starting": "Avvio di Grasscutter...",
|
"starting": "Avvio di Grasscutter...",
|
||||||
"shutdown": "Chiusura in corso...",
|
"shutdown": "Chiusura in corso...",
|
||||||
"done": "Fatto! Per aiuto, digita \"help\"",
|
"done": "Fatto! Per aiuto, digita \"help\"",
|
||||||
"error": "Si è verificato un errore.",
|
"error": "Si è verificato un errore.",
|
||||||
"welcome": "Benvenuto in Grasscutter!",
|
"welcome": "Benvenuto a Grasscutter!",
|
||||||
"run_mode_error": "Modalità di esecuzione del server non valida: %s.",
|
"run_mode_error": "Modalità di esecuzione del server non valida: %s.",
|
||||||
"run_mode_help": "La modalità di esecuzione del server deve essere 'HYBRID', 'DISPATCH_ONLY' o 'GAME_ONLY'. Impossibile avviare Grasscutter...",
|
"run_mode_help": "La modalità di esecuzione del server deve essere 'HYBRID', 'DISPATCH_ONLY' o 'GAME_ONLY'. Impossibile avviare Grasscutter...",
|
||||||
"create_resources": "Creazione cartella risorse...",
|
"create_resources": "Creazione cartella delle risorse...",
|
||||||
"resources_error": "Inserisci una copia di 'BinOutput' e 'ExcelBinOutput' nella cartella delle risorse.",
|
"resources_error": "Inserisci una copia di 'BinOutput' e 'ExcelBinOutput' nella cartella delle risorse.",
|
||||||
"version": "Versione Grassscutter: %s-%s",
|
"version": "Versione Grassscutter: %s-%s",
|
||||||
"game_version": "Versione del gioco: %s",
|
"game_version": "Versione del gioco: %s",
|
||||||
"resources": {
|
"resources": {
|
||||||
"loading": "Caricamento risorse...",
|
"loading": "Caricamento risorse...",
|
||||||
"finish": "Terminato il caricamento delle risorse.",
|
"finish": "Terminato il caricamento delle risorse.",
|
||||||
"custom": "🇺🇸Find additional resources at: 'Anime-Game-Servers/CustomGCResources'.",
|
"custom": "Puoi trovare risorse aggiuntive a: 'Anime-Game-Servers/CustomGCResources'.",
|
||||||
"missing_server": "🇺🇸To fully use questing, it is recommended to add the 'Server' folder.",
|
"missing_server": "Per usare questing al completo, è consigliato aggiungere la cartella 'Server'.",
|
||||||
"missing_scenes": "🇺🇸To fully use questing, it is recommended to add the 'ScriptSceneData' folder."
|
"missing_scenes": "Per usare questing al completo, è consigliato aggiungere la cartella 'ScriptSceneData'."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -84,10 +84,10 @@
|
|||||||
"set_for_to": "%s per %s impostato su %s.",
|
"set_for_to": "%s per %s impostato su %s.",
|
||||||
"invalid": {
|
"invalid": {
|
||||||
"amount": "Importo non valido.",
|
"amount": "Importo non valido.",
|
||||||
"artifactId": "ID artefatto non valido.",
|
"artifactId": "ID manufatto non valido.",
|
||||||
"avatarId": "ID avatar non valido.",
|
"avatarId": "🇺🇸Invalid avatar ID.",
|
||||||
"avatarLevel": "Livello avatar non valido.",
|
"avatarLevel": "🇺🇸Invalid avatarLevel.",
|
||||||
"cfgId": "🇺🇸Invalid cfg ID.",
|
"cfgId": "cfg ID invalido.",
|
||||||
"entityId": "ID entità non valido.",
|
"entityId": "ID entità non valido.",
|
||||||
"itemId": "ID articolo non valido.",
|
"itemId": "ID articolo non valido.",
|
||||||
"itemLevel": "ItemLevel non valido.",
|
"itemLevel": "ItemLevel non valido.",
|
||||||
@ -130,25 +130,25 @@
|
|||||||
},
|
},
|
||||||
"achievement": {
|
"achievement": {
|
||||||
"success": {
|
"success": {
|
||||||
"grant": "🇺🇸Granted the achievement to %s.",
|
"grant": "Concesso l'obbiettivo a %s.",
|
||||||
"revoke": "🇺🇸Revoked the achievement from %s.",
|
"revoke": "Revocato l'obbiettivo from %s.",
|
||||||
"progress": "🇺🇸Set progress of %s's achievement(id: %s) to %s.",
|
"progress": "Impostato il progresso della completazione dell'obbiettivo(id: %s) di %s a %s.",
|
||||||
"grantall": "🇺🇸Granted %s achievement(s) to %s.",
|
"grantall": "Concesso/i l'/gli obbiettivo/i a %s.",
|
||||||
"revokeall": "🇺🇸Revoked %s achievement(s) from %s."
|
"revokeall": "Revocato/i l'/gli obbiettivo/i da %s."
|
||||||
},
|
},
|
||||||
"fail": {
|
"fail": {
|
||||||
"achievement_not_found": "🇺🇸Achievement not found.",
|
"achievement_not_found": "Obbiettivo non trovato.",
|
||||||
"already_achieved": "🇺🇸%s has already achieved the achievement.",
|
"already_achieved": "%s ha già completato l'obbiettivo.",
|
||||||
"not_yet_achieved": "🇺🇸%s hasn't achieved the achievement yet."
|
"not_yet_achieved": "🇺🇸%s non ha ancora completato l'obbiettivo."
|
||||||
},
|
},
|
||||||
"description": "🇺🇸Grant, Revoke or Progress achievements."
|
"description": "Concedi, revoca o imposta il progresso della completazione degli obbiettivi."
|
||||||
},
|
},
|
||||||
"announce": {
|
"announce": {
|
||||||
"send_success": "Invia un annuncio con successo, puoi revocarlo /a revoca %s.",
|
"send_success": "Invia un annuncio con successo, puoi revocarlo /a revoca %s.",
|
||||||
"refresh_success": "Aggiorna il file di configurazione dell'annuncio con successo. [Totale %s]",
|
"refresh_success": "Aggiorna il file di configurazione dell'annuncio con successo. [Totale %s]",
|
||||||
"revoke_done": "Prova a revocare l'annuncio %s.",
|
"revoke_done": "Prova a revocare l'annuncio %s.",
|
||||||
"not_found": "Impossibile trovare l'annuncio %s.",
|
"not_found": "Impossibile trovare l'annuncio %s.",
|
||||||
"description": "Invia annuncio a tutti i giocatori online o gestisci l'annuncio del server"
|
"description": "Invia un annuncio a tutti i giocatori online o gestisci l'annuncio del server"
|
||||||
},
|
},
|
||||||
"clear": {
|
"clear": {
|
||||||
"weapons": "Armi cancellate per %s.",
|
"weapons": "Armi cancellate per %s.",
|
||||||
@ -162,7 +162,7 @@
|
|||||||
},
|
},
|
||||||
"coop": {
|
"coop": {
|
||||||
"success": "Convocato %s nel mondo di %s.",
|
"success": "Convocato %s nel mondo di %s.",
|
||||||
"description": "Forza qualcuno a unirsi al mondo degli altri. Se nessuno viene preso di mira, ti manda comunque in modalità cooperativa."
|
"description": "Forza qualcuno a unirsi al mondo degli altri. Se il bersaglio non è impostato, ti manda comunque in modalità cooperativa."
|
||||||
},
|
},
|
||||||
"enter_dungeon": {
|
"enter_dungeon": {
|
||||||
"changed": "Cambiato nel dungeon %s.",
|
"changed": "Cambiato nel dungeon %s.",
|
||||||
@ -171,22 +171,22 @@
|
|||||||
"description": "Entra in un dungeon"
|
"description": "Entra in un dungeon"
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
"description": "🇺🇸Modify an existing entity's properties",
|
"description": "Modifica le proprietà di un entità esistente",
|
||||||
"not_found_error": "🇺🇸Entity does not exist"
|
"not_found_error": "L'entità non esiste."
|
||||||
},
|
},
|
||||||
"give": {
|
"give": {
|
||||||
"usage_relic": "Utilizzo: fornire <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<livello 0-20>]",
|
"usage_relic": "Utilizzo: fornire <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<livello 0-20>]",
|
||||||
"illegal_relic": "Questo ID artefatto appartiene a un intervallo nella blacklist, potrebbe non essere quello che volevi.",
|
"illegal_relic": "Questo ID manufatto appartiene a un intervallo nella blacklist, potrebbe non essere quello che volevi.",
|
||||||
"given": "Dato %s di %s a %s.",
|
"given": "Dato %s di %s a %s.",
|
||||||
"given_with_level_and_refinement": "Dato %s con livello %s, perfezionamento %s %s volte a %s.",
|
"given_with_level_and_refinement": "Dato %s con livello %s, perfezionamento %s %s volte a %s.",
|
||||||
"given_level": "Dato %s con livello %s %s volte a %s.",
|
"given_level": "Dato %s con livello %s %s volte a %s.",
|
||||||
"given_avatar": "Dato %s con livello da %s a %s.",
|
"given_avatar": "🇺🇸Given %s with level %s to %s.",
|
||||||
"giveall_success": "Ha dato tutti gli oggetti con successo.",
|
"giveall_success": "Ha dato tutti gli oggetti con successo.",
|
||||||
"description": "Dà un oggetto a te o al giocatore specificato. Può anche dare tutte le armi, avatar e/o materiali, e può costruire artefatti personalizzati."
|
"description": "Dà un oggetto a te o al giocatore specificato. Può anche dare tutte le armi, Avatar e/o materiali, e può costruire manufatti personalizzati."
|
||||||
},
|
},
|
||||||
"heal": {
|
"heal": {
|
||||||
"success": "Tutti i personaggi sono stati curati.",
|
"success": "Tutti i personaggi sono stati curati.",
|
||||||
"description": "Guarisci tutti i personaggi della tua squadra attuale."
|
"description": "Guarisce tutti i personaggi della tua squadra attuale"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"aliases": "Alias: ",
|
"aliases": "Alias: ",
|
||||||
@ -199,26 +199,26 @@
|
|||||||
},
|
},
|
||||||
"kick": {
|
"kick": {
|
||||||
"player_kick_player": "Il giocatore [%s:%s] ha espulso un giocatore [%s:%s]",
|
"player_kick_player": "Il giocatore [%s:%s] ha espulso un giocatore [%s:%s]",
|
||||||
"server_kick_player": "Ha preso a calci il giocatore [%s:%s]...",
|
"server_kick_player": "È stato espulso il giocatore [%s:%s]...",
|
||||||
"description": "Espelle il giocatore specificato dal server (WIP)"
|
"description": "Espelle il giocatore specificato dal server (WIP)"
|
||||||
},
|
},
|
||||||
"killall": {
|
"killall": {
|
||||||
"scene_not_found_in_player_world": "Scena non trovata nel mondo del giocatore.",
|
"scene_not_found_in_player_world": "Scena non trovata nel mondo del giocatore.",
|
||||||
"kill_monsters_in_scene": "Uccidere %s mostri nella scena %s.",
|
"kill_monsters_in_scene": "Uccisi %s mostri nella scena %s.",
|
||||||
"description": "Uccidi tutte le entità"
|
"description": "Uccide tutte le entità"
|
||||||
},
|
},
|
||||||
"killCharacter": {
|
"killCharacter": {
|
||||||
"success": "Hai ucciso il personaggio attuale di %s.",
|
"success": "Ucciso il personaggio attuale di %s.",
|
||||||
"description": "Uccide il personaggio attuale del giocatore"
|
"description": "Uccide il personaggio attuale del giocatore"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"current_language": "La lingua attuale è %s.",
|
"current_language": "La lingua attuale è %s.",
|
||||||
"language_changed": "Lingua modificata in %s.",
|
"language_changed": "Lingua cambiata a %s.",
|
||||||
"language_not_found": "Attualmente, il server non ha quella lingua.",
|
"language_not_found": "Attualmente, il server non ha quella lingua.",
|
||||||
"description": "Mostra o cambia la lingua corrente"
|
"description": "Mostra o cambia la lingua corrente"
|
||||||
},
|
},
|
||||||
"list": {
|
"list": {
|
||||||
"success": "Ci sono %s player(s) online:",
|
"success": "Ci sono %s player online:",
|
||||||
"description": "Lista player online"
|
"description": "Lista player online"
|
||||||
},
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
@ -231,7 +231,7 @@
|
|||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"success": "Coordinate: %s, %s, %s\nRotazione:%s, %s, %s\nID scena: %a",
|
"success": "Coordinate: %s, %s, %s\nRotazione:%s, %s, %s\nID scena: %a",
|
||||||
"description": "Ottiene informazioni sulla posizione e sulla rotazione"
|
"description": "Ottiene informazioni sulla posizione e sulla rotazione attuale del giocatore"
|
||||||
},
|
},
|
||||||
"quest": {
|
"quest": {
|
||||||
"added": "Missione %s aggiunta.",
|
"added": "Missione %s aggiunta.",
|
||||||
@ -239,39 +239,39 @@
|
|||||||
"not_found": "Missione non trovata.",
|
"not_found": "Missione non trovata.",
|
||||||
"invalid_id": "ID missione non valido.",
|
"invalid_id": "ID missione non valido.",
|
||||||
"description": "Aggiungi o completa missioni",
|
"description": "Aggiungi o completa missioni",
|
||||||
"running": "🇺🇸Quest %s is %s (%s).",
|
"running": "Missione %s è %s (%s).",
|
||||||
"talking": "🇺🇸Talk %s is %s for main quest %s (%s).",
|
"talking": "Talk %s è %s per la missione principale %s (%s).",
|
||||||
"state": {
|
"state": {
|
||||||
"none": "🇺🇸unknown (none)",
|
"none": "sconosciuta (nessuna)",
|
||||||
"unstarted": "🇺🇸unfinished (not started, not completed)",
|
"unstarted": "incompleta (not cominciata, non completata)",
|
||||||
"unfinished": "🇺🇸unfinished (started, not completed)",
|
"unfinished": "incompleta (cominciata, non completata)",
|
||||||
"finished": "🇺🇸finished (completed)",
|
"finished": "completa (completata)",
|
||||||
"failed": "🇺🇸finished (completed, but failed)",
|
"failed": "incompleta (completata, ma fallita)",
|
||||||
"exists": "🇺🇸found",
|
"exists": "Missione esistente",
|
||||||
"not_exists": "🇺🇸not found"
|
"not_exists": "Missione non esistente."
|
||||||
},
|
},
|
||||||
"enabled": "🇺🇸Questing enabled."
|
"enabled": "Questing abilitato."
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"invalid_groupid": "🇺🇸Invalid group ID.",
|
"invalid_groupid": "group ID non valido.",
|
||||||
"invalid_suiteid": "🇺🇸Invalid suite ID.",
|
"invalid_suiteid": "suite ID non valido.",
|
||||||
"group_not_found": "🇺🇸Group not found.",
|
"group_not_found": "group non trovato.",
|
||||||
"description": "🇺🇸Alter group loading",
|
"description": "Carica Alter Group",
|
||||||
"refreshed": "🇺🇸Group %s refreshed."
|
"refreshed": "Group %s ricaricato."
|
||||||
},
|
},
|
||||||
"cutscene": {
|
"cutscene": {
|
||||||
"description": "Riproduce un filmato"
|
"description": "Riproduce una cutscene"
|
||||||
},
|
},
|
||||||
"sound": {
|
"sound": {
|
||||||
"description": "🇺🇸Plays a sound"
|
"description": "Riproduce un suono"
|
||||||
},
|
},
|
||||||
"reload": {
|
"reload": {
|
||||||
"reload_start": "Ricarica configurazione.",
|
"reload_start": "Ricarica in configurazione.",
|
||||||
"reload_done": "Ricarica completa.",
|
"reload_done": "Ricarica completa.",
|
||||||
"description": "Ricarica configurazione server"
|
"description": "Ricarica la configurazione del server"
|
||||||
},
|
},
|
||||||
"resetConst": {
|
"resetConst": {
|
||||||
"reset_all": "Ripristina le costellazioni di tutti gli avatar.",
|
"reset_all": "Ripristina le costellazioni di tutti gli Avatar.",
|
||||||
"success": "Le costellazioni per %s sono state reimpostate. Effettua nuovamente il login per vedere le modifiche.",
|
"success": "Le costellazioni per %s sono state reimpostate. Effettua nuovamente il login per vedere le modifiche.",
|
||||||
"description": "Reimposta il livello della costellazione sul tuo personaggio attivo corrente, dovrai reloggare dopo aver usato il comando per vedere eventuali modifiche"
|
"description": "Reimposta il livello della costellazione sul tuo personaggio attivo corrente, dovrai reloggare dopo aver usato il comando per vedere eventuali modifiche"
|
||||||
},
|
},
|
||||||
@ -304,7 +304,7 @@
|
|||||||
},
|
},
|
||||||
"sendMessage": {
|
"sendMessage": {
|
||||||
"success": "Messaggio inviato.",
|
"success": "Messaggio inviato.",
|
||||||
"description": "Invia un messaggio a un giocatore come server. Se usato senza target, invia a tutti i giocatori sul server."
|
"description": "Invia un messaggio a un giocatore come server. Se usato senza bersaglio, invia a tutti i giocatori sul server."
|
||||||
},
|
},
|
||||||
"setConst": {
|
"setConst": {
|
||||||
"range_error": "Il livello della costellazione deve essere compreso tra 0 e 6.",
|
"range_error": "Il livello della costellazione deve essere compreso tra 0 e 6.",
|
||||||
@ -316,10 +316,10 @@
|
|||||||
"description": "Imposta il livello di costellazione per il tuo attuale personaggio attivo"
|
"description": "Imposta il livello di costellazione per il tuo attuale personaggio attivo"
|
||||||
},
|
},
|
||||||
"setFetterLevel": {
|
"setFetterLevel": {
|
||||||
"range_error": "Il livello di restrizione deve essere compreso tra 0 e 10.",
|
"range_error": "Il livello di amicizia deve essere compreso tra 0 e 10.",
|
||||||
"success": "Livello di restrizione impostato su %s.",
|
"success": "Livello di amicizia impostato a %s.",
|
||||||
"level_error": "Livello restrizione non valido.",
|
"level_error": "Livello di amicizia non valido.",
|
||||||
"description": "Imposta il tuo livello di restrizione per il tuo attuale personaggio attivo"
|
"description": "Imposta il tuo livello di amicizia per il tuo attuale personaggio attivo"
|
||||||
},
|
},
|
||||||
"setProp": {
|
"setProp": {
|
||||||
"description": "Imposta le proprietà dell'intero account. Cose come godmode possono essere abilitate in questo modo, oltre a cambiare cose come il pavimento dell'abisso sbloccato e il progresso del pass battaglia.\n\tValori per <prop> (senza distinzione tra maiuscole e minuscole): GodMode | UnlimitedStamina | UnlimitedEnergy | TowerLevel | WorldLevel | BPLevel | SetOpenState | UnsetOpenState | UnlockMap\n\t(cont.) vedi PlayerProperty enum per altri possibili valori, nella forma PROP_MAX_SPRING_VOLUME -> max_spring_volume"
|
"description": "Imposta le proprietà dell'intero account. Cose come godmode possono essere abilitate in questo modo, oltre a cambiare cose come il pavimento dell'abisso sbloccato e il progresso del pass battaglia.\n\tValori per <prop> (senza distinzione tra maiuscole e minuscole): GodMode | UnlimitedStamina | UnlimitedEnergy | TowerLevel | WorldLevel | BPLevel | SetOpenState | UnsetOpenState | UnlockMap\n\t(cont.) vedi PlayerProperty enum per altri possibili valori, nella forma PROP_MAX_SPRING_VOLUME -> max_spring_volume"
|
||||||
@ -354,19 +354,19 @@
|
|||||||
"team": {
|
"team": {
|
||||||
"invalid_usage": "Utilizzo non valido.",
|
"invalid_usage": "Utilizzo non valido.",
|
||||||
"invalid_index": "L'indice non è valido.",
|
"invalid_index": "L'indice non è valido.",
|
||||||
"add_too_much": "Il server ti permette di avere al massimo %s avatar nella tua squadra.",
|
"add_too_much": "Il server ti permette di avere al massimo %s personaggi nella tua squadra.",
|
||||||
"failed_to_add_avatar": "Impossibile aggiungere l'ID avatar %s.",
|
"failed_to_add_avatar": "🇺🇸Failed to add avatar ID %s.",
|
||||||
"failed_to_parse_index": "Impossibile analizzare l'indice: %s",
|
"failed_to_parse_index": "Impossibile analizzare l'indice: %s",
|
||||||
"remove_too_much": "Non puoi rimuovere tutti i tuoi avatar.",
|
"remove_too_much": "Non puoi rimuovere tutti i tuoi personaggi.",
|
||||||
"ignore_index": "Indici ignorati: %s",
|
"ignore_index": "Indici ignorati: %s",
|
||||||
"index_out_of_range": "L'indice che hai specificato non è compreso nell'intervallo.",
|
"index_out_of_range": "L'indice che hai specificato non è compreso nell'intervallo.",
|
||||||
"failed_parse_avatar_id": "Impossibile analizzare l'ID avatar: %s",
|
"failed_parse_avatar_id": "🇺🇸Failed to parse avatar ID: %s",
|
||||||
"avatar_already_in_team": "Avatar è già nel team.",
|
"avatar_already_in_team": "🇺🇸Avatar is already in team.",
|
||||||
"avatar_not_found": "Avatar %s non trovato.",
|
"avatar_not_found": "🇺🇸Avatar %s not found.",
|
||||||
"description": "Modifica manualmente la tua squadra."
|
"description": "Modifica manualmente la tua squadra."
|
||||||
},
|
},
|
||||||
"teleportAll": {
|
"teleportAll": {
|
||||||
"success": "Evoca tutti i giocatori nella tua posizione.",
|
"success": "Teletrasportati tutti i giocatori nella tua posizione.",
|
||||||
"error": "Puoi usare questo comando solo in modalità MP.",
|
"error": "Puoi usare questo comando solo in modalità MP.",
|
||||||
"description": "Teletrasporta tutti i giocatori del tuo mondo nella tua posizione"
|
"description": "Teletrasporta tutti i giocatori del tuo mondo nella tua posizione"
|
||||||
},
|
},
|
||||||
@ -377,15 +377,15 @@
|
|||||||
"description": "Cambia la posizione del giocatore"
|
"description": "Cambia la posizione del giocatore"
|
||||||
},
|
},
|
||||||
"trialAvatarActivity": {
|
"trialAvatarActivity": {
|
||||||
"description": "Manipolare le funzionalità dell'attività Avatar di prova. Ciò include la commutazione degli stati dei sotterranei e delle ricompense.",
|
"description": "Manipola le funzionalità dell'attività Trial del personaggio. Ciò include la commutazione degli stati dei dungeon e delle ricompense.",
|
||||||
"not_found": "Dati giocatore attività avatar di prova non trovati. Forse l'attività non è abilitata.",
|
"not_found": "Dati giocatore attività personaggi di prova non trovati. Forse l'attività non è abilitata.",
|
||||||
"invalid_param": "Parametro non valido.",
|
"invalid_param": "Parametro non valido.",
|
||||||
"schedule_not_found": "Programma %s non trovato.",
|
"schedule_not_found": "Programma %s non trovato.",
|
||||||
"success_schedule": "ID programma modificato in %s.",
|
"success_schedule": "ID programma modificato in %s.",
|
||||||
"success_dungeon": "Stato del dungeon dell'avatar %s attivato.",
|
"success_dungeon": "Stato del dungeon del personaggio %s attivato.",
|
||||||
"success_dungeon_all": "Modificato lo stato dei dungeon di tutti gli avatar.",
|
"success_dungeon_all": "Modificato lo stato dei dungeon di tutti i personaggi.",
|
||||||
"success_reward": "Stato della ricompensa dell'avatar %s attivato/disattivato.",
|
"success_reward": "Stato della ricompensa del personaggio %s attivato/disattivato.",
|
||||||
"success_reward_all": "Attivato/disattivato lo stato di ricompensa di tutti gli avatar."
|
"success_reward_all": "Attivato/disattivato lo stato di ricompensa di tutti i personaggi."
|
||||||
},
|
},
|
||||||
"weather": {
|
"weather": {
|
||||||
"success": "Imposta l'ID meteo su %s con il tipo di clima %s.",
|
"success": "Imposta l'ID meteo su %s con il tipo di clima %s.",
|
||||||
@ -393,7 +393,7 @@
|
|||||||
"description": "Cambia l'ID meteo e il tipo di clima. Gli ID meteo possono essere trovati in ./Resources/ExcelBinOutput/WeatherExcelConfigData.json.\nTipi di clima: soleggiato, nuvoloso, pioggia, temporale, neve, nebbia"
|
"description": "Cambia l'ID meteo e il tipo di clima. Gli ID meteo possono essere trovati in ./Resources/ExcelBinOutput/WeatherExcelConfigData.json.\nTipi di clima: soleggiato, nuvoloso, pioggia, temporale, neve, nebbia"
|
||||||
},
|
},
|
||||||
"ban": {
|
"ban": {
|
||||||
"success": "Soccesso.",
|
"success": "Successo.",
|
||||||
"failure": "Fallito, giocatore non trovato.",
|
"failure": "Fallito, giocatore non trovato.",
|
||||||
"invalid_time": "Impossibile analizzare il timestamp.",
|
"invalid_time": "Impossibile analizzare il timestamp.",
|
||||||
"description": "Banna un giocatore"
|
"description": "Banna un giocatore"
|
||||||
@ -408,7 +408,7 @@
|
|||||||
"description": "Sbanna un giocatore"
|
"description": "Sbanna un giocatore"
|
||||||
},
|
},
|
||||||
"troubleshoot": {
|
"troubleshoot": {
|
||||||
"description": "🇺🇸Generate debugging information for troubleshooting."
|
"description": "Genera informazioni di debugging per il troubleshooting."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gacha": {
|
"gacha": {
|
||||||
@ -419,7 +419,7 @@
|
|||||||
"available_three_stars": "Articoli a 3 stelle disponibili"
|
"available_three_stars": "Articoli a 3 stelle disponibili"
|
||||||
},
|
},
|
||||||
"records": {
|
"records": {
|
||||||
"title": "🇺🇸Gacha Records",
|
"title": "Cronologia Gacha",
|
||||||
"date": "Data",
|
"date": "Data",
|
||||||
"item": "oggetto"
|
"item": "oggetto"
|
||||||
}
|
}
|
||||||
@ -428,7 +428,7 @@
|
|||||||
"handbook": {
|
"handbook": {
|
||||||
"title": "Manuale GM",
|
"title": "Manuale GM",
|
||||||
"title_commands": "Comandi",
|
"title_commands": "Comandi",
|
||||||
"title_avatars": "Avatar",
|
"title_avatars": "🇺🇸Avatars",
|
||||||
"title_items": "Articoli",
|
"title_items": "Articoli",
|
||||||
"title_scenes": "Scene",
|
"title_scenes": "Scene",
|
||||||
"title_monsters": "Mostri",
|
"title_monsters": "Mostri",
|
||||||
@ -462,9 +462,9 @@
|
|||||||
"disabling_plugin": "Disabilitazione plug-in: %s",
|
"disabling_plugin": "Disabilitazione plug-in: %s",
|
||||||
"disabling_failed": "Impossibile disabilitare il plug-in: %s",
|
"disabling_failed": "Impossibile disabilitare il plug-in: %s",
|
||||||
"invalid_api": {
|
"invalid_api": {
|
||||||
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
"not_present": "Il plugin %s non ha una versione API specifica.",
|
||||||
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s.",
|
"lower": "Il plugin %s sta usando la versione API %s, mentre il server sta usando la versione API %s.",
|
||||||
"outdated": "🇺🇸Plugin %s is using an outdated API method."
|
"outdated": "Il plugin %s sta usando un metodo API obsoleto."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,9 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"loading": "Загружаем ресурсы...",
|
"loading": "Загружаем ресурсы...",
|
||||||
"finish": "Загрузка ресурсов завершена.",
|
"finish": "Загрузка ресурсов завершена.",
|
||||||
"custom": "🇺🇸Find additional resources at: 'Anime-Game-Servers/CustomGCResources'.",
|
"custom": "Ищите дополнительные ресурсы в репозитории: 'Anime-Game-Servers/CustomGCResources'.",
|
||||||
"missing_server": "🇺🇸To fully use questing, it is recommended to add the 'Server' folder.",
|
"missing_server": "Для полноценной поддержки квестов, рекомендуется добавить папку 'Server'.",
|
||||||
"missing_scenes": "🇺🇸To fully use questing, it is recommended to add the 'ScriptSceneData' folder."
|
"missing_scenes": "Для полноценной поддержки квестов, рекомендуется добавить папку 'ScriptSceneData'."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -87,7 +87,7 @@
|
|||||||
"artifactId": "Некорректный ID артефакта.",
|
"artifactId": "Некорректный ID артефакта.",
|
||||||
"avatarId": "Некорректный ID персонажа.",
|
"avatarId": "Некорректный ID персонажа.",
|
||||||
"avatarLevel": "Некорректный уровень персонажа (avatarLevel).",
|
"avatarLevel": "Некорректный уровень персонажа (avatarLevel).",
|
||||||
"cfgId": "🇺🇸Invalid cfg ID.",
|
"cfgId": "Некорректный ID конфига.",
|
||||||
"entityId": "Некорректный ID сущности.",
|
"entityId": "Некорректный ID сущности.",
|
||||||
"itemId": "Некорректный ID предмета.",
|
"itemId": "Некорректный ID предмета.",
|
||||||
"itemLevel": "Некорректный уровень предмета (itemLevel).",
|
"itemLevel": "Некорректный уровень предмета (itemLevel).",
|
||||||
@ -171,8 +171,8 @@
|
|||||||
"description": "Позволяет войти в подземелье"
|
"description": "Позволяет войти в подземелье"
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
"description": "🇺🇸Modify an existing entity's properties",
|
"description": "Изменяет свойства выбранной сущности",
|
||||||
"not_found_error": "🇺🇸Entity does not exist"
|
"not_found_error": "Сущность не найдена"
|
||||||
},
|
},
|
||||||
"give": {
|
"give": {
|
||||||
"usage_relic": "Применение: give <ID_артефакта> [ID_глав_хар-ки] [<ID доп_хар-ки>[,<раз>]]... [lv<уровень 0-20>]",
|
"usage_relic": "Применение: give <ID_артефакта> [ID_глав_хар-ки] [<ID доп_хар-ки>[,<раз>]]... [lv<уровень 0-20>]",
|
||||||
@ -239,31 +239,31 @@
|
|||||||
"not_found": "Квест не найден.",
|
"not_found": "Квест не найден.",
|
||||||
"invalid_id": "Некорректный ID квеста.",
|
"invalid_id": "Некорректный ID квеста.",
|
||||||
"description": "Добавляет (add) или завершает (finish) квесты",
|
"description": "Добавляет (add) или завершает (finish) квесты",
|
||||||
"running": "🇺🇸Quest %s is %s (%s).",
|
"running": "Квест %s %s (%s).",
|
||||||
"talking": "🇺🇸Talk %s is %s for main quest %s (%s).",
|
"talking": "Разговор %s %s для главного квеста %s (%s).",
|
||||||
"state": {
|
"state": {
|
||||||
"none": "🇺🇸unknown (none)",
|
"none": "неизвестно (none)",
|
||||||
"unstarted": "🇺🇸unfinished (not started, not completed)",
|
"unstarted": "незавершен (не начат)",
|
||||||
"unfinished": "🇺🇸unfinished (started, not completed)",
|
"unfinished": "незавершен (начат, но не закончен)",
|
||||||
"finished": "🇺🇸finished (completed)",
|
"finished": "завершен",
|
||||||
"failed": "🇺🇸finished (completed, but failed)",
|
"failed": "завершен (но провален)",
|
||||||
"exists": "🇺🇸found",
|
"exists": "найден",
|
||||||
"not_exists": "🇺🇸not found"
|
"not_exists": "не найден"
|
||||||
},
|
},
|
||||||
"enabled": "🇺🇸Questing enabled."
|
"enabled": "Квестинг включен."
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"invalid_groupid": "🇺🇸Invalid group ID.",
|
"invalid_groupid": "Некорректный ID Группы.",
|
||||||
"invalid_suiteid": "🇺🇸Invalid suite ID.",
|
"invalid_suiteid": "Некорректный ID Комплекта.",
|
||||||
"group_not_found": "🇺🇸Group not found.",
|
"group_not_found": "Группа не найдена.",
|
||||||
"description": "🇺🇸Alter group loading",
|
"description": "Меняет загрузку группы",
|
||||||
"refreshed": "🇺🇸Group %s refreshed."
|
"refreshed": "Группа %s обновлена."
|
||||||
},
|
},
|
||||||
"cutscene": {
|
"cutscene": {
|
||||||
"description": "Odtwarza przerywnik filmowy"
|
"description": "Odtwarza przerywnik filmowy"
|
||||||
},
|
},
|
||||||
"sound": {
|
"sound": {
|
||||||
"description": "🇺🇸Plays a sound"
|
"description": "Проигрывает звук"
|
||||||
},
|
},
|
||||||
"reload": {
|
"reload": {
|
||||||
"reload_start": "Перезагружаем файл конфигурации.",
|
"reload_start": "Перезагружаем файл конфигурации.",
|
||||||
@ -408,7 +408,7 @@
|
|||||||
"description": "Разблокировывает доступ к серверу (\"разбанивает\")"
|
"description": "Разблокировывает доступ к серверу (\"разбанивает\")"
|
||||||
},
|
},
|
||||||
"troubleshoot": {
|
"troubleshoot": {
|
||||||
"description": "🇺🇸Generate debugging information for troubleshooting."
|
"description": "Генерирует отладочную информацию для решения проблем."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gacha": {
|
"gacha": {
|
||||||
@ -462,9 +462,9 @@
|
|||||||
"disabling_plugin": "Отключаем Плагин: %s",
|
"disabling_plugin": "Отключаем Плагин: %s",
|
||||||
"disabling_failed": "Ошибка отключения Плагина: %s",
|
"disabling_failed": "Ошибка отключения Плагина: %s",
|
||||||
"invalid_api": {
|
"invalid_api": {
|
||||||
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
"not_present": "В Плагине %s не указана версия API.",
|
||||||
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s.",
|
"lower": "Плагин %s использует версию API %s, однако сервер работает на версии API %s.",
|
||||||
"outdated": "🇺🇸Plugin %s is using an outdated API method."
|
"outdated": "Плагин %s использует устаревший API метод."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,72 +1,72 @@
|
|||||||
{
|
{
|
||||||
"messages": {
|
"messages": {
|
||||||
"game": {
|
"game": {
|
||||||
"address_bind": "🇺🇸Game Server started at \u001b[1m\u001b[33m%s:%s\u001b[0m",
|
"address_bind": "遊戲伺服器已於 \u001b[1m\u001b[33m%s:%s\u001b[0m 啟動",
|
||||||
"port_bind": "遊戲伺服器已成功啟動。端口號:%s",
|
"port_bind": "遊戲伺服器已在連接埠 %s 上啟動",
|
||||||
"connect": "客戶端已連接至 %s",
|
"connect": "客戶端 %s 已連線",
|
||||||
"disconnect": "客戶端 %s 已斷開連接。",
|
"disconnect": "客戶端 %s 已斷開連線",
|
||||||
"game_update_error": "遊戲更新時發生了錯誤。",
|
"game_update_error": "遊戲更新時發生了錯誤。",
|
||||||
"command_error": "指令發生錯誤:"
|
"command_error": "指令發生錯誤:"
|
||||||
},
|
},
|
||||||
"dispatch": {
|
"dispatch": {
|
||||||
"address_bind": "🇺🇸[Dispatch] Dispatch server started at \u001b[1m\u001b[33m%s:%s\u001b[0m",
|
"address_bind": "[Dispatch] Dispatch 伺服器已於 \u001b[1m\u001b[33m%s:%s\u001b[0m 啟動",
|
||||||
"port_bind": "[Dispatch] 伺服器已在端口 %s 上開啟。",
|
"port_bind": "[Dispatch] Dispatch 伺服器已在連接埠 %s 上啟動",
|
||||||
"request": "[Dispatch] 客戶端 %s 請求: %s %s",
|
"request": "[Dispatch] 客戶端 %s 請求:%s %s",
|
||||||
"keystore": {
|
"keystore": {
|
||||||
"general_error": "[Dispatch] 加載keystore文件時發生錯誤!",
|
"general_error": "[Dispatch] 載入 keystore 檔案時發生錯誤!",
|
||||||
"password_error": "[Dispatch] 加載 keystore 失敗。正在嘗試使用預設 keystore 密碼...",
|
"password_error": "[Dispatch] 載入 keystore 失敗。正在嘗試使用預設 keystore 密碼...",
|
||||||
"no_keystore_error": "[Dispatch] 未找到 SSL 憑證!已後降到 HTTP 伺服器。",
|
"no_keystore_error": "[Dispatch] 未找到 SSL 憑證!已回退到 HTTP 伺服器。",
|
||||||
"default_password": "[Dispatch] 默認的 keystore 密碼加載成功。請考慮將 config.json 的憑證密碼設定成 123456。"
|
"default_password": "[Dispatch] keystore 預設密碼載入成功。請考慮將 config.json 的憑證密碼設定成 123456。"
|
||||||
},
|
},
|
||||||
"authentication": {
|
"authentication": {
|
||||||
"default_unable_to_verify": "[驗證系統] 稱為 verifyUser 方法的東西在默認身份驗證程序中不可用。"
|
"default_unable_to_verify": "[驗證系統] 稱為 verifyUser 方法的東西在默認身份驗證程序中不可用。"
|
||||||
},
|
},
|
||||||
"no_commands_error": "此指令不適用於Dispatch-only模式。",
|
"no_commands_error": "此指令不適用於僅限 Dispatch 模式。",
|
||||||
"unhandled_request_error": "[Dispatch] 潛在的未處理請求 %s 請求:%s",
|
"unhandled_request_error": "[Dispatch] 潛在的未處理請求 %s 請求:%s",
|
||||||
"account": {
|
"account": {
|
||||||
"login_attempt": "[Dispatch] 客戶端 %s 正在嘗試登入",
|
"login_attempt": "[Dispatch] 客戶端 %s 正在嘗試登入",
|
||||||
"login_success": "[Dispatch] 客戶端 %s 已登入,UID為 %s",
|
"login_success": "[Dispatch] 客戶端 %s 已登入,UID 為 %s",
|
||||||
"login_max_player_limit": "[Dispatch] 客戶端 %s 登入失敗:在線人數已滿",
|
"login_max_player_limit": "[Dispatch] 客戶端 %s 登入失敗:線上人數已滿",
|
||||||
"login_token_attempt": "[Dispatch] 客戶端 %s 正在嘗試用憑證登入",
|
"login_token_attempt": "[Dispatch] 客戶端 %s 正在嘗試用憑證登入",
|
||||||
"login_token_error": "[Dispatch] 客戶端 %s 使用憑證登入失敗",
|
"login_token_error": "[Dispatch] 客戶端 %s 使用憑證登入失敗",
|
||||||
"login_token_success": "[Dispatch] 客戶端 %s 已透過憑證登入,UID為 %s",
|
"login_token_success": "[Dispatch] 客戶端 %s 已透過憑證登入,UID 為 %s",
|
||||||
"login_password_error": "[Dispatch] 客戶端 %s 使用密碼登入失敗",
|
"login_password_error": "[Dispatch] 客戶端 %s 使用密碼登入失敗",
|
||||||
"login_password_storage_error": "[Dispatch] 客戶端 %s 使用密碼登入失敗,因為該帳號在資料庫裡面沒有設定密碼。",
|
"login_password_storage_error": "[Dispatch] 客戶端 %s 使用密碼登入失敗,因為該帳號在資料庫裡面沒有設定密碼。",
|
||||||
"combo_token_success": "[Dispatch] 客戶端 %s 交換憑證成功",
|
"combo_token_success": "[Dispatch] 客戶端 %s 交換憑證成功",
|
||||||
"combo_token_error": "[Dispatch] 客戶端 %s 交換憑證失敗",
|
"combo_token_error": "[Dispatch] 客戶端 %s 交換憑證失敗",
|
||||||
"account_login_create_success": "[Dispatch] 客戶端 %s 登入失敗: 已註冊UID為 %s 的帳號。",
|
"account_login_create_success": "[Dispatch] 客戶端 %s 登入失敗:已註冊 UID 為 %s 的帳號。",
|
||||||
"account_login_create_error": "[Dispatch] 客戶端 %s 登入失敗:帳號建立失敗。",
|
"account_login_create_error": "[Dispatch] 客戶端 %s 登入失敗:帳號建立失敗。",
|
||||||
"account_login_exist_error": "[Dispatch] 客戶端 %s 登入失敗: 帳號不存在。",
|
"account_login_exist_error": "[Dispatch] 客戶端 %s 登入失敗:帳號不存在。",
|
||||||
"account_cache_error": "遊戲帳號緩存資訊錯誤",
|
"account_cache_error": "遊戲帳號快取資訊錯誤。",
|
||||||
"session_key_error": "對話密鑰不符。",
|
"session_key_error": "工作階段金鑰錯誤。",
|
||||||
"username_error": "未找到此用戶名。",
|
"username_error": "找不到此使用者名稱。",
|
||||||
"username_create_error": "未找到用戶名,建立失敗。",
|
"username_create_error": "找不到使用者名稱,建立失敗。",
|
||||||
"password_error": "無效的密碼",
|
"password_error": "密碼無效",
|
||||||
"password_length_error": "密碼長度必須大於或等於 8。",
|
"password_length_error": "密碼長度必須大於或等於 8",
|
||||||
"password_storage_error": "此帳號沒有設定密碼,請聯繫伺服器管理員。",
|
"password_storage_error": "您的帳號沒有設定密碼,請聯繫管理員。",
|
||||||
"server_max_player_limit": "伺服器在線人數已滿"
|
"server_max_player_limit": "伺服器線上人數已滿"
|
||||||
},
|
},
|
||||||
"router_error": "[Dispatch] 無法附加到路由上。"
|
"router_error": "[Dispatch] 無法附加路由。"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"free_software": "Grasscutter 是免費開源軟體。如果你已經付錢了,那你可能被騙了。主頁:https://github.com/Grasscutters/Grasscutter",
|
"free_software": "Grasscutter 是免費開源軟體。如果你已經付錢了,那你可能被騙了。主頁:https://github.com/Grasscutters/Grasscutter",
|
||||||
"starting": "正在啟動 Grasscutter...",
|
"starting": "正在啟動 Grasscutter...",
|
||||||
"shutdown": "正在關閉...",
|
"shutdown": "正在關閉...",
|
||||||
"done": "加載完成!需要指令幫助請輸入 \"help\"",
|
"done": "載入完成!需要指令幫助請輸入 \"help\"",
|
||||||
"error": "發生了一個錯誤。",
|
"error": "發生了一個錯誤。",
|
||||||
"welcome": "歡迎使用 Grasscutter",
|
"welcome": "歡迎使用 Grasscutter!",
|
||||||
"run_mode_error": "無效的伺服器運行模式: %s。",
|
"run_mode_error": "無效的伺服器運行模式:%s。",
|
||||||
"run_mode_help": "伺服器運行模式必須為 HYBRID 或者 DISPATCH_ONLY 或者 GAME_ONLY。 Grasscutter 啟動失敗...",
|
"run_mode_help": "伺服器運行模式必須為 HYBRID 或者 DISPATCH_ONLY 或者 GAME_ONLY。Grasscutter 啟動失敗...",
|
||||||
"create_resources": "正在建立 resources 資料夾...",
|
"create_resources": "正在建立 resources 資料夾...",
|
||||||
"resources_error": "請將 BinOutput 和 ExcelBinOutput 複製到 resources 資料夾。",
|
"resources_error": "請將 BinOutput 和 ExcelBinOutput 複製到 resources 資料夾。",
|
||||||
"version": "Grasscutter版本: %s-%s",
|
"version": "Grasscutter 版本: %s-%s",
|
||||||
"game_version": "遊戲版本:%s",
|
"game_version": "遊戲版本:%s",
|
||||||
"resources": {
|
"resources": {
|
||||||
"loading": "加載資源中...",
|
"loading": "載入資源中...",
|
||||||
"finish": "資源加載完成.。",
|
"finish": "資源載入完成。",
|
||||||
"custom": "🇺🇸Find additional resources at: 'Anime-Game-Servers/CustomGCResources'.",
|
"custom": "在 'Anime-Game-Servers/CustomGCResources' 尋找額外資源。",
|
||||||
"missing_server": "🇺🇸To fully use questing, it is recommended to add the 'Server' folder.",
|
"missing_server": "若要完整使用任務功能,建議加入 'Server' 資料夾。",
|
||||||
"missing_scenes": "🇺🇸To fully use questing, it is recommended to add the 'ScriptSceneData' folder."
|
"missing_scenes": "若要完整使用任務功能,建議加入 'ScriptSceneData' 資料夾。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -83,36 +83,36 @@
|
|||||||
"set_to": "%s 已經設為 %s。",
|
"set_to": "%s 已經設為 %s。",
|
||||||
"set_for_to": "%s 的使用者 %s 更改為 %s。",
|
"set_for_to": "%s 的使用者 %s 更改為 %s。",
|
||||||
"invalid": {
|
"invalid": {
|
||||||
"amount": "無效的數量。",
|
"amount": "數量無效。",
|
||||||
"artifactId": "無效的聖遺物ID。",
|
"artifactId": "聖遺物 ID 無效。",
|
||||||
"avatarId": "無效的角色ID。",
|
"avatarId": "角色 ID 無效。",
|
||||||
"avatarLevel": "無效的角色等級。",
|
"avatarLevel": "角色等級無效。",
|
||||||
"cfgId": "🇺🇸Invalid cfg ID.",
|
"cfgId": "cfg ID 無效。",
|
||||||
"entityId": "無效的實體ID。",
|
"entityId": "實體 ID 無效。",
|
||||||
"itemId": "無效的物品ID。",
|
"itemId": "物品 ID 無效。",
|
||||||
"itemLevel": "無效的物品等級。",
|
"itemLevel": "物品等級無效。",
|
||||||
"itemRefinement": "無效的物品精煉度。",
|
"itemRefinement": "物品精煉度無效。",
|
||||||
"statValue": "無效的數據值。",
|
"statValue": "數據值無效。",
|
||||||
"value_between": "無效的屬性值:%s 必須在 %s 到 %s 之間。",
|
"value_between": "屬性值:%s 必須在 %s 到 %s 之間。",
|
||||||
"playerId": "無效的玩家ID。",
|
"playerId": "玩家 ID 無效。",
|
||||||
"uid": "無效的UID。",
|
"uid": "UID 無效。",
|
||||||
"id": "無效的ID。"
|
"id": "ID 無效。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"execution": {
|
"execution": {
|
||||||
"usage_prefix": "用法:",
|
"usage_prefix": "用法:",
|
||||||
"player_exist_error": "用戶不存在。",
|
"player_exist_error": "使用者不存在。",
|
||||||
"player_offline_error": "玩家已離線。",
|
"player_offline_error": "玩家已離線。",
|
||||||
"item_player_exist_error": "無效的物品/玩家UID。",
|
"item_player_exist_error": "無效的物品/玩家 UID。",
|
||||||
"player_exist_offline_error": "玩家不存在或已離線。",
|
"player_exist_offline_error": "玩家不存在或已離線。",
|
||||||
"argument_error": "無效的參數。",
|
"argument_error": "無效的參數。",
|
||||||
"clear_target": "目標已清除.",
|
"clear_target": "目標已清除.",
|
||||||
"set_target": "隨後的指令都會以@%s為預設。",
|
"set_target": "隨後的指令都會以 @%s 為預設。",
|
||||||
"set_target_online": "@%s 在線。 某些命令可能需要離線目標。",
|
"set_target_online": "@%s 正在線上。某些命令可能需要離線目標。",
|
||||||
"set_target_offline": "@%s 離線。 某些命令可能需要在線目標。",
|
"set_target_offline": "@%s 目前離線。某些命令可能需要線上目標。",
|
||||||
"need_target": "此指令需要一個目標 UID。添加 <@UID> 引數或者使用 /target @UID 來設定持久目標。",
|
"need_target": "此指令需要一個目標 UID。添加 <@UID> 引數或者使用 /target @UID 來設定持久目標。",
|
||||||
"need_target_online": "此命令需要在線目標 UID,但當前目標離線。 添加不同的 <@UID> 參數或使用 /target @UID 設置持久目標。",
|
"need_target_online": "此命令需要線上目標 UID,但目前目標離線。添加不同的 <@UID> 參數或使用 /target @UID 設置持久目標。",
|
||||||
"need_target_offline": "此命令需要離線目標 UID,但當前目標在線。 添加不同的 <@UID> 參數或使用 /target @UID 設置持久目標。"
|
"need_target_offline": "此命令需要離線目標 UID,但目前目標線上。添加不同的 <@UID> 參數或使用 /target @UID 設置持久目標。"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"enabled": "已啟用",
|
"enabled": "已啟用",
|
||||||
@ -121,34 +121,34 @@
|
|||||||
"success": "成功"
|
"success": "成功"
|
||||||
},
|
},
|
||||||
"account": {
|
"account": {
|
||||||
"invalid": "無效的UID。",
|
"invalid": "無效的 UID。",
|
||||||
"exists": "帳號已存在。",
|
"exists": "帳號已存在。",
|
||||||
"create": "已建立帳號,UID 為 %s 。",
|
"create": "已建立帳號,UID 為 %s。",
|
||||||
"delete": "帳號已刪除。",
|
"delete": "帳號已刪除。",
|
||||||
"no_account": "帳號不存在。",
|
"no_account": "帳號不存在。",
|
||||||
"description": "建立或刪除帳號。"
|
"description": "建立或刪除帳號。"
|
||||||
},
|
},
|
||||||
"achievement": {
|
"achievement": {
|
||||||
"success": {
|
"success": {
|
||||||
"grant": "🇺🇸Granted the achievement to %s.",
|
"grant": "已將成就授予 %s。",
|
||||||
"revoke": "🇺🇸Revoked the achievement from %s.",
|
"revoke": "已從 %s 撤回成就。",
|
||||||
"progress": "🇺🇸Set progress of %s's achievement(id: %s) to %s.",
|
"progress": "將 %s 的成就 (id: %s) 進度設為 %s。",
|
||||||
"grantall": "🇺🇸Granted %s achievement(s) to %s.",
|
"grantall": "已授予 %s 項成就給 %s。",
|
||||||
"revokeall": "🇺🇸Revoked %s achievement(s) from %s."
|
"revokeall": "已撤回 %s 項成就:%s。"
|
||||||
},
|
},
|
||||||
"fail": {
|
"fail": {
|
||||||
"achievement_not_found": "🇺🇸Achievement not found.",
|
"achievement_not_found": "找不到成就。",
|
||||||
"already_achieved": "🇺🇸%s has already achieved the achievement.",
|
"already_achieved": "%s 已經達成成就了。",
|
||||||
"not_yet_achieved": "🇺🇸%s hasn't achieved the achievement yet."
|
"not_yet_achieved": "%s 尚未達成成就。"
|
||||||
},
|
},
|
||||||
"description": "🇺🇸Grant, Revoke or Progress achievements."
|
"description": "授予、撤回,或提升成就。"
|
||||||
},
|
},
|
||||||
"announce": {
|
"announce": {
|
||||||
"send_success": "成功發送了一則公告,你可以通過 /a revoke %s 撤銷。",
|
"send_success": "成功傳送了一則公告,你可以通過 /a revoke %s 撤銷。",
|
||||||
"refresh_success": "已重新整理了%s個公告。",
|
"refresh_success": "已重新整理了 %s 個公告。",
|
||||||
"revoke_done": "嘗試撤回公告 %s。",
|
"revoke_done": "嘗試撤回公告 %s。",
|
||||||
"not_found": "找不到公告 %s。",
|
"not_found": "找不到公告 %s。",
|
||||||
"description": "發送公告給所有在線玩家,或者是更改伺服器的公告。"
|
"description": "傳送公告給所有線上玩家,或者是更改伺服器的公告。"
|
||||||
},
|
},
|
||||||
"clear": {
|
"clear": {
|
||||||
"weapons": "已將 %s 的武器清空。",
|
"weapons": "已將 %s 的武器清空。",
|
||||||
@ -158,11 +158,11 @@
|
|||||||
"displays": "已清除 %s 的顯示。",
|
"displays": "已清除 %s 的顯示。",
|
||||||
"virtuals": "已將 %s 的所有貨幣和經驗值清空。",
|
"virtuals": "已將 %s 的所有貨幣和經驗值清空。",
|
||||||
"everything": "已將 %s 的所有物品清空。",
|
"everything": "已將 %s 的所有物品清空。",
|
||||||
"description": "從你的背包中刪除所有未裝備且未上鎖的物品,包括稀有物品。"
|
"description": "從你的背包中刪除所有未裝備且未上鎖的物品,預設為 4 星且等級和精煉均為 1 以下的物品,但可以提高限制。"
|
||||||
},
|
},
|
||||||
"coop": {
|
"coop": {
|
||||||
"success": "召喚了 %s 到 %s 的世界。",
|
"success": "召喚了 %s 到 %s 的世界。",
|
||||||
"description": "強制傳送指定用戶到他人的世界。如果未指定玩家,則會將你設為多人遊戲狀態。"
|
"description": "強制傳送指定使用者到他人的世界。如果未指定玩家,則會將你設為多人遊戲狀態。"
|
||||||
},
|
},
|
||||||
"enter_dungeon": {
|
"enter_dungeon": {
|
||||||
"changed": "已進入祕境 %s",
|
"changed": "已進入祕境 %s",
|
||||||
@ -171,14 +171,14 @@
|
|||||||
"description": "進入指定祕境。"
|
"description": "進入指定祕境。"
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
"description": "🇺🇸Modify an existing entity's properties",
|
"description": "編輯現有實體的屬性",
|
||||||
"not_found_error": "🇺🇸Entity does not exist"
|
"not_found_error": "實體不存在"
|
||||||
},
|
},
|
||||||
"give": {
|
"give": {
|
||||||
"usage_relic": "用法: give <artifactID> [mainPropID] [<appendPropID>[,<times>]]... [lv<level 0-20>]",
|
"usage_relic": "用法: give <聖遺物 ID> [主詞條 ID] [<副詞條 ID>[,<次數>]]... [lv<等級 0-20>]",
|
||||||
"illegal_relic": "你不可以取得這個聖遺物,因為該聖遺物ID在黑名單列表內。",
|
"illegal_relic": "你不可以取得這個聖遺物,因為該聖遺物 ID 在黑名單列表內。",
|
||||||
"given": "已經將 %s 個 %s 給予 %s。",
|
"given": "已經將 %s 個 %s 給予 %s。",
|
||||||
"given_with_level_and_refinement": "已將 %s [等級%s, 精煉%s] %s個給予 %s",
|
"given_with_level_and_refinement": "已將 %s [等級 %s, 精煉 %s] %s 個給予 %s",
|
||||||
"given_level": "已將 %s 等級 %s %s 個給予 %s",
|
"given_level": "已將 %s 等級 %s %s 個給予 %s",
|
||||||
"given_avatar": "已將 %s 等級 %s 給予 %s。",
|
"given_avatar": "已將 %s 等級 %s 給予 %s。",
|
||||||
"giveall_success": "成功給予所有物品。",
|
"giveall_success": "成功給予所有物品。",
|
||||||
@ -186,16 +186,16 @@
|
|||||||
},
|
},
|
||||||
"heal": {
|
"heal": {
|
||||||
"success": "所有角色已被治療。",
|
"success": "所有角色已被治療。",
|
||||||
"description": "治療當前隊伍的角色。"
|
"description": "治療目前隊伍的角色。"
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"aliases": "別名:",
|
"aliases": "別名:",
|
||||||
"available_commands": "可用指令:",
|
"available_commands": "可用指令:",
|
||||||
"tip_need_permission": "需要的權限: ",
|
"tip_need_permission": "需要的權限:",
|
||||||
"tip_need_no_permission": "無",
|
"tip_need_no_permission": "無",
|
||||||
"tip_permission_targeted": "(對其他的玩家使用這個指令還需要權限%s)",
|
"tip_permission_targeted": "(對其他的玩家使用這個指令還需要權限 %s)",
|
||||||
"warn_player_has_no_permission": "注意:你沒有執行這條指令的權限",
|
"warn_player_has_no_permission": "注意:你沒有執行這條指令的權限",
|
||||||
"description": "發送幫助信息或顯示特定命令的信息"
|
"description": "傳送幫助訊息或顯示特定命令的資訊"
|
||||||
},
|
},
|
||||||
"kick": {
|
"kick": {
|
||||||
"player_kick_player": "玩家 [%s:%s] 已把 [%s:%s] 踢出",
|
"player_kick_player": "玩家 [%s:%s] 已把 [%s:%s] 踢出",
|
||||||
@ -204,7 +204,7 @@
|
|||||||
},
|
},
|
||||||
"killall": {
|
"killall": {
|
||||||
"scene_not_found_in_player_world": "未在玩家世界中找到此場景",
|
"scene_not_found_in_player_world": "未在玩家世界中找到此場景",
|
||||||
"kill_monsters_in_scene": "已殺死 %s 個怪物。 [場景ID: %s]",
|
"kill_monsters_in_scene": "已殺死 %s 個怪物。[場景ID: %s]",
|
||||||
"description": "殺死所有怪物。"
|
"description": "殺死所有怪物。"
|
||||||
},
|
},
|
||||||
"killCharacter": {
|
"killCharacter": {
|
||||||
@ -212,14 +212,14 @@
|
|||||||
"description": "殺死玩家目前使用的場上角色。"
|
"description": "殺死玩家目前使用的場上角色。"
|
||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"current_language": "當前語言是: %s",
|
"current_language": "目前語言是:%s",
|
||||||
"language_changed": "語言切換至: %s",
|
"language_changed": "語言切換至:%s",
|
||||||
"language_not_found": "目前客戶端沒有這種語言: %s",
|
"language_not_found": "目前客戶端沒有這種語言:%s",
|
||||||
"description": "顯示或切換當前語言。"
|
"description": "顯示或切換目前語言。"
|
||||||
},
|
},
|
||||||
"list": {
|
"list": {
|
||||||
"success": "目前總線上人數:%s",
|
"success": "目前總線上人數:%s",
|
||||||
"description": "查看所有在線玩家"
|
"description": "查看所有線上玩家"
|
||||||
},
|
},
|
||||||
"permission": {
|
"permission": {
|
||||||
"add": "已指派權限。",
|
"add": "已指派權限。",
|
||||||
@ -231,7 +231,7 @@
|
|||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"success": "坐標:%s, %s, %s\n旋轉:%s, %s, %s\n場景ID:%s",
|
"success": "坐標:%s, %s, %s\n旋轉:%s, %s, %s\n場景ID:%s",
|
||||||
"description": "獲取所在坐標和旋轉信息"
|
"description": "獲取所在坐標和旋轉資訊"
|
||||||
},
|
},
|
||||||
"quest": {
|
"quest": {
|
||||||
"added": "已添加任務 %s",
|
"added": "已添加任務 %s",
|
||||||
@ -239,128 +239,128 @@
|
|||||||
"not_found": "未找到任務",
|
"not_found": "未找到任務",
|
||||||
"invalid_id": "無效的任務ID",
|
"invalid_id": "無效的任務ID",
|
||||||
"description": "添加或完成任務",
|
"description": "添加或完成任務",
|
||||||
"running": "🇺🇸Quest %s is %s (%s).",
|
"running": "任務 %s 的狀態為 %s (%s)。",
|
||||||
"talking": "🇺🇸Talk %s is %s for main quest %s (%s).",
|
"talking": "對話 %s 的狀態為 %s,主任務為 %s (%s)。",
|
||||||
"state": {
|
"state": {
|
||||||
"none": "🇺🇸unknown (none)",
|
"none": "未知 (無)",
|
||||||
"unstarted": "🇺🇸unfinished (not started, not completed)",
|
"unstarted": "未完成 (未開始,未結束)",
|
||||||
"unfinished": "🇺🇸unfinished (started, not completed)",
|
"unfinished": "未完成 (已開始,未結束)",
|
||||||
"finished": "🇺🇸finished (completed)",
|
"finished": "已完成 (已結束)",
|
||||||
"failed": "🇺🇸finished (completed, but failed)",
|
"failed": "已完成 (已結束,但失敗)",
|
||||||
"exists": "🇺🇸found",
|
"exists": "存在",
|
||||||
"not_exists": "🇺🇸not found"
|
"not_exists": "找不到"
|
||||||
},
|
},
|
||||||
"enabled": "🇺🇸Questing enabled."
|
"enabled": "已啟用任務。"
|
||||||
},
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"invalid_groupid": "🇺🇸Invalid group ID.",
|
"invalid_groupid": "群組 ID 無效。",
|
||||||
"invalid_suiteid": "🇺🇸Invalid suite ID.",
|
"invalid_suiteid": "suite ID 無效。",
|
||||||
"group_not_found": "🇺🇸Group not found.",
|
"group_not_found": "找不到群組。",
|
||||||
"description": "🇺🇸Alter group loading",
|
"description": "更改群組載入",
|
||||||
"refreshed": "🇺🇸Group %s refreshed."
|
"refreshed": "已重新載入群組 %s。"
|
||||||
},
|
},
|
||||||
"cutscene": {
|
"cutscene": {
|
||||||
"description": "🇺🇸Plays a cutscene"
|
"description": "播放過場動畫"
|
||||||
},
|
},
|
||||||
"sound": {
|
"sound": {
|
||||||
"description": "🇺🇸Plays a sound"
|
"description": "播放音效"
|
||||||
},
|
},
|
||||||
"reload": {
|
"reload": {
|
||||||
"reload_start": "正在重新加載設定檔。",
|
"reload_start": "正在重新載入設定檔。",
|
||||||
"reload_done": "重新加載已完成。",
|
"reload_done": "重新載入已完成。",
|
||||||
"description": "重新加載設定檔和數據。"
|
"description": "重新載入設定檔和數據。"
|
||||||
},
|
},
|
||||||
"resetConst": {
|
"resetConst": {
|
||||||
"reset_all": "重設所有角色的命座。",
|
"reset_all": "重設所有角色的命之座。",
|
||||||
"success": "已重設 %s 的命座,重新登入後將會生效。",
|
"success": "已重設 %s 的命之座,重新登入後將會生效。",
|
||||||
"description": "重置當前角色的命之座,重新登入後將會生效。"
|
"description": "重置目前角色的命之座,重新登入後將會生效。"
|
||||||
},
|
},
|
||||||
"resetShopLimit": {
|
"resetShopLimit": {
|
||||||
"success": "重置完成。",
|
"success": "重置完成。",
|
||||||
"description": "重置所選玩家的商店刷新時間。"
|
"description": "重置所選玩家的商店刷新時間。"
|
||||||
},
|
},
|
||||||
"sendMail": {
|
"sendMail": {
|
||||||
"give_usage": "用法: give <player> <itemID|itemName> [amount] [level] [refinement]",
|
"give_usage": "用法: give <玩家> <物品 ID|物品名稱> [數量] [等級] [精煉]",
|
||||||
"user_not_exist": "ID '%s' 的使用者不存在。",
|
"user_not_exist": "ID '%s' 的使用者不存在。",
|
||||||
"start_composition": "發送郵件流程。\n請使用`/send <郵件標題>`來進到下一步。\n你可以在任何時間使用`/sendmail stop`來停止發送。",
|
"start_composition": "寄送郵件流程。\n請使用`/send <郵件標題>`來進到下一步。\n你可以在任何時間使用`/sendmail stop`來停止傳送。",
|
||||||
"templates": "郵件模板尚未實裝...",
|
"templates": "郵件模板尚未實裝...",
|
||||||
"invalid_arguments": "無效的參數。\n指令使用方法 `/sendmail <userId|all|help> [templateId]`",
|
"invalid_arguments": "無效的參數。\n指令使用方法 `/sendmail <userId|all|help> [templateId]`",
|
||||||
"send_cancel": "取消傳送信息",
|
"send_cancel": "取消傳送郵件",
|
||||||
"send_done": "已將消息發送給 %s!",
|
"send_done": "已將郵件傳送給 %s!",
|
||||||
"send_all_done": "消息已發送給全體用戶!",
|
"send_all_done": "郵件已傳送給全體使用者!",
|
||||||
"not_composition_end": "現在郵件發送未到最後階段。\n請使用 `/sendmail %s` 繼續發送郵件,或者 `/sendmail stop` 來停止發送郵件。",
|
"not_composition_end": "現在郵件傳送未到最後階段。\n請使用 `/sendmail %s` 繼續傳送郵件,或者 `/sendmail stop` 來停止傳送郵件。",
|
||||||
"please_use": "請使用 `/sendmail %s`",
|
"please_use": "請使用 `/sendmail %s`",
|
||||||
"set_title": "成功將郵件標題設定成 '%s'。\n接下來請繼續使用 '/sendmail <content>' 來設定郵件內容。",
|
"set_title": "成功將郵件標題設定成 '%s'。\n接下來請繼續使用 '/sendmail <content>' 來設定郵件內容。",
|
||||||
"set_contents": "成功將'%s'為郵件內容。\n接下來請打出 '/sendmail <寄件者名稱>' 來設定郵件寄件者名稱。",
|
"set_contents": "成功將 '%s' 為郵件內容。\n接下來請打出 '/sendmail <寄件者名稱>' 來設定郵件寄件者名稱。",
|
||||||
"set_message_sender": "郵件寄件者已設為 '%s'。\n使用 '/sendmail <itemId|itemName|finish> [amount] [level]' 以繼續操作。",
|
"set_message_sender": "郵件寄件者已設為 '%s'。\n使用 '/sendmail <itemId|itemName|finish> [數量] [等級]' 以繼續操作。",
|
||||||
"send": "已添加 %s 個 %s (等級為 %s) 到郵件附件。\n如果沒有要繼續添加道具請使用 `/sendmail finish` 來完成郵件發送。",
|
"send": "已添加 %s 個 %s (等級為 %s) 到郵件附件。\n如果沒有要繼續添加道具,請使用 `/sendmail finish` 來完成郵件傳送。",
|
||||||
"invalid_arguments_please_use": "無效的參數 \n 請改用 `/sendmail %s`",
|
"invalid_arguments_please_use": "無效的參數 \n 請改用 `/sendmail %s`",
|
||||||
"title": "<標題>",
|
"title": "<標題>",
|
||||||
"message": "<正文>",
|
"message": "<正文>",
|
||||||
"sender": "<寄件者>",
|
"sender": "<寄件者>",
|
||||||
"arguments": "<itemId|itemName|finish> [數量] [等級]",
|
"arguments": "<itemId|itemName|finish> [數量] [等級]",
|
||||||
"error": "錯誤:無效的編寫階段 %s。需要 stacktrace 請查看伺服器命令提示字元。",
|
"error": "錯誤:無效的編寫階段 %s。需要 stacktrace 請查看伺服器命令提示字元。",
|
||||||
"description": "向指定用戶發送郵件。此指令的用法可根據附加的參數而改變。"
|
"description": "向指定使用者傳送郵件。此指令的用法可根據附加的參數而改變。"
|
||||||
},
|
},
|
||||||
"sendMessage": {
|
"sendMessage": {
|
||||||
"success": "訊息已發送。",
|
"success": "訊息已傳送。",
|
||||||
"description": "向指定玩家發送訊息。"
|
"description": "向指定玩家傳送訊息。"
|
||||||
},
|
},
|
||||||
"setConst": {
|
"setConst": {
|
||||||
"range_error": "命座必須在0到6之間。",
|
"range_error": "命之座必須在 0 到 6 之間。",
|
||||||
"level_error": "無效的命座等級。",
|
"level_error": "無效的命之座等級。",
|
||||||
"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.",
|
"successall": "所有角色的命之座已設為 %s。",
|
||||||
"description": "設定當前角色的命之座。"
|
"description": "設定目前角色的命之座"
|
||||||
},
|
},
|
||||||
"setFetterLevel": {
|
"setFetterLevel": {
|
||||||
"range_error": "好感度必須在 0 到 10 之間。",
|
"range_error": "好感度必須在 0 到 10 之間。",
|
||||||
"success": "好感等級已設定為 %s",
|
"success": "好感等級已設定為 %s",
|
||||||
"level_error": "無效的好感度。",
|
"level_error": "無效的好感度。",
|
||||||
"description": "設定當前角色的好感度等級。"
|
"description": "設定目前角色的好感度等級。"
|
||||||
},
|
},
|
||||||
"setProp": {
|
"setProp": {
|
||||||
"description": "設定帳號屬性。 比如可以通過此命令啟用無敵,也可以解鎖深淵或更改紀行等級。\n\t可更改的屬性列表: godmode(無敵)|nostamina(無限體力)|unlimitedenergy(無限元素能量)|abyss(深淵螺旋)|worldlevel(世界等級)|bplevel(紀行等級)\n\t(cont.) `有關其他可能的數值,請參閱 PlayerProperty 列舉。 (範例 PROP_MAX_SPRING_VOLUME -> max_spring_volume)`"
|
"description": "設定帳號屬性。比如可以通過此命令啟用無敵,也可以解鎖深淵或更改紀行等級。\n\t可更改的屬性列表: godmode(無敵)|nostamina(無限體力)|unlimitedenergy(無限元素能量)|abyss(深淵螺旋)|worldlevel(世界等級)|bplevel(紀行等級)\n\t(cont.) `有關其他可能的數值,請參閱 PlayerProperty 列舉。 (範例 PROP_MAX_SPRING_VOLUME -> max_spring_volume)`"
|
||||||
},
|
},
|
||||||
"setStats": {
|
"setStats": {
|
||||||
"description": "設定當前角色的數據類型。\n\t可使用的數據類型:hp (生命值)| maxhp (最大生命值) | def(防禦力) | atk (攻擊力)| em (元素精通) | er (元素充能效率) | crate(暴擊率) | cdmg (暴擊傷害)| cdr (冷卻縮減) | heal(治療加成)| heali (受治療加成)| shield (護盾強效)| defi (無視防禦)\n\t(cont.) 元素增傷類:epyro (火傷) | ecryo (冰傷) | ehydro (水傷) | egeo (岩傷) | edendro (草傷) | eelectro (雷傷) | ephys (物傷)(cont.) 元素減傷類:respyro (火抗) | rescryo (冰抗) | reshydro (水抗) | resgeo (岩抗) | resdendro (草抗) | reselectro (雷抗) | resphys (物抗)",
|
"description": "設定目前角色的數據類型。\n\t可使用的數據類型:hp (生命值)| maxhp (最大生命值) | def(防禦力) | atk (攻擊力)| em (元素精通) | er (元素充能效率) | crate(暴擊率) | cdmg (暴擊傷害)| cdr (冷卻縮減) | heal(治療加成)| heali (受治療加成)| shield (護盾強效)| defi (無視防禦)\n\t(cont.) 元素增傷類:epyro (火傷) | ecryo (冰傷) | ehydro (水傷) | egeo (岩傷) | edendro (草傷) | eelectro (雷傷) | ephys (物傷)(cont.) 元素減傷類:respyro (火抗) | rescryo (冰抗) | reshydro (水抗) | resgeo (岩抗) | resdendro (草抗) | reselectro (雷抗) | resphys (物抗)",
|
||||||
"locked_to": "🇺🇸%s locked to %s.",
|
"locked_to": "%s 已鎖定為 %s.",
|
||||||
"locked_for_to": "🇺🇸%s for %s locked to %s.",
|
"locked_for_to": "%s (玩家 %s) 已鎖定為 %s。",
|
||||||
"unlocked": "🇺🇸%s unlocked.",
|
"unlocked": "%s 已解鎖。",
|
||||||
"unlocked_for": "🇺🇸%s for %s unlocked."
|
"unlocked_for": "%s (玩家 %s) 已解鎖。"
|
||||||
},
|
},
|
||||||
"spawn": {
|
"spawn": {
|
||||||
"success": "已生成 %s 個 %s。",
|
"success": "已生成 %s 個 %s。",
|
||||||
"limit_reached": "已達到場景生成上限,已改為%s個實體。",
|
"limit_reached": "已達到場景生成上限,已改為 %s 個實體。",
|
||||||
"description": "在你附近生成一個實體動物。"
|
"description": "在你附近生成一個實體。"
|
||||||
},
|
},
|
||||||
"stop": {
|
"stop": {
|
||||||
"success": "正在關閉伺服器...",
|
"success": "正在關閉伺服器...",
|
||||||
"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": "🇺🇸Set talent %s - \"%s\" to %s.",
|
"set_id": "設置天賦 %s - \"%s\" 至 %s。",
|
||||||
"id_desc": "🇺🇸Talent %s - \"%s\" - \"%s\"",
|
"id_desc": "天賦 %s - \"%s\" - \"%s\"",
|
||||||
"invalid_skill_id": "無效的技能ID。",
|
"invalid_skill_id": "無效的技能 ID。",
|
||||||
"invalid_level": "無效的天賦等級。",
|
"invalid_level": "無效的天賦等級。",
|
||||||
"normal_attack_id": "普通攻擊的 ID 為 %s。",
|
"normal_attack_id": "普通攻擊的 ID 為 %s。",
|
||||||
"e_skill_id": "元素戰技技能ID %s。",
|
"e_skill_id": "元素戰技技能 ID 為 %s。",
|
||||||
"q_skill_id": "元素爆發技能ID %s。",
|
"q_skill_id": "元素爆發技能 ID 為 %s。",
|
||||||
"description": "設定當前角色的天賦等級"
|
"description": "設定目前角色的天賦等級"
|
||||||
},
|
},
|
||||||
"team": {
|
"team": {
|
||||||
"invalid_usage": "無效的用法。",
|
"invalid_usage": "無效的用法。",
|
||||||
"invalid_index": "無效索引。",
|
"invalid_index": "無效索引。",
|
||||||
"add_too_much": "服務端只允許您的隊伍裡最多 %s 名角色。",
|
"add_too_much": "服務端只允許您的隊伍裡最多 %s 名角色。",
|
||||||
"failed_to_add_avatar": "無法根據ID %s 添加角色。",
|
"failed_to_add_avatar": "無法根據 ID %s 添加角色。",
|
||||||
"failed_to_parse_index": "無法解析的索引:%s",
|
"failed_to_parse_index": "無法解析的索引:%s",
|
||||||
"remove_too_much": "您不能删除那麼多的角色,因為您的隊伍列表角色會全部被刪除。",
|
"remove_too_much": "您不能删除那麼多的角色,因為您的隊伍列表角色會全部被刪除。",
|
||||||
"ignore_index": "無視的索引列表:%s",
|
"ignore_index": "無視的索引列表:%s",
|
||||||
"index_out_of_range": "您指定的索引超出了範圍。",
|
"index_out_of_range": "您指定的索引超出了範圍。",
|
||||||
"failed_parse_avatar_id": "無法解析的角色ID:%s",
|
"failed_parse_avatar_id": "無法解析的角色 ID:%s",
|
||||||
"avatar_already_in_team": "該角色已經在您的隊伍當中了。",
|
"avatar_already_in_team": "該角色已經在您的隊伍當中了。",
|
||||||
"avatar_not_found": "無法找到該角色:%s",
|
"avatar_not_found": "無法找到該角色:%s",
|
||||||
"description": "手動修改您的隊伍配置。"
|
"description": "手動修改您的隊伍配置。"
|
||||||
@ -373,24 +373,24 @@
|
|||||||
"teleport": {
|
"teleport": {
|
||||||
"invalid_position": "無效的座標。",
|
"invalid_position": "無效的座標。",
|
||||||
"exists_error": "此場景不存在。",
|
"exists_error": "此場景不存在。",
|
||||||
"success": "傳送 %s 到座標 %s,%s,%s ,場景為 %s 。",
|
"success": "傳送 %s 到座標 %s,%s,%s,場景為 %s。",
|
||||||
"description": "將玩家的位置傳送到你所指定的座標。"
|
"description": "將玩家的位置傳送到你所指定的座標。"
|
||||||
},
|
},
|
||||||
"trialAvatarActivity": {
|
"trialAvatarActivity": {
|
||||||
"description": "操縱試用角色活動的功能。這包括切換地牢和獎勵的狀態。",
|
"description": "操縱試用角色活動的功能。這包括切換秘境和獎勵的狀態。",
|
||||||
"not_found": "未找到試用角色活動玩家數據。也許該活動未被啟用。",
|
"not_found": "未找到試用角色活動玩家數據。也許該活動未被啟用。",
|
||||||
"invalid_param": "無效的參數。",
|
"invalid_param": "無效的參數。",
|
||||||
"schedule_not_found": "未找到計劃 %s。",
|
"schedule_not_found": "未找到計劃 %s。",
|
||||||
"success_schedule": "已將計劃 ID 更改為 %s。",
|
"success_schedule": "已將計劃 ID 更改為 %s。",
|
||||||
"success_dungeon": "已切換角色 %s 的地牢狀態。",
|
"success_dungeon": "已切換角色 %s 的秘境狀態。",
|
||||||
"success_dungeon_all": "已切換所有角色的地牢狀態。",
|
"success_dungeon_all": "已切換所有角色的秘境狀態。",
|
||||||
"success_reward": "已切換角色 %s 的獎勵狀態。",
|
"success_reward": "已切換角色 %s 的獎勵狀態。",
|
||||||
"success_reward_all": "已切換所有角色的獎勵狀態。"
|
"success_reward_all": "已切換所有角色的獎勵狀態。"
|
||||||
},
|
},
|
||||||
"weather": {
|
"weather": {
|
||||||
"success": "已設定天氣ID 為 %s,氣候型別為 %s。",
|
"success": "已設定天氣 ID 為 %s,氣候型別為 %s。",
|
||||||
"status": "當前天氣ID 為 %s,氣候型別為 %s。",
|
"status": "目前天氣 ID 為 %s,氣候型別為 %s。",
|
||||||
"description": "更改天氣ID和氣候型別。天氣ID可以在 ./Resources/ExcelBinOutput/WeatherExcelConfigData.json 中找到。\n氣候型別:sunny(晴天), cloudy(多雲), rain(雨), thunderstorm(雷雨), snow(雪), mist(霧)"
|
"description": "更改天氣 ID 和氣候型別。天氣 ID 可以在 ./Resources/ExcelBinOutput/WeatherExcelConfigData.json 中找到。\n氣候型別:sunny(晴天), cloudy(多雲), rain(雨), thunderstorm(雷雨), snow(雪), mist(霧)"
|
||||||
},
|
},
|
||||||
"ban": {
|
"ban": {
|
||||||
"success": "停權成功。",
|
"success": "停權成功。",
|
||||||
@ -399,8 +399,8 @@
|
|||||||
"description": "停權指定玩家。"
|
"description": "停權指定玩家。"
|
||||||
},
|
},
|
||||||
"unlockall": {
|
"unlockall": {
|
||||||
"success": "🇺🇸Unlocked all open states for %s.",
|
"success": "已為 %s 解鎖所有開放狀態。",
|
||||||
"description": "🇺🇸Unlocks all open states for a player."
|
"description": "為指定玩家解鎖所有開放狀態。"
|
||||||
},
|
},
|
||||||
"unban": {
|
"unban": {
|
||||||
"success": "撤銷停權成功。",
|
"success": "撤銷停權成功。",
|
||||||
@ -408,15 +408,15 @@
|
|||||||
"description": "撤銷停權指定玩家。"
|
"description": "撤銷停權指定玩家。"
|
||||||
},
|
},
|
||||||
"troubleshoot": {
|
"troubleshoot": {
|
||||||
"description": "🇺🇸Generate debugging information for troubleshooting."
|
"description": "產生疑難排解用的除錯資訊。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gacha": {
|
"gacha": {
|
||||||
"details": {
|
"details": {
|
||||||
"title": "祈願詳情",
|
"title": "祈願詳情",
|
||||||
"available_five_stars": "可獲得的5星物品",
|
"available_five_stars": "可獲得的 5 星物品",
|
||||||
"available_four_stars": "可獲得的4星物品",
|
"available_four_stars": "可獲得的 4 星物品",
|
||||||
"available_three_stars": "可獲得的3星物品"
|
"available_three_stars": "可獲得的 3 星物品"
|
||||||
},
|
},
|
||||||
"records": {
|
"records": {
|
||||||
"title": "祈願記錄",
|
"title": "祈願記錄",
|
||||||
@ -426,7 +426,7 @@
|
|||||||
},
|
},
|
||||||
"documentation": {
|
"documentation": {
|
||||||
"handbook": {
|
"handbook": {
|
||||||
"title": "🇺🇸GM Handbook",
|
"title": "GM 手冊",
|
||||||
"title_commands": "指令",
|
"title_commands": "指令",
|
||||||
"title_avatars": "角色",
|
"title_avatars": "角色",
|
||||||
"title_items": "道具",
|
"title_items": "道具",
|
||||||
@ -442,29 +442,29 @@
|
|||||||
},
|
},
|
||||||
"index": {
|
"index": {
|
||||||
"title": "文件",
|
"title": "文件",
|
||||||
"handbook": "🇺🇸GM Handbook",
|
"handbook": "GM 手冊",
|
||||||
"gacha_mapping": "祈願物品映射到JSON上"
|
"gacha_mapping": "祈願物品映射到 JSON 上"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"plugin": {
|
"plugin": {
|
||||||
"directory_failed": "🇺🇸Failed to create plugins directory: ",
|
"directory_failed": "無法建立外掛程式路徑:",
|
||||||
"unable_to_load": "🇺🇸Unable to load plugin.",
|
"unable_to_load": "無法載入外掛程式。",
|
||||||
"invalid_config": "🇺🇸Plugin %s has an invalid config file.",
|
"invalid_config": "外掛程式 %s 的設定檔無效。",
|
||||||
"invalid_main_class": "🇺🇸Plugin %s has an invalid main class.",
|
"invalid_main_class": "外掛程式 %s 的主類別無效。",
|
||||||
"missing_config": "🇺🇸Plugin %s lacks a valid config file.",
|
"missing_config": "外掛程式 %s 缺少有效的設定檔。",
|
||||||
"failed_to_load_plugin": "🇺🇸Failed to load plugin: %s",
|
"failed_to_load_plugin": "無法載入外掛程式:%s",
|
||||||
"failed_to_load": "🇺🇸Failed to load a plugin.",
|
"failed_to_load": "無法載入外掛程式。",
|
||||||
"failed_to_load_dependencies": "🇺🇸Failed to load plugins with dependencies.",
|
"failed_to_load_dependencies": "無法載入外掛程式的相依項目。",
|
||||||
"loading_plugin": "🇺🇸Loading plugin: %s",
|
"loading_plugin": "正在載入外掛程式:%s",
|
||||||
"failed_add_id": "🇺🇸Failed to add plugin identifier: %s",
|
"failed_add_id": "無法新增外掛程式識別碼:%s",
|
||||||
"enabling_plugin": "🇺🇸Enabling plugin: %s",
|
"enabling_plugin": "正在啟用外掛程式:%s",
|
||||||
"enabling_failed": "🇺🇸Failed to enable plugin: %s",
|
"enabling_failed": "無法啟用外掛程式:%s",
|
||||||
"disabling_plugin": "🇺🇸Disabling plugin: %s",
|
"disabling_plugin": "正在停用外掛程式:%s",
|
||||||
"disabling_failed": "🇺🇸Failed to disable plugin: %s",
|
"disabling_failed": "無法停用外掛程式:%s",
|
||||||
"invalid_api": {
|
"invalid_api": {
|
||||||
"not_present": "🇺🇸Plugin %s does not specify an API version.",
|
"not_present": "外掛程式 %s 並未指定 API 版本。",
|
||||||
"lower": "🇺🇸Plugin %s is using API version %s, while the server is using API version %s.",
|
"lower": "外掛程式 %s 使用的 API 版本為 %s,而伺服器使用的 API 版本為 %s。",
|
||||||
"outdated": "🇺🇸Plugin %s is using an outdated API method."
|
"outdated": "外掛程式 %s 使用了舊版的 API 方法。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user