Compare commits

...

102 Commits
v0.9.1 ... main

Author SHA1 Message Date
Magix
7368963399
Update README.md 2022-07-04 12:48:18 -04:00
SpikeHD
b2873efcc5
Update README.md 2022-06-02 17:19:56 -07:00
SpikeHD
5e782857b8 Merge branch 'main' of https://github.com/Grasscutters/GrassClipper into main 2022-05-19 00:09:22 -07:00
SpikeHD
224a8b9041 fix missing grasscutter file dialog lang option 2022-05-19 00:09:16 -07:00
SpikeHD
957440ec38
Update README.md 2022-05-16 08:59:00 -07:00
SpikeHD
b0638e7b76 Merge branch 'main' of https://github.com/Grasscutters/GrassClipper into main 2022-05-14 15:12:13 -07:00
SpikeHD
f09eb6ceb1
Update setup_win.cmd 2022-05-14 12:26:51 -07:00
SpikeHD
89dd29a528
Update README.md 2022-05-14 02:46:44 -07:00
SpikeHD
45015ae509
Merge pull request #74 from tsukiroku/main
Added Korean translation.
2022-05-14 02:46:17 -07:00
SpikeHD
2484d0bc6b
Merge pull request #77 from omg-xtao/omg-xtao-patch-1
loginByThirdparty
2022-05-14 02:45:56 -07:00
omg-xtao
c2383577d1
loginByThirdparty 2022-05-14 01:24:32 +08:00
tsukiroku
66b6330c73
Create ko.json
ko-KR
2022-05-14 00:10:23 +09:00
SpikeHD
e6854d454f
Merge pull request #73 from xwwwb/main
replace axios link to local source, some Some countries cannot access unpkg.com
2022-05-12 08:59:59 -07:00
雨奇晴好
9897b3fe49
Update index.html 2022-05-12 22:49:09 +08:00
雨奇晴好
2cc581aff4
use local sourse 2022-05-12 22:48:38 +08:00
SpikeHD
ae0578b8f5
Update README.md 2022-05-11 09:11:35 -07:00
SpikeHD
06d95b3165
Merge pull request #71 from ongsalt/main
Added Thai translation
2022-05-11 09:11:20 -07:00
Oachi
17254dcc5b added Thai translation 2022-05-11 17:05:00 +07:00
SpikeHD
3dce59e869
Update README.md 2022-05-10 22:26:10 -07:00
SpikeHD
797f760094 version bump 2022-05-09 20:22:11 -07:00
SpikeHD
f4f98d1847 fix java version 2022-05-08 12:39:14 -07:00
SpikeHD
ed59684ac9 fix foreign chars 2022-05-08 12:37:08 -07:00
SpikeHD
c72e00f784 version bump 2022-05-07 22:51:40 -07:00
SpikeHD
f2cdab068a Fix resource getting 2022-05-07 22:51:17 -07:00
SpikeHD
60569bf0b1 version bump 2022-05-07 21:55:17 -07:00
SpikeHD
98762a310e get process output during data file install 2022-05-07 21:54:50 -07:00
SpikeHD
2ded1f69ae disable data downloader when gc folder not set 2022-05-07 21:51:49 -07:00
SpikeHD
fecd82fe75 temp foreign char regex 2022-05-07 20:56:44 -07:00
SpikeHD
b9a77ab8f1 allow debugging 2022-05-07 20:49:45 -07:00
SpikeHD
376171b2cf data file options and translations 2022-05-07 20:13:54 -07:00
SpikeHD
5f81ced09f do button stuff 2022-05-07 20:08:55 -07:00
SpikeHD
4a32d1fb41 seperate data files 2022-05-07 20:05:01 -07:00
SpikeHD
71235a59c3 hardcoded language defaults 2022-05-07 19:58:17 -07:00
SpikeHD
a73c3ed5cd foreign char alert 2022-05-07 19:56:02 -07:00
SpikeHD
8951974633 fallback build URL 2022-05-07 19:44:07 -07:00
SpikeHD
7094277199 version bump 2022-05-07 17:32:57 -07:00
SpikeHD
9a09182973 Merge branch 'main' of https://github.com/Grasscutters/GrassClipper into main 2022-05-07 17:32:52 -07:00
SpikeHD
67dc692270 update java version scripts 2022-05-07 17:32:30 -07:00
SpikeHD
055abef5ce add resource download properly 2022-05-07 17:15:54 -07:00
SpikeHD
37d1761813
Merge pull request #63 from nautilust/main
Update language options in README file and add Indonesian README translation
2022-05-07 13:34:39 -07:00
Nautilus
b03de8a055 Add README_id.md 2022-05-07 18:01:30 +07:00
SpikeHD
a9a7cc2e45
Update README.md 2022-05-07 03:29:20 -07:00
SpikeHD
6ccbaa1f24
Merge pull request #62 from actuallyeunha/main
Update pt-br.json
2022-05-07 03:28:55 -07:00
Nautilus
24bc47a72c Update README 2022-05-07 15:25:30 +07:00
Ana Eunha
98657a8270 Update pt-br.json
Updates pt-br to include text from newer versions.
2022-05-06 22:40:23 -03:00
Ana Eunha
5e80d59ed7 Merge branch 'main' of https://github.com/actuallyeunha/GrassClipper 2022-05-06 22:39:26 -03:00
SpikeHD
b6adec4079
Update README.md 2022-05-06 17:29:49 -07:00
SpikeHD
f3534a3fff
Merge pull request #61 from lunaticwhat/main
fixed vn-vi language grammars and added new strings
2022-05-06 17:29:24 -07:00
SpikeHD
4c2e303c6e
Merge pull request #60 from zakhil-dev/main
Added Polish README
2022-05-06 17:29:08 -07:00
SpikeHD
4971d7a4b0
Merge pull request #59 from zakhil-dev/patch-1
Update polish translation
2022-05-06 17:28:42 -07:00
SpikeHD
d8b753f6e8 Merge branch 'main' of https://github.com/Grasscutters/GrassClipper into main 2022-05-06 17:28:27 -07:00
SpikeHD
34ad43cdcb fix launching grasscutter jar 2022-05-06 17:28:22 -07:00
lunaticwhat
a4cf3ee7d4 fixed vn-vi language grammar and added new strings 2022-05-07 06:20:47 +07:00
Piotr Blecharski
1dba3f682c Added Polish README 2022-05-07 00:33:33 +02:00
Zakhil
8c8bd4476c
Update polish translation
Found another string wich I forgot about
2022-05-06 23:41:47 +02:00
SpikeHD
b4760fae9a
Merge pull request #58 from nautilust/main
Update Indonesian Translation
2022-05-06 14:27:53 -07:00
Nautilus
35d2d4de77 small fix and update translations 2022-05-07 03:17:57 +07:00
SpikeHD
90fd5e6204
Update README.md 2022-05-06 12:25:46 -07:00
SpikeHD
5d8f8fe09d
Update README.md 2022-05-06 10:46:18 -07:00
SpikeHD
af225781e3
Merge pull request #57 from zakhil-dev/main
Added Polish translation
2022-05-06 10:45:46 -07:00
Piotr Blecharski
73b1a93039 Merge branch 'main' of github.com:zakhil-dev/GrassClipper 2022-05-06 19:37:12 +02:00
Piotr Blecharski
acb7d9ef91 Forgor to translate one string 2022-05-06 19:37:08 +02:00
Zakhil
19fcfa446c
Merge branch 'Grasscutters:main' into main 2022-05-06 19:33:50 +02:00
Piotr Blecharski
61ebbaf72e Added Polish translation 2022-05-06 19:33:23 +02:00
SpikeHD
5843f0d589
Update README.md 2022-05-06 10:21:28 -07:00
SpikeHD
412be98a05
Merge pull request #56 from Kimi898246/patch-3
Traditional Chinese | Translation Patch
2022-05-06 10:04:28 -07:00
Kimi
72a9d77dd5
Traditional Chinese 2022-05-06 22:42:01 +08:00
SpikeHD
a5303e7192 more slash fixes 2022-05-05 21:56:08 -07:00
SpikeHD
f4b506435d slash consistency 2022-05-05 21:52:20 -07:00
SpikeHD
06fd68e72b kill grasscutter installer if opened in admin 2022-05-05 20:43:39 -07:00
SpikeHD
dc7c766499 fix killswitch a lil 2022-05-05 20:37:43 -07:00
SpikeHD
a69e36d7bb misc fixes 2022-05-05 20:31:13 -07:00
SpikeHD
7c405a31fd translations for dialogs 2022-05-05 20:25:39 -07:00
SpikeHD
00d8d57e66 start proxy connection in background 2022-05-05 20:11:41 -07:00
SpikeHD
5ff0654413 version bump 2022-05-05 18:19:19 -07:00
SpikeHD
b33551d9b2 dialog system and gc launcher dialog 2022-05-05 18:16:15 -07:00
SpikeHD
5cf37bd8d2 Merge branch 'main' of https://github.com/Grasscutters/GrassClipper into main 2022-05-05 18:16:01 -07:00
SpikeHD
351d6daa34 fix opening folders again 2022-05-05 17:29:23 -07:00
SpikeHD
af7d241c63
Update README.md 2022-05-05 11:20:44 -07:00
SpikeHD
f268a37dc7
Merge pull request #55 from Arikatsu/Arikatsu-patch-1
Added Hindi (Indian) translation for Grassclipper
2022-05-05 11:20:24 -07:00
Scald
06f4efef8e
Added Hindi (Indian) translation for Grassclipper 2022-05-05 22:55:03 +05:30
SpikeHD
ba1ef063f9
Rename ja.json to jp.json 2022-05-05 09:07:23 -07:00
SpikeHD
35608adf68
Update README.md 2022-05-05 09:06:45 -07:00
SpikeHD
7c3e1b87ec
Merge pull request #54 from Scirese/patch-2
Update zh.json
2022-05-05 09:06:02 -07:00
SpikeHD
bbb20e0704
Merge pull request #52 from conochy/main
Add Japanese (日本語) Translation
2022-05-05 09:05:01 -07:00
conochy
36aa7b73e3 Add Japanese (日本語) Translation 2022-05-06 02:51:45 +09:00
Scirese
d562957f23
Update zh.json 2022-05-05 22:06:45 +08:00
SpikeHD
ccbad14029
Update README.md 2022-05-04 23:29:47 -07:00
SpikeHD
e8fe7e316f Merge branch 'main' of https://github.com/Grasscutters/GrassClipper into main 2022-05-04 21:42:13 -07:00
SpikeHD
25d3792930 placeholder version 0.0.0 2022-05-04 21:42:07 -07:00
SpikeHD
d7509bd205
Update README.md 2022-05-04 18:41:33 -07:00
SpikeHD
89c9d310ef fix zh-tw formatting 2022-05-03 22:04:23 -07:00
SpikeHD
55ccb6dc69
Merge pull request #49 from Kimi898246/patch-3
Traditional Chinese | New Translations
2022-05-03 22:00:59 -07:00
Kimi
92b2d1be9a
Traditional Chinese | New Translations
Updated since "chineseCharacterAlert" was added.
2022-05-04 12:56:45 +08:00
SpikeHD
de54cc60a1 version bump 2022-05-03 21:14:43 -07:00
SpikeHD
e0d3ed4948 Merge branch 'main' of https://github.com/Grasscutters/GrassClipper into main 2022-05-03 21:14:09 -07:00
SpikeHD
a55db33f42 display chinese character alert 2022-05-03 21:14:02 -07:00
SpikeHD
73a3d173e8 small alert styling change 2022-05-03 21:08:12 -07:00
SpikeHD
6c0d8c2a19 alert system 2022-05-03 21:06:01 -07:00
SpikeHD
223790b0bd potentially fix opening game/gc folders 2022-05-03 20:34:53 -07:00
SpikeHD
5cc2091764
Update zh.json 2022-05-03 01:33:56 -07:00
Ana Eunha
55e3a8f6f2 Add "Portugues Brasileiro" support 2022-04-23 03:33:09 -03:00
41 changed files with 3034 additions and 164 deletions

View File

@ -12,6 +12,7 @@
"no-undef": 0,
"no-unused-vars": 0,
"no-case-declarations": 0,
"no-control-regex": 0,
"indent": [
"error",

View File

@ -1,7 +1,15 @@
# GrassClipper
Grasscutter launcher for easily switching between Official and Private servers
# Please for the love of god do not install GrassClipper into a path in OneDrive
[Download Here!](https://github.com/Grasscutters/GrassClipper/releases/)
# ! NOTICE !
The previously mentioned **new launcher**: [Cultivation](https://github.com/Grasscutters/Cultivation) has been "released"!\
If you are experiencing problems with GrassClipper, we encourage you to try and checkout the new launcher.
# GrassClipper
EN | [PL](README_PL.md) | [ID](README_id.md)
Experimental Grasscutter launcher for easily switching between Official and Private servers
[Download Here!](https://github.com/Grasscutters/GrassClipper/releases/) (Supports Windows 8+)
*\*Note: some translations are outdated, so if random English text appears or an option seems misleading, this is why. If you notice an issue like this, feel free to make a pull request!*
@ -11,6 +19,7 @@ Grasscutter launcher for easily switching between Official and Private servers
* [Setup (for development)](#setup-for-development)
* [TODO](#todo)
* [Common Problems](#having-problems)
* [Proxy Installation not Opening/Failing](#manual-proxy-installation)
* [White Screen Fix](#white-screen-fix)
* [Error 502](#error-502)
* [Error 4206](#error-4206)
@ -45,10 +54,10 @@ Grasscutter launcher for easily switching between Official and Private servers
* [x] Fun fancy CSS styling n stuff (CoD: MW 2019-style vertical menu for choosing between official and private servers? [See this](https://charlieintel.com/wp-content/uploads/2020/11/MW-new-menu.png))
* [x] Kill switch script (optional)
* [x] Automatically run `install.cmd` when opening for the first time
* [ ] Grasscutter auto-downloader
* [x] Grasscutter auto-downloader
* [ ] Detect when in a folder that is inaccessible to the program (eg. `C:/Program Files`) and warn
* [ ] Custom images for private server sections (anyone is welcome to submit a pull request to add some!)
* [ ] Optional username/password creation for servers before entering (not implemented in Grasscutter yet)
* [x] Optional username/password creation for servers before entering (not implemented in Grasscutter yet)
* [ ] Platform detection and bash scripts
* [ ] Integrated banner creator
* Proxy service
@ -60,6 +69,15 @@ Grasscutter launcher for easily switching between Official and Private servers
Below are some scenarios you may encounter and their solutions.
# Manual Proxy Installation
If you having trouble installing the proxy server, you can also install it manually. To do so:
1. Create a folder if it does not exist named `ext` in the GrassClipper folder.
2. Download and extract the contents of [this file](https://snapshots.mitmproxy.org/7.0.4/mitmproxy-7.0.4-windows.zip) into the `ext` folder
3. Double click `mitmdump.exe` and allow it to run for a few seconds to generate the certificate
4. Run this command as Administrator: `certutil -addstore root "%USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer"`
5. Use GrassClipper like normal!
## White Screen Fix
Encountering a white screen? [Ensure WebView2 is installed](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download)
@ -69,6 +87,8 @@ You may also want to run this command as administrator:
If you have Chinese characters in your file path, this may crash it too! I am working on a fix.
You can also try running in Windows 8 compatitbility mode.
If all else fails, you can run GrassClipper in `chrome` or `browser` mode. To do so:
* Create a shortcut to `GrassClipper.exe`
* Right click the shortcut, click `properties`
@ -80,6 +100,8 @@ If all else fails, you can run GrassClipper in `chrome` or `browser` mode. To do
## Error 502
***You may be using the wrong port, ensure your port in GrassClipper is either 443 or nothing (not 0, but literally nothing)***
1. If you are running a local server, ensure the local server is running. Otherwise, ensure the server you are connecting to is actually running.
2. If you are able, [use the development branch of Grasscutter](https://github.com/Grasscutters/Grasscutter/tree/development). It is known to work better with GrassClipper.
@ -113,14 +135,19 @@ Thank you to everyone who has provided translations! <3
* ZH - nuoxianCN, Scirese & MrAru
* ZH-TW - Kimi & KormiMeiko
* PT-BR - na.na
* VIE - labalityowo
* PT-BR - na.na & actuallyeunha
* VIE - labalityowo & lunaticwhat
* ID - Iqrar99 & nautilust
* FR - linsorak & memetrollsXD
* ES - memetrollsXD
* ND - memetrollsXD
* RU - fitiskin
* TR - lilmayofuksu
* JP - conochy
* HD - Arikatsu
* PL - zakhil-dev
* TH - ongsalt
* KO - tsukiroku
# Screenshots

152
README_PL.md Normal file
View File

@ -0,0 +1,152 @@
# GrassClipper
[EN](README.md) | PL | [ID](README_id.md)
Experymentalny launcher Grasscutter'a stworzony dla łatwego przełączania się pomiędzy serwerami oficjalnymi, a prywatnymi
[Pobierz tutaj!](https://github.com/Grasscutters/GrassClipper/releases/) (Wspiera Windows'a 8+)
*\*Uwaga: niektóre tłumaczenia są nie aktualne, więc jeżeli widzisz tekst po angielsku, lub jakiś tekst wprowadza w błąd, to to jest powodem. W przypadku zauważenia takiego błędu, śmiało otwórz pull request'a!*
# Spis treści
* [Instalacja (dla użytkownika)](#instalacja-dla-użytkownika)
* [Instalacja (dla developera)](#instalacja-dla-developera)
* [Do zrobienia](#do-zrobienia)
* [Częste problmy](#napotkałeś-problem?)
* [Instalacja proxy nie uruchamia się / nie powodzi się](#ręczna-instalacja-proxy)
* [Naprawa białego ekranu](#naprawa-białego-ekranu)
* [Błąd 502](#błąd-502)
* [Błąd 4206](#błąd-4206)
* [Nieskończone okna CMD](#nieskończone-okna-CMD)
* [Niedziałający Discord/Youtube](#discord-nie-pozwala-wysyłać-mi-wiadomości-lub-wczytywać-obrazków/YouTube-dziwnie-się-zachowuje)
* [Brak internetu](#nie-mam-dostępu-do-internetu-po-zamknięciu-wszystkiego/restarcie-komputera!)
* [Dostępne tłumaczenia oraz ich autorzy](#dostępne-tłumaczenia-oraz-ich-autorzy)
* [Zrzuty ekranu](#zrzuty-ekranu)
# Instalacja (dla użytkownika)
1. Pobierz plik zip
2. Wypakuj gdzieś plik zip
3. Uruchom `GrassClipper.exe`, zainstaluj serwer proxy oraz ustaw folder z grą!
# Instalacja (dla developera)
0. Sklonuj repozytorium
1. Upewnij się, że masz zainstalowanego [NodeJS'a](https://nodejs.org/en/download/).
2. Zainstaluj narzędzie `neu` CLI: `npm install -g @neutralinojs/neu`
3. Zainstaluj zależności: `setup_win.cmd`
4. Skompiluj i uruchom:
* Testowanie: `npm run dev`
* Produkcja: `npm run build`
# Do zrobienia
* Interfejst/wewnętrzne
* [x] UI
* [x] Opcje Oficjalny i Prywatny
* [x] Wprowadzanie IP serwera
* [x] Stylowanie CSS - Pionowe menu do wybierania pomiędzy oficjalnym, a prywatnym serwerem? (Stylizowane na CoD: MW 2019) [Zobacz tutaj](https://charlieintel.com/wp-content/uploads/2020/11/MW-new-menu.png))
* [x] Skrypt Kill Switch (opcjonalne)
* [x] Automatyczne uruchamianie `install.cmd`, jeżeli uruchamamy program po raz pierwszy
* [x] Auto-pobieranie Grasscutter'a
* [ ] Wykrywanie gdy program jest uruchomiony w folderze, do którego nie ma dostępu (np. `C:/Program Files`) i wysyłanie ostrzeżenia.
* [ ] Nowe obrazki dla sekcji serwera prywatnego (Pull request'y od wszystkich są mile widziane!)
* [x] Opcjonalne tworzenie loginu/hasła dla serwera przed połączeniem (nie zaimplementowane jeszcze w Grasscutter)
* [ ] Wykrywanie systemu i skrypty bash
* [ ] Zintegrowany kreator bannerów
* Usługa proxy
* [x] Lokalny serwer proxy
* [x] Przechwytywanie i modyfikowanie zapytań GI, np. przy użyciu Fiddler'a, przepuszczanie wszystkigo innego.
* [ ] Naprawienie problemów z Discordem i YouTube'm gdy proxy jest włączone (może naprawione)
# Napotkałeś problem?
Poniżej znajdują się najczęściej pojawiające się problemy oraz ich rozwiązania.
## Ręczna instalacja proxy
Jeżeli napotkałeś problemy z automatyczną instalacją proxy, możesz zainstalować je ręcznie. <br>
W tym celu:
1. Jeżeli nie istnieje stwórz folder `ext` w folderze GrassClipper'a.
2. Pobierz i wypakuj zawartość [tego pliku](https://snapshots.mitmproxy.org/7.0.4/mitmproxy-7.0.4-windows.zip) do folderu `ext`
3. Uruchom `mitmdump.exe` i poczekaj kilka chwil, żeby wygenerował certyfikat.
4. Wywołaj to polecenie jako Administrator: `certutil -addstore root "%USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer"`
5. GrassClipper powinien działać poprawnie!
## Naprawa białego ekranu
Napotkałeś biały ekran? Upewnij się czy [WebView2](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download) jest zainstalowany.
Wywołanie tego polecenia jako Administrator również może pomóc:
`CheckNetIsolation.exe LoopbackExempt -a -n="Microsoft.Win32WebViewHost_cw5n1h2txyewy"`
Jeżeli w twojej ścieżce do pliku występują chińskie symbole, to mogą one być tego przyczyną. Pracujemy nad poprawką.
Możesz spróbować uruchomić aplikacje w trybie zgodności z Windows'em 8
Jeżeli nic z tego nie pomoże, możesz uruchomić GrassClipper'a w trybie `chrome` lub `browser`. W tym celu:
* Stwórz skrót do `GrassClipper.exe`
* Kliknij na niego prawym przyciskiem, wybierz `Właściwości`
* W polu `Element docelowy`, na samym końcu, dodaj ` --mode=chrome` lub ` --mode=browser`
* `chrome` działa tylko wtedy gdy masz zainstalowanego Chrome'a, otworzy okienko Chrome'a
* `brower` otworzy GrassClippera w twojej domyślnej przeglądarce
* Kliknij `Ok`
* Od teraz uruchamiaj GrassClippera nowo stworzonym skrótem.
## Błąd 502
1. Jeżeli dołączas na serwer lokalny to upewnij się czy jest włączony. W przeciwnym wypadku, upewnij się, czy serwer do którego się łączysz działa.
2. Jeżeli to możliwe, [użyj wersji developerskiej Grasscutter'a](https://github.com/Grasscutters/Grasscutter/tree/development). Z tego co wiadomo to działa lepiej z GrassClipper'em.
Jeżeli dalej dostajesz błąd 502 przy próbie logowania do własnego serwera, otwórz plik `config.json` w folderze Grasscutter'a i dodaj w nim w sekcji `DispatchServer`:
```json
"PublicPort": TWÓJ_PORT
```
`TWÓJ_PORT` jest tym samym portem co w polu `Port`. Jest to prawdopodobnie wartość 443.
## Błąd 4206
Upewnij się, że posiadasz odpowiedni plik `keystore.p12` dla twojej wersji. Sprawdź, czy hasło jest poprawnie ustawione w pliku `config.json` (puste dla wersji `stabilnej`, "123456" dla wersji `developerskiej`).
## Nieskończone okna CMD
Jeżeli jakikolwiek skrypt uruchamia nieskończoność okien CMD (np. instalator proxy albo starter serwera prywatnego), upewnij się, że UAC (User Access Control) jest ustawiony na dowolną opcje która wymaga potwierdzenia. Sprawdź czy twoje konto może uruchamiać programy jako Administrator.
## Discord nie pozwala wysyłać mi wiadomości lub wczytywać obrazków/YouTube dziwnie się zachowuje
Discord/Youtube (i na pewno pare innych) nie przepadają za serwerem proxy. Musisz go wyłączyć zamykając mitmdump, albo wyłączając proxy w ustawieniach Windowsa.
## Nie mam dostępu do internetu po zamknięciu wszystkiego/restarcie komputera!
Launcher najprawdopodobniej nie został poprawnie zamknięty, przez co nie był w stanie przywrócić oryginalnych ustawień proxy. Wyłącz proxy w ustawieniach Windows'a.
# Dostępne tłumaczenia oraz ich autorzy
Dziękujemy dla wszystkich, którzy pomagają w tłumaczeniu! <3
* ZH - nuoxianCN, Scirese & MrAru
* ZH-TW - Kimi & KormiMeiko
* PT-BR - na.na
* VIE - labalityowo
* ID - Iqrar99 & nautilust
* FR - linsorak & memetrollsXD
* ES - memetrollsXD
* ND - memetrollsXD
* RU - fitiskin
* TR - lilmayofuksu
* JP - conochy
* HD - Arikatsu
* PL - zakhil-dev
# Zrzuty ekranu
![image](https://user-images.githubusercontent.com/25207995/164574276-645548c2-7ba6-47c3-8df4-77082003648f.png)
![image](https://user-images.githubusercontent.com/25207995/164393190-f7e6633c-60bd-4186-bf0c-30d9f30871f4.png)
![image](https://user-images.githubusercontent.com/25207995/164393040-4da72f29-6d59-4af4-bd60-072269f2ba2a.png)
![image](https://user-images.githubusercontent.com/25207995/164393024-56543ddf-7063-4c04-9a9f-0c6238f30e90.png)
![image](https://user-images.githubusercontent.com/25207995/164393118-de844e75-f9a2-491a-aea6-f2d563abecc7.png)
![image](https://user-images.githubusercontent.com/25207995/164882735-77aa535c-0e93-4b32-af7c-f8b59888257a.png)
![image](https://user-images.githubusercontent.com/25207995/164882716-c9f16cd0-c0b6-4c0a-ae9e-4c95da9ef7f5.png)

152
README_id.md Normal file
View File

@ -0,0 +1,152 @@
# GrassClipper
[EN](README.md) | [PL](README_PL.md) | ID
Peluncur eksperimental Grasscutter untuk memudahkan penggantian antara server resmi (Official) dan server pribadi
[Unduh Disini!](https://github.com/Grasscutters/GrassClipper/releases/) (Mendukung Windows 8 keatas)
*\*Catatan: Beberapa terjemahan mungkin ada yang sudah usang, kalau ada bahasa Inggris yang muncul secara acak pada teks atau opsi pilihan mungkin ini penyebabnya. Jika kamu melihat masalah seperti ini, jangan ragu untuk membuat pull request!*
# Daftar Isi
* [Setup (untuk pengguna)](#setup-untuk-pengguna)
* [Setup (untuk pengembang)](#setup-untuk-pengembang)
* [Daftar yang Harus Dilakukan](#daftar-yang-harus-dilakukan)
* [Masalah Umum](#punya-masalah)
* [Pemasangan Proxy Tidak Terbuka/Gagal](#pemasangan-manual-proxy)
* [Perbaikan Layar Putih](#perbaikan-layar-putih)
* [Kesalahan 502](#kesalahan-502)
* [Kesalahan 4206](#kesalahan-4206)
* [Jendela CMD Terbuka Terus-menerus](#jendela-cmd-terbuka-terus-menerus)
* [Discord/Youtube Tidak Berfungsi dengan Baik](#discord-tidak-bisa-mengirim-pesan-atau-memuat-gambar-atau-youtube-tidak-tampil-dengan-baik)
* [Tidak Ada Koneksi Internet](#komputerku-tidak-ada-akses-internet-setelah-menutup-peluncur-atau-restart)
* [Bahasa dan Kredit Terjemahan](#bahasa-yang-tersedia-dan-kredit-penerjemah)
* [Tangkapan Layar](#tangkapan-layar)
# Setup (untuk Pengguna)
1. Unduh file zip nya
2. Ekstrak file zip nya di sembarang tempat atau tempat yang sudah ditentukan
3. Jalankan `GrassClipper.exe`, pasang server proxy nya, dan atur folder game nya!
# Setup (untuk Pengembang)
0. Clone/unduh repositori ini
1. Pastikan kamu punya [NodeJS](https://nodejs.org/en/download/) yang sudah terpasang.
2. Pasang alat CLI `neu`: `npm install -g @neutralinojs/neu`
3. Pasang dependensinya: `setup_win.cmd`
4. Kompilasi dan jalankan:
* Untuk pengujian: `npm run dev`
* Untuk produksi: `npm run build`
# Daftar yang Harus Dilakukan
* Antarmuka/internal
* [x] UI
* [x] Opsi server resmi (Official) dan pribadi
* [x] IP server masukan
* [x] Penataan gaya CSS yang wah! (Seperti gaya menu vertikal ala CoD: MW 2019 untuk memilih antara server resmi (official) dan pribadi? [Lihat disini](https://charlieintel.com/wp-content/uploads/2020/11/MW-new-menu.png))
* [x] Skrip saklar mati (opsional)
* [x] Otomatis menjalankan `install.cmd` ketika membuka GrassClipper untuk pertama kalinya
* [x] Pengunduh otomatis Grasscutter
* [ ] Deteksi saat berada di folder yang tidak dapat diakses oleh program (contohnya `C:/Program Files`) dan ingatkan
* [ ] Gambar kustom untuk bagian server pribadi (siapapun dipersilahkan mengirimkan pull request untuk menambahkan gambar lainnya!)
* [x] Nama pengguna/kata sandi opsional sebelum memasuki server (belum terimplementasi di Grasscutter)
* [ ] Deteksi platform dan skrip bash
* [ ] Pembuat spanduk terintegrasi
* Layanan Proxy
* [x] Server lokal proxy
* [x] Cegat dan ubah permintaan GI seperti dengan Fiddler, izinkan yang lain melewati
* [ ] Perbaiki masalah Discord dan YouTube saat proxy diaktifkan (mungkin diperbaiki)
# Punya masalah?
Dibawah ini mungkin beberapa skenario yang kamu hadapi dan beserta solusinya.
# Pemasangan Manual Proxy
Jika kamu punya masalah saat memasang server proxy, kamu juga dapat memasangnya secara manual. Cara memasangnya:
1. Buat sebuah folder yang bernama `ext` di folder GrassClipper jika folder tersebut tidak ada.
2. Unduh dan ekstrak isi konten dari [file ini](https://snapshots.mitmproxy.org/7.0.4/mitmproxy-7.0.4-windows.zip) ke dalam folder `ext`
3. Klik dua kali `mitmdump.exe` dan izinkan untuk menjalankan beberapa detik agar bisa membuat sertifikat
4. Jalankan perintah ini sebagai Administrator: `certutil -addstore root "%USERPROFILE%\.mitmproxy\mitmproxy-ca-cert.cer"`
5. Gunakan GrassClipper seperti biasa!
## Perbaikan Layar Putih
Mengalami layar putih? [Pastikan WebView2 terpasang](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download)
Kamu mungkin perlu menjalankan perintah ini sebagai Administrator:
`CheckNetIsolation.exe LoopbackExempt -a -n="Microsoft.Win32WebViewHost_cw5n1h2txyewy"`
Jika kamu mempunyai karakter Cina di jalur file mu, mungkin ini dapat menyebabkan crash! Saya sedang mengerjakan perbaikannya.
Kamu mungkin bisa juga menjalankan ini di mode kompatibilitas Windows 8.
Jika semuanya gagal, kamu bisa menjalankan GrassClipper di mode `chrome` atau `browser`. Cara melakukannya:
* Buat sebuah shortcut ke `GrassClipper.exe`
* Klik kanan shortcut tersebut, lalu klik `Properties`
* Di dalam kotak `Target`, pada bagian akhirnya, tambahkan ` --mode=chrome` atau ` --mode=browser`
* `chrome` hanya bisa bekerja jika kamu punya Chrome yang terpasang dan akan membuat jendela Chrome
* Untuk `browser` seperti yang kamu tebak, akan membuka GrassClipper di default browser mu
* Klik `Ok`
* Jalankan GrassClipper dengan menggunakan shortcut ini mulai dari sekarang!
## Kesalahan 502
1. Jika kamu menjalankan ini di server lokal, pastikan server lokal tersebut berjalan dengan baik. Sebaliknya, pastikan server yang kamu hubungkan juga berjalan dengan baik.
2. Kalau bisa, [gunakan versi pengembangan Grasscutter](https://github.com/Grasscutters/Grasscutter/tree/development). Biasanya versi ini bekerja dengan baik di GrassClipper.
Jika kamu masih mendapatkan kesalahan 502 ketika mencoba masuk ke servermu sendiri, buka file konfigurasi Grasscutter dan tambahkan pada bagian `DispatchServer`:
```json
"PublicPort": PORT_MU
```
dimana `PORT_MU` itu sama dengan port yang kamu gunakan sebagai nilai `Port`. Biasanya diisi dengan nilai 443.
## Kesalahan 4206
Pastikan kamu punya file `keystore.p12` dari versi yang kamu pilih (`stabil` atau `pengembangan`). Dan juga pastikan kata sandinya diatur dengan benar di file `config.json` pada Grasscutters (kosong untuk `stabil`, "123456" untuk `pengembangan`).
## Jendela CMD Terbuka Terus-menerus
Jika kamu mendapatkan jendela CMD yang terbuka secara terus-menerus dari beberapa skrip (seperti pemasangan proxy atau saat menjalankan server pribadi), pastikan kamu punya UAC (User Access Control) yang diatur pada opsi yang memunculkan dialog permintaan izin menjalankan. Pastikan juga akun penggunamu (user account) bisa dibuka dengan perizinan Admin.
## Discord Tidak Bisa Mengirim Pesan atau Memuat Gambar atau Youtube Tidak Tampil dengan Baik
Discord/YouTube (dan beberapa aplikasi lainnya) sepertinya tidak menyukai server proxy mu. Kamu mungkin perlu menonaktifkannya dengan menutup mitmdump atau dengan menonaktifkan proxy mu di pengaturan Windows proxy.
## Komputerku Tidak Ada Akses Internet Setelah Menutup Peluncur atau Restart!
Sepertinya peluncur tidak menutup dengan benar dan tidak bisa membersihkan pengaturan proxy seperti semula. Nonaktifkan proxy mu di pengaturan Windows proxy.
# Bahasa yang Tersedia dan Kredit Penerjemah
Terima kasih kepada semua orang yang telah menyediakan terjemahan! <3
* ZH - nuoxianCN, Scirese & MrAru
* ZH-TW - Kimi & KormiMeiko
* PT-BR - na.na
* VIE - labalityowo & lunaticwhat
* ID - Iqrar99 & nautilust
* FR - linsorak & memetrollsXD
* ES - memetrollsXD
* ND - memetrollsXD
* RU - fitiskin
* TR - lilmayofuksu
* JP - conochy
* HD - Arikatsu
* PL - zakhil-dev
# Tangkapan Layar
![image](https://user-images.githubusercontent.com/25207995/164574276-645548c2-7ba6-47c3-8df4-77082003648f.png)
![image](https://user-images.githubusercontent.com/25207995/164393190-f7e6633c-60bd-4186-bf0c-30d9f30871f4.png)
![image](https://user-images.githubusercontent.com/25207995/164393040-4da72f29-6d59-4af4-bd60-072269f2ba2a.png)
![image](https://user-images.githubusercontent.com/25207995/164393024-56543ddf-7063-4c04-9a9f-0c6238f30e90.png)
![image](https://user-images.githubusercontent.com/25207995/164393118-de844e75-f9a2-491a-aea6-f2d563abecc7.png)
![image](https://user-images.githubusercontent.com/25207995/164882735-77aa535c-0e93-4b32-af7c-f8b59888257a.png)
![image](https://user-images.githubusercontent.com/25207995/164882716-c9f16cd0-c0b6-4c0a-ae9e-4c95da9ef7f5.png)

View File

@ -10,7 +10,7 @@
"grasscutterFileSet": "Set \"Grasscutter\" .jar file",
"folderNotSet": "Not set",
"ipPlaceholder": "IP Address",
"ipPlaceholder": "Server Address...",
"portPlaceholder": "Port",
"noFavorites": "No favorites set",
@ -28,6 +28,7 @@
"enableServerLauncherSubtitle": "Enable to server launcher tile for launching a local Grasscutter instance.",
"httpsOption": "Use HTTPS",
"httpsSubtitle": "Choose between using HTTPS or HTTP.",
"debugOption": "Debugging",
"introSen1": "Looks like this is your first time opening GrassClipper!",
"introSen2": "First of all, welcome, happy to see you here! :)",
@ -38,7 +39,7 @@
"proxyInstallBtn": "Install",
"proxyInstallDeny": "No thanks",
"gameFolderDialog": "Select game folder",
"gameFolderDialog": "Select game exe",
"grasscutterFileDialog": "Select Grasscutter server jar file",
"loggingInTo": "Logging in to: ",
@ -74,10 +75,20 @@
"devSubtitle": "Install Grasscutter development branch. This build sometimes has bugs, and is frequently updated. Use at your own risk.",
"downloadResources": "Download Grasscutter Resources",
"resourceSubtitle": "Downloads Grasscutter resources into the currently set Grasscutter folder. This should be done unless you plan on getting resources externally.",
"downloadData": "Download Grasscutter Data",
"dataSubtitle": "Downloads Grasscutter data files, such as keys, spawns, and other vital files.",
"gcScriptRunning": "Running...",
"stableInstall": "Download",
"devInstall": "Download",
"updateNotifText": "A new update is available! Newest version: "
"updateNotifText": "A new update is available! Newest version: ",
"foreignCharacterAlert": "The file path set contains foreign characters, this may cause problems!",
"dialogOk": "OK",
"dialogNo": "NO",
"serverEnableDialogTitle": "You found the Grasscutter server launcher!",
"serverEnableDialogText": "If you do not have an existing Grasscutter installation to set, would you like to download a build?"
}

85
languages/hd.json Normal file
View File

@ -0,0 +1,85 @@
{
"fullLangName": "Hindi",
"appName": "ग्रासक्लिपर",
"playOfficial": "खेलो असली गेम",
"playPrivate": "खेलो ग्रासकटर पर",
"launchLocalServer": "शुरू करे लोकल सर्वर",
"gameExeSet": "गेम का निष्पादन करे",
"grasscutterFileSet": "लगाए \"ग्रासकटर \" .jar फ़ाइल",
"folderNotSet": "नहीं लगा है",
"ipPlaceholder": "आय पी एड्रेस",
"portPlaceholder": "पोर्ट",
"noFavorites": "कोई पसन्दीदार नहीं लगे",
"settingsTitle": "सेटिंग्स",
"scriptsSectionTitle": "स्क्रिप्ट्स",
"killswitchOption": "किल स्विच",
"killswitchSubtitle": "सिर्फ उनके लिए जो सोचते हैं की यह सब असली अकाउंट को बन कर देग। यह गेम और *इंटरनेट कनेक्शन* मर देता है अगर कुछ प्रॉक्सी को होता है। ",
"proxyOption": "प्रॉक्सी",
"proxySubtitle": "प्रॉक्सी सर्वर इनस्टॉल करे प्रॉक्सी स्क्रिप्ट्स से",
"updateOption": "अपडेट ",
"updateSubtitle": "अपने आप अपडेट होने का फीचर अभी बंद है। GitHub देखे नए रिलीज़ के लिए। ",
"languageOption": "भाषा ",
"languageSubtitle": "अपनी भाषा चुने!",
"enableServerLauncherOption": "सर्वर लांचर शुरू करे",
"enableServerLauncherSubtitle": "सक्षम करे सर्वर लांचर टाइल ताकि ये एक लोकल ग्रासकटर इंस्टैंस को शुरू कर सके। ",
"httpsOption": "HTTPS का उपयोग करे",
"httpsSubtitle": "चयन करे HTTPS या HTTP",
"introSen1": "लग रहा है यह तुम्हारा पहली बार खोलना हुआ है ग्रास्सक्लीप्पेर!",
"introSen2": "पहली बात, स्वागत है, अच्छा लगा आपको देख के यहाँ! :)",
"introSen3": "प्रॉक्सी इंस्टालर शुरू करे?",
"introSen4": "(ज़रुरत है इसकी सर्वर से कनेक्ट करने के लिए)",
"updateBtn": "अपडेट ",
"proxyInstallBtn": "इनस्टॉल ",
"proxyInstallDeny": "कोई ज़रुरत नहीं",
"gameFolderDialog": "गेम फोल्डर सेट करे",
"grasscutterFileDialog": "ग्रासकटर jar फाइल सेलेक्ट करे",
"loggingInTo": "लोग हो रहे हैं इसमें: ",
"registeringFor": "रजिस्टर करे इसके लिए: ",
"authUsername": "यूजरनाम: ",
"authPassword": "पासवर्ड: ",
"authConfirmPassword": "पासवर्ड पक्का करे: ",
"authLoginBtn": "लॉगिन",
"authRegisterBtn": "रजिस्टर",
"authLoginTitle": "लॉगिन",
"authRegisterTitle": "रजिस्टर",
"launchWithoutAuth": "शुरू करे बिना ऑथेंटिकेशन के",
"alertInvalid": "गलत यूजरनाम या पासवर्ड",
"alertNoPass": "कोई पासवर्ड नहीं लगा, कृपया पासवर्ड चेंज करे",
"alertUnknown": "अनजान एरर। सर्वर के मालिक से बात करे",
"alertAuthNoLogin": "ऑथेंटिकेशन बंद है, लॉगिन की कोई ज़रुरत नहीं!",
"alertLoginSuccess": "लॉगिन पूरा हुआ! टोकन क्लिपबोर्ड पर कॉपी हो गया है। यह टोकन पेस्ट करे यूजरनाम की जगह पर गेम के अंदर ताकि लॉगिन हो सके। ",
"alertUserTaken": "यूजरनाम ले लिया गया है",
"alertPassMismatch": "पासवर्ड और पासवर्ड कन्फर्मेशन मैच नहीं कर रहे",
"alertAuthNoRegister": "ऑथेंटिकेशन बंद है, रजिस्ट्रेशन की कोई ज़रुरत नहीं!",
"alertRegisterSuccess": "रजिस्ट्रेशन समाप्त हुआ!",
"downloadTitle": "डौन्लोडस",
"grassclipperTitle": "ग्रासक्लिपर",
"grasscutterTitle": "ग्रासकटर",
"installerTitle": "इंस्टालर",
"installerSubtitle": "ये प्रॉक्सी और कुछ और टूल्स इनस्टॉल करता है। ज़रुरत है इसकी ग्रासकटर सर्वर्स के लिए",
"downloadStable": "डाउनलोड ग्रासकटर स्टेबल बिल्ड",
"stableSubtitle": "इनस्टॉल ग्रासकटर स्टेबल ब्रांच। यह बिल्ड में काम फीचर्स है पर काम बग्स भी है।",
"downloadDev": "डाउनलोड ग्रासकटर डेवलपमेंट बिल्ड",
"devSubtitle": "इनस्टॉल ग्रासकटर डेवलपमेंट ब्रांच। इस बिल्ड में काफी बार बग्स होते हैं पर जल्दी जल्दी अपडेट होता है। अपने बूते पे इस्तेमाल करे।",
"downloadResources": "डाउनलोड ग्रसससटर रिसोर्सेज",
"resourceSubtitle": "आपभी सेट हुए ग्रासकटर फोल्डर में ग्रासकटर के रिसोर्सेज डाउनलोड करता है। यह हो जाना चाहिए अगर आपने कही और से रिसोर्सेज नहीं लिये।",
"gcScriptRunning": "चल रहा है...",
"stableInstall": "डाउनलोड",
"devInstall": "डाउनलोड",
"updateNotifText": "नया अपडेट आया है! नया वर्शन: ",
"foreignCharacterAlert": "इस फाइल पथ में चीनी चरक्टेर्स हैं, यह समस्या दे सकता है!"
}

View File

@ -71,13 +71,20 @@
"downloadStable": "Unduh Versi Stabil Grasscutter",
"stableSubtitle": "Pasang versi stabil Grasscutter. Versi ini biasanya tidak punya banyak bug, tetapi juga fiturnya lebih sedikit.",
"downloadDev": "Unduh Versi Pengembangan Grasscutter",
"downloadSubtitle": "Pasang versi pengembangan Grasscutter. Versi ini biasanya mempunyai banyak bug dan sering diperbarui. Gunakan dengan resikomu sendiri.",
"devSubtitle": "Pasang versi pengembangan Grasscutter. Versi ini biasanya mempunyai banyak bug dan sering diperbarui. Gunakan dengan resikomu sendiri.",
"downloadResources": "Unduh Sumber Daya Grasscutter",
"devSubtitle": "Unduh sumber daya Grasscutter ke dalam folder Grasscutter yang sudah diatur. Ini harus dilakukan kecuali kamu berencana untuk mendapatkan sumber daya secara eksternal.",
"resourceSubtitle": "Unduh sumber daya Grasscutter ke dalam folder Grasscutter yang sudah diatur. Ini harus dilakukan kecuali kamu berencana untuk mendapatkan sumber daya secara eksternal.",
"gcScriptRunning": "Menjalankan...",
"stableInstall": "Unduh",
"devInstall": "Unduh",
"updateNotifText": "Pembaruan baru tersedia! Versi terbaru: "
"updateNotifText": "Pembaruan baru tersedia! Versi terbaru: ",
"foreignCharacterAlert": "Jalur file yang diatur berisi karakter Cina, ini dapat menyebabkan masalah!",
"dialogOk": "OK",
"dialogNo": "TIDAK",
"serverEnableDialogTitle": "Kamu menemukan peluncur server Grasscutter!",
"serverEnableDialogText": "Jika kamu tidak memiliki pemasangan Grasscutter untuk diatur, apakah kamu mau mengunduh build nya?"
}

85
languages/jp.json Normal file
View File

@ -0,0 +1,85 @@
{
"fullLangName": "日本語",
"appName": "GrassClipper",
"playOfficial": "起動 (Official)",
"playPrivate": "起動 (Grasscutter)",
"launchLocalServer": "ローカルサーバーを起動",
"gameExeSet": "GenshinImpact.exe の場所を指定",
"grasscutterFileSet": "grasscutter.jar の場所を指定",
"folderNotSet": "原神のフォルダーが指定されていません。",
"ipPlaceholder": "IP アドレス",
"portPlaceholder": "ポート",
"noFavorites": "お気に入りはまだ登録されていません",
"settingsTitle": "設定",
"scriptsSectionTitle": "スクリプト",
"killswitchOption": "強制終了",
"killswitchSubtitle": "緊急時のみ。プロキシにエラーが発生した場合に、ゲームを終了し、インターネットを遮断します。",
"proxyOption": "プロキシ",
"proxySubtitle": "プロキシサーバーをインストールします。",
"updateOption": "更新",
"updateSubtitle": "自動更新は現在無効化されています。GitHub で最新バージョンを確認してください。",
"languageOption": "言語",
"languageSubtitle": "言語を選択してください。",
"enableServerLauncherOption": "サーバーランチャーを有効化します",
"enableServerLauncherSubtitle": "Grasscutter を起動するための、ランチャータイルを有効化します。",
"httpsOption": "HTTPS を使用",
"httpsSubtitle": "HTTP と HTTPS のどちらを使用するか選択します。このオプションは、プライベートサーバーでプレイするときにのみ適用されます。",
"introSen1": "GrassClipper へようこそ!",
"introSen2": "GrassClipper をご利用いただきありがとうございます。",
"introSen3": "プロキシサーバーをインストールしますか?",
"introSen4": "(インターネットへの接続が必要)",
"updateBtn": "更新",
"proxyInstallBtn": "インストールする",
"proxyInstallDeny": "インストールしない",
"gameFolderDialog": "原神のゲームフォルダーを指定",
"grasscutterFileDialog": "grasscutter.jar の場所を指定",
"loggingInTo": "ログイン先: ",
"registeringFor": "登録先: ",
"authUsername": "ユーザー名: ",
"authPassword": "パスワード: ",
"authConfirmPassword": "パスワード(確認): ",
"authLoginBtn": "ログイン",
"authRegisterBtn": "登録",
"authLoginTitle": "ログイン",
"authRegisterTitle": "登録",
"launchWithoutAuth": "認証せず起動",
"alertInvalid": "ユーザー名またはパスワードが誤っています。",
"alertNoPass": "パスワードが設定されていません。パスワードを設定してください。",
"alertUnknown": "不明なエラーが発生しました。サーバーの管理者に連絡してください。",
"alertAuthNoLogin": "認証が無効になっています。ログインする必要はありません。",
"alertLoginSuccess": "ログインに成功しました。トークンをクリップボードにコピーしたので、ゲームのユーザー名欄に貼り付けてログインしてください。",
"alertUserTaken": "そのユーザー名はすでに使用されています。",
"alertPassMismatch": "パスワードが一致していません。",
"alertAuthNoRegister": "認証が無効になっています。ログインする必要はありません。",
"alertRegisterSuccess": "登録成功",
"downloadTitle": "ダウンロード",
"grassclipperTitle": "GrassClipper",
"grasscutterTitle": "Grasscutter",
"installerTitle": "インストーラー",
"installerSubtitle": "Grasscutter に必要な、プロキシなどのツールをインストールします。",
"downloadStable": "Grasscutter の安定版をインストール",
"stableSubtitle": "Grasscutter の安定版をインストールします。バグは少ないですが、新機能も少ないです。",
"downloadDev": "Grasscutter の開発版をインストール",
"devSubtitle": "Grasscutter の開発版をインストールします。バグが多い恐れがあります。また、頻繁に更新されます。",
"downloadResources": "Grasscutter のリソースをダウンロード",
"resourceSubtitle": "Grasscutter のリソースをダウンロードします。ほかのところから入手しない場合は、これをダウンロードする必要があります。",
"gcScriptRunning": "実行中...",
"stableInstall": "ダウンロード",
"devInstall": "ダウンロード",
"updateNotifText": "新しいバージョンが利用できます。Version: ",
"foreignCharacterAlert": "ファイルパスに漢字やひらがななどの全角文字が含まれているため、正常に動作しない場合があります。"
}

93
languages/ko.json Normal file
View File

@ -0,0 +1,93 @@
{
"fullLangName": "한국어",
"appName": "GrassClipper",
"playOfficial": "플레이 (공식)",
"playPrivate": "플레이 (Grasscutter)",
"launchLocalServer": "로컬에서 실행",
"gameExeSet": "게임 실행파일 설정",
"grasscutterFileSet": "\"Grasscutter\" .jar 파일 설정",
"folderNotSet": "폴더가 지정되지 않았습니다.",
"ipPlaceholder": "서버 주소",
"portPlaceholder": "포트",
"noFavorites": "즐겨찾기를 설정하지 않았습니다.",
"settingsTitle": "설정",
"scriptsSectionTitle": "스크립트",
"killswitchOption": "프로세스 중지",
"killswitchSubtitle": "프록시에 문제가 발생할 경우, 게임과 인터넷을 중지합니다.",
"proxyOption": "프록시",
"proxySubtitle": "스크립트를 통해 프록시 서버 설치",
"updateOption": "업데이트",
"updateSubtitle": "자동 업데이트가 일시적으로 비활성화되어 있습니다. Github에서 최신 버전을 확인하세요.",
"languageOption": "언어",
"languageSubtitle": "언어를 선택해주세요.",
"enableServerLauncherOption": "서버 실행 버튼 활성화",
"enableServerLauncherSubtitle": "로컬 Grasscutter 인스턴스를 실행하기 위해, 서버 실행기 타일을 활성화합니다.",
"httpsOption": "HTTPS 사용",
"httpsSubtitle": "HTTPS 또는 HTTP 중 하나를 선택하세요.",
"debugOption": "디버깅",
"introSen1": "GrassClipper에 오신 것을 환영합니다!",
"introSen2": "GrassClipper를 사용해주셔서 감사드립니다.",
"introSen3": "프록시 설치 관리자를 실행하시겠습니까?",
"introSen4": "(서버에 연결하는 데 필요)",
"updateBtn": "업데이트",
"proxyInstallBtn": "설치",
"proxyInstallDeny": "사양하겠습니다.",
"gameFolderDialog": "게임 실행 파일을 설정하세요.",
"grasscutterFileDialog": "Grasscutter jar을 설정하세요.",
"loggingInTo": "로그인: ",
"registeringFor": "등록: ",
"authUsername": "이름: ",
"authPassword": "비밀번호: ",
"authConfirmPassword": "비밀번호 확인: ",
"authLoginBtn": "로그인",
"authRegisterBtn": "가입",
"authLoginTitle": "로그인",
"authRegisterTitle": "가입",
"launchWithoutAuth": "인증 없이 실행",
"alertInvalid": "잘못된 사용자 이름 또는 비밀번호입니다.",
"alertNoPass": "비밀번호를 설정하지 않았습니다. 비밀번호를 설정하세요.",
"alertUnknown": "알 수 없는 오류, 서버 소유자에게 문의하세요.",
"alertAuthNoLogin": "인증이 비활성화되어있으므로, 로그인이 필요하지 않습니다!",
"alertLoginSuccess": "로그인 성공! 토큰이 클립보드에 복사되었습니다. 토큰을 게임의 사용자 이름 필드에 붙여 로그인합니다.",
"alertUserTaken": "해당 사용자 이름은 이미 사용 중입니다.",
"alertPassMismatch": "암호 확인이 일치하지 않습니다.",
"alertAuthNoRegister": "인증이 비활성화되어있으므로, 가입이 필요하지 않습니다!",
"alertRegisterSuccess": "가입 성공!",
"downloadTitle": "다운로드",
"grassclipperTitle": "GrassClipper",
"grasscutterTitle": "Grasscutter",
"installerTitle": "설치 관리자",
"installerSubtitle": "프록시 및 기타 도구를 설치합니다. (Grasscutter 서버에 필요)",
"downloadStable": "안정적인 Grasscutter 빌드 다운로드",
"stableSubtitle": "안정적인 Grasscutter를 설치합니다. (버그는 거의 없지만, 새로운 기능 또한 적습니다.)",
"downloadDev": "개발 버전 Grasscutter 다운로드",
"devSubtitle": "개발 버전의 Grasscutter를 설치합니다. (버그가 있을 수 있으며, 자주 업데이트됩니다. 버그로 인한 피해는 책임지지 않습니다.)",
"downloadResources": "Grasscutter 리소스 다운로드",
"resourceSubtitle": "Grasscutter 리소스를 현재 설정된 Grasscutter 폴더에 다운로드합니다. 외부에서 리소스를 가져올 예정이 아니라면, 이 작업을 수행해야 합니다.",
"downloadData": "Grasscutter 데이터 다운로드",
"dataSubtitle": "중요한 Grasscutter 데이터 파일을 다운로드합니다.",
"gcScriptRunning": "실행중...",
"stableInstall": "다운로드 (stable)",
"devInstall": "다운로드 (dev)",
"updateNotifText": "새 업데이트를 사용할 수 있습니다: ",
"foreignCharacterAlert": "파일 경로에 유효하지 않은 문자가 포함되어 있으므로, 문제가 발생할 수 있습니다!",
"dialogOk": "예",
"dialogNo": "아니오",
"serverEnableDialogTitle": "Grasscutter 서버 실행기를 찾았습니다!",
"serverEnableDialogText": "설정할 기존의 Grasscutter가 없는 경우, 빌드를 다운로드하시겠습니까?"
}

91
languages/pl.json Normal file
View File

@ -0,0 +1,91 @@
{
"fullLangName": "Polski",
"appName": "GrassClipper",
"playOfficial": "Serwer oficjalny",
"playPrivate": "Serwer prywatny",
"launchLocalServer": "Uruchom serwer prywatny",
"gameExeSet": "Ustaw plik gry",
"grasscutterFileSet": "Ustaw plik \"Grasscutter\" .jar ",
"folderNotSet": "Nie ustawiono",
"ipPlaceholder": "Adres serwera",
"portPlaceholder": "Port",
"noFavorites": "Nie dodano żadnych ulubionych",
"settingsTitle": "Ustawienia",
"scriptsSectionTitle": "Skrypty",
"killswitchOption": "Kill Switch",
"killswitchSubtitle": "Tylko dla tych, którzy boją się o dostanie bana. Wyłącza gre *oraz twój internet* jeżeli coś stanie się z proxy.",
"proxyOption": "Proxy",
"proxySubtitle": "Zainstaluj serwer proxy poprzez skrypt instalacyjny",
"updateOption": "Aktualizacja",
"updateSubtitle": "Auto-aktualizacje są niedostępne. Sprawdź GitHub'a projektu po nowe wersje.",
"languageOption": "Język",
"languageSubtitle": "Wybierz swój język!",
"enableServerLauncherOption": "Włącz Launcher Serwera",
"enableServerLauncherSubtitle": "Enable to server launcher tile for launching a local Grasscutter instance.",
"httpsOption": "Używaj HTTPS",
"httpsSubtitle": "Wybierz pomiędzy używaniem HTTPS, a HTTP.",
"introSen1": "Wygląda na to, że po raz pierwszy uruchomiłeś GrassClipper'a!",
"introSen2": "Po pierwsze, miło Cię tu widzieć! :)",
"introSen3": "Czy chcesz uruchomić instalator proxy?",
"introSen4": "(proxy wymagane jest do łączenia się z serwerem prywatnym)",
"updateBtn": "Aktualizuj",
"proxyInstallBtn": "Instaluj",
"proxyInstallDeny": "Nie, dziękuję",
"gameFolderDialog": "Ustaw folder gry",
"grasscutterFileDialog": "Wybierz plik serwera Grasscutter",
"loggingInTo": "Logowanie do: ",
"registeringFor": "Rejestracja do: ",
"authUsername": "Nazwa użytkownika: ",
"authPassword": "Hasło: ",
"authConfirmPassword": "Potwierdź hasło: ",
"authLoginBtn": "Zaloguj",
"authRegisterBtn": "Zarejestruj",
"authLoginTitle": "Logowanie",
"authRegisterTitle": "Rejestracja",
"launchWithoutAuth": "Uruchom bez autentykacji",
"alertInvalid": "Błędna nazwa użytkownika lub hasło",
"alertNoPass": "Nie ustawiono hasła, proszę ustawić hasło",
"alertUnknown": "Nieznany błąd, skontaktuj się z właścicielem serwera",
"alertAuthNoLogin": "Autentykacja jest wyłączona, nie ma potrzeby logowania się!",
"alertLoginSuccess": "Pomyślnie zalogowano! Twój Token został skopiowany do schowka. Wklej go w polu nazwy użytkownika w grze aby się zalogować.",
"alertUserTaken": "Ta nazwa jest już zajęta",
"alertPassMismatch": "Hasła nie zgadzają się",
"alertAuthNoRegister": "Autentykacja jest wyłączona, nie ma potrzeby rejestrowania się!",
"alertRegisterSuccess": "Pomyślnie zarejestrowano!",
"downloadTitle": "Pobieranie",
"grassclipperTitle": "GrassClipper",
"grasscutterTitle": "Grasscutter",
"installerTitle": "Instalator",
"installerSubtitle": "Instaluje proxy oraz inne niezbędne narzędzia do grania na serwerach Grasscutter'a.",
"downloadStable": "Pobierz stabilną wersję Grasscutter'a",
"stableSubtitle": "Zainstaluj stabilną wersję Grasscutter'a. Ma ona mało błędów, ale też mniej funkcji.",
"downloadDev": "Pobierz wersję developerską Grasscutter'a",
"devSubtitle": "Zainstaluj wersję developerską Grasscutter'a. Może posiadać sporo błędów, ma najnowsze funkcje, używaj na własne ryzyko.",
"downloadResources": "Pobierz Zasoby Grasscutter'a",
"resourceSubtitle": "Pobiera zasoby Grasscuterra do aktualnie wybranego folderu. Nie powinno się tego uruchamiać gdy zasoby chcesz pobierać z zewnątrz.",
"gcScriptRunning": "Pracuje...",
"stableInstall": "Pobierz wersje stabilną",
"devInstall": "Pobierz wersje deweloperską",
"updateNotifText": "Nowa wersja jest dostępna! Najnowsza wersja: ",
"foreignCharacterAlert": "Ścieżka pliku zawierająca chińskie symbole może powodować błędy.",
"dialogOk": "Tak",
"dialogNo": "Nie",
"serverEnableDialogTitle": "Znalazłeś Launcher Serwera",
"serverEnableDialogText": "Jeżeli nie posiadasz instalacji Grasscutter'a, możesz ją teraz pobrać. Uruchomić pobieranie?"
}

View File

@ -35,5 +35,53 @@
"proxyInstallDeny": "Não obrigado",
"gameFolderDialog": "Selecione a game pasta",
"grasscutterFileDialog": "Selecione o arquivo jar do Grasscutter"
"grasscutterFileDialog": "Selecione o arquivo jar do Grasscutter",
"loggingInTo": "Logando como: ",
"registeringFor": "Registrando como: ",
"authUsername": "Usuário: ",
"authPassword": "Senha: ",
"authConfirmPassword": "Confirme a senha: ",
"authLoginBtn": "Login",
"authRegisterBtn": "Registrar",
"authLoginTitle": "Login",
"authRegisterTitle": "Registrar",
"launchWithoutAuth": "Iniciar sem autenticação",
"alertInvalid": "Usuário ou senha invalidos",
"alertNoPass": "Nenhuma senha cadastrada, por favor troque a senha",
"alertUnknown": "Erro desconhecido, contate o dono do servidor",
"alertAuthNoLogin": "Autenticação desabilitada, não ha necessidade de logar!",
"alertLoginSuccess": "Sucesso no login! Token copiado. Cole esse token no lugar do usuário no jogo para logar.",
"alertUserTaken": "Usuário em uso",
"alertPassMismatch": "Senha e confirmação não estão iguais",
"alertAuthNoRegister": "Autenticação desabilitada, não há necessidade de registrar!",
"alertRegisterSuccess": "Registrado com sucesso!",
"downloadTitle": "Downloads",
"grassclipperTitle": "GrassClipper",
"grasscutterTitle": "Grasscutter",
"installerTitle": "Instalador",
"installerSubtitle": "Instala o proxy e outras ferramentas. Necessário para servidores Grasscutter",
"downloadStable": "Baixar a build Grasscutter Stable",
"stableSubtitle": "Instalar Grasscutter stable. Essa build geralmente tem menos bugs, mas menos recursos",
"downloadDev": "Baixar a build Grasscutter Development",
"devSubtitle": "Instalar Grasscutter Development. Essa build geralmente tem bugs e é frequentemente atualizada. Use por sua conta e risco.",
"downloadResources": "Baixar Grasscutter Resources",
"resourceSubtitle": "Baixar Grasscutter Resources na pasta atual setada do Grasscutter. Isso deve ser feito a não ser que você planeje colocar os resources externamente.",
"gcScriptRunning": "Rodando...",
"stableInstall": "Baixar",
"devInstall": "Baixar",
"updateNotifText": "Uma nova atualização esta disponivel! Nova versão: ",
"foreignCharacterAlert": "O caminho setado contem caracteres chineses, isso pode causar problemas!",
"dialogOk": "OK",
"dialogNo": "Não",
"serverEnableDialogTitle": "Você achou o launcher do server do Grasscutter!",
"serverEnableDialogText": "Caso você ainda não tenha uma instalação do grasscutter para setar, quer baixar uma build?"
}

95
languages/th.json Normal file
View File

@ -0,0 +1,95 @@
{
"fullLangName": "ภาษาไทย",
"appName": "GrassClipper",
"playOfficial": "เริ่มเกม (Official)",
"playPrivate": "เริ่มเกม (Grasscutter)",
"launchLocalServer": "เริ่ม Local Server",
"gameExeSet": "เลือกไฟล์เกม",
"grasscutterFileSet": "เลือกไฟล์ \"Grasscutter\" .jar ",
"folderNotSet": "ยังไม่ได้ตั้ง",
"ipPlaceholder": "ที่อยู่เซิร์ฟเวอร์...",
"portPlaceholder": "พอร์ต",
"noFavorites": "ยังไม่ได้ตั้ง",
"settingsTitle": "การตั้งค่า",
"scriptsSectionTitle": "สคริปต์",
"killswitchOption": "Kill Switch",
"killswitchSubtitle": "เอาไว้สำหรับพวกที่กลัวโดนแบนมากๆ เมื่อพร็อกซี่มีปัญหาจะบังคับปิดเกมและตัดอินเตอร์เน็ตทันที",
"proxyOption": "พร็อกซี่",
"proxySubtitle": "ติดตั้งพร็อกซี่ด้วยสคริปต์ติดตั้ง",
"updateOption": "อัพเดท",
"updateSubtitle": "การอัพเดทอัตโนมัติไม่พร้อมใช้งานในขณะนี้ ไปที่ Github สำหรับเวอร์ชั่นใหม่",
"languageOption": "ภาษา",
"languageSubtitle": "เลือกภาษาของคุณ",
"enableServerLauncherOption": "เพิ่มปุ่มเริ่มเซิร์ฟเวอร์",
"enableServerLauncherSubtitle": "เพิ่มปุ่มเริ่มเซิร์ฟเวอร์ไปยังหน้าแลนเชอร์ใช้สำหรับเริ่มการทำงานของเซิร์ฟเวอร์ Grasscutter ที่ติดตั้งไว้",
"httpsOption": "ใช้ HTTPS",
"httpsSubtitle": "เลือกระหว่าง HTTPS กับ HTTP.",
"debugOption": "การดีบัก",
"introSen1": "ดูเหมือนว่านี่เป็นครั้งแรกที่คุณเปิด GrassClipper!",
"introSen2": "อย่างแรกเลย ยินดีต้อนรับ เรายินดีที่ได้พบคุณที่นีี่! :)",
"introSen3": "คุณต้องการที่จะรันตัวติดตั้งพร็อกซี่หรือไม่ ",
"introSen4": "(จำเป็นต้องเชื่อมต่อไปยังเซิร์ฟเวอร์)",
"updateBtn": "อัพเดท",
"proxyInstallBtn": "ติดตั้ง",
"proxyInstallDeny": "ไม่ ขอบคุณ",
"gameFolderDialog": "เลือกไฟล์ .exe เกม",
"grasscutterFileDialog": "เลือกไฟล์ .jar Grasscutter ",
"loggingInTo": "เข้าสู่ระบบไปยัง: ",
"registeringFor": "ลงทะเบียนำหรับ: ",
"authUsername": "ชื่อผู้ใช้: ",
"authPassword": "รหัสผ่าน: ",
"authConfirmPassword": "ยืนยันรหัสผ่าน: ",
"authLoginBtn": "เข้าสู่ระบบ",
"authRegisterBtn": "ลงทะเบียน",
"authLoginTitle": "เข้าสู่ระบบ",
"authRegisterTitle": "ลงทะเบียน",
"launchWithoutAuth": "เริ่มเกมโดยไม่ต้องยืนยันตัวตน",
"alertInvalid": "ชื่อผู้ใช้หรือรหัสผ่านผิดพลาด",
"alertNoPass": "ไม้ได้ตั้งรหัสผ่าน กรุณาตั้ง",
"alertUnknown": "เกิดข้อผิดพลาดไม่ทราบสาเหตุ โปรดติดต่อผู้ดูแล",
"alertAuthNoLogin": "การยืนยันตัวตนถูกปิดใช้งาน ไม่จำเป็นต้องเข้าสู่ระบบ",
"alertLoginSuccess": "เข้าสู่ระบบสำเร็จ โทเคนถูกคัดลอกไปยังคลิปบอร์ด นำโทเคนนี้ไปกรอกใส่ช่องชื่อผู้ใช้เพื่อเข้าสู่ระบบ",
"alertUserTaken": "ชื่อผู้ใช้นี้ถูกใช้งานแล้ว",
"alertPassMismatch": "รหัสผ่านกับยืนยันรหัสผ่านไม่ตรงกัน",
"alertAuthNoRegister": "การยืนยันตัวตนถูกปิดใช้งาน ไม่จำเป็นต้องลงทะเบียน",
"alertRegisterSuccess": "ลงทะเบียนสำเร็จ!",
"downloadTitle": "ดาวน์โหลด",
"grassclipperTitle": "GrassClipper",
"grasscutterTitle": "Grasscutter",
"installerTitle": "ตัวติดตั้ง",
"installerSubtitle": "ติดตั้งพร็อกซี่และเครื่องมืออื่นๆที่จำเป็นสำหรับเซิร์ฟเวอร์ Grasscutter",
"downloadStable": "ดาวน์โหลด Grasscutter รุ่นเสถียร",
"stableSubtitle": "ดาวน์โหลด Grasscutter จากแบรนช์เสถียร โดยปกติแล้วรุ่นนี้จะมีบั๊กน้อยกว่าฟีเจอร์ก็น้อยกว่าเช่นกัน",
"downloadDev": "ดาวน์โหลด Grasscutter รุ่นนักพัฒนา",
"devSubtitle": "ดาวน์โหลด Grasscutter จากแบรนช์นักพัฒนา รุ่นนี้มีการอัพเดทบ่อย บางครั้งอาจมีบั๊ก ใช้เป็นความเสี่ยงของคุณ",
"downloadResources": "ดาวน์โหลดไฟล์ทรัพยากร Grasscutter ",
"resourceSubtitle": "ดาวน์โหลดไฟล์ทรัพยากรของ Grasscutter ไปยังโฟลเดอร์ของ Grasscutter ที่ตั้งไว้ คุณควรดำเนินการนี้เว้นแต่ว่าตุณวางแผนจะใช้ไฟล์จากภายนอก",
"downloadData": "ดาวน์โหลดไฟล์ข้อมูล Grasscutter",
"dataSubtitle": "ดาวน์โหลดไฟล์ข้อมูลของ Grasscutter อย่างเช่น keys, spawns หรือไฟล์สำคัญอย่างอื่น",
"gcScriptRunning": "กำลังรัน...",
"stableInstall": "ดาวน์โหลด",
"devInstall": "ดาวน์โหลด",
"updateNotifText": "มีการอัพเดทพร้อมใช้งาน เวอร์ชั่นล่าสุด: ",
"foreignCharacterAlert": "เส้นทางของไฟล์มีภาษาอื่นนอกจากภาษาอังกฤษอยู่ นี่อาจก่อให้เกิดปัญหาได้",
"dialogOk": "ตกลง",
"dialogNo": "ไม่",
"serverEnableDialogTitle": "คุณพบแลนเชอร์ของเซิร์ฟเวอร์ Grasscutter",
"serverEnableDialogText": "หากคุณยังไม่ได้ติดตั้งเซิร์ฟเวอร์ Grasscutter คุณต้องการจะดาวน์โหลดหรือไม่"
}

View File

@ -3,45 +3,45 @@
"appName": "GrassClipper",
"playOfficial": "Máy chủ chính thức",
"playPrivate": "Máy chủ thứ 3",
"launchLocalServer": "Khởi động Grasscutter",
"playPrivate": "Máy chủ riêng",
"launchLocalServer": "Khởi động máy chủ cục bộ",
"gameExeSet": "Chọn file \"GenshinImpact.exe\"",
"grasscutterFileSet": "Chọn file \"Grasscutter.jar\"",
"folderNotSet": "Chưa chọn file",
"gameExeSet": "Chọn tệp \"GenshinImpact.exe\"",
"grasscutterFileSet": "Chọn tệp \"Grasscutter.jar\"",
"folderNotSet": "Chưa chọn tệp",
"ipPlaceholder": "Địa chỉ",
"portPlaceholder": "Port",
"ipPlaceholder": "Địa chỉ máy chủ",
"portPlaceholder": "Cổng",
"noFavorites": "Không có máy chủ yêu thích",
"settingsTitle": "Cài đặt",
"scriptsSectionTitle": "Scripts",
"killswitchOption": "Công tắc đóng",
"killswitchSubtitle": "Dành cho những ai sợ bị ban. Tắt game *và mạng* nếu proxy có vấn đề.",
"killswitchOption": "Thoát khẩn cấp",
"killswitchSubtitle": "Để phòng tránh bị ban, thoát game *và ngắt internet* của bạn ngay lập tức nếu có vấn đề xảy ra.",
"proxyOption": "Proxy",
"proxySubtitle": "Dùng để kết nối vào máy chủ thứ 3",
"proxySubtitle": "Dùng để kết nối vào máy chủ riêng",
"updateOption": "Cập nhật",
"updateSubtitle": "Tạm thời chưa dùng được. Kiểm tra Github để biết thêm chi tiết",
"updateSubtitle": "Tính năng tự động cập nhập tạm thời chưa khả dụng. Kiểm tra Github để biết thêm chi tiết",
"languageOption": "Ngôn ngữ",
"languageSubtitle": " ",
"languageSubtitle": "Thay đổi ngôn ngữ",
"enableServerLauncherOption": "Grasscutter",
"enableServerLauncherSubtitle": "Thêm lựa chọn bật máy chủ grasscutter",
"httpsOption": "Dùng HTTPS",
"httpsSubtitle": " ",
"httpsSubtitle": "Thay đổi giao thức giữa HTTPS và HTTP",
"introSen1": "Hình như đây là lần đầu tiên bạn dùng ứng dụng này!",
"introSen2": "Trước hết, chào bạn, cảm ơn bạn đã sử dụng! :)",
"introSen3": "Bạn có muốn tải proxy không?",
"introSen4": "(dùng để vào máy chủ riêng)",
"introSen2": "Trước tiên xin chào và cảm ơn bạn đã sử dụng! :)",
"introSen3": "Bạn có muốn cài đặt ngay proxy không?",
"introSen4": "(cần thiết để vào máy chủ riêng)",
"updateBtn": "Cập nhật",
"proxyInstallBtn": "Tải",
"proxyInstallDeny": "Không",
"proxyInstallBtn": "Cài đặt",
"proxyInstallDeny": "Huỷ bỏ",
"gameFolderDialog": "Chọn GenshinImpact.exe",
"grasscutterFileDialog": "Chọn Grasscutter.jar",
"gameFolderDialog": "Chọn tệp GenshinImpact.exe",
"grasscutterFileDialog": "Chọn tệp Grasscutter.jar",
"loggingInTo": "Đang đăng nhập với tên: ",
"registeringFor": ăng ký tài khoản: ",
"registeringFor": ang đăng ký tài khoản: ",
"authUsername": "Tài khoản: ",
"authPassword": "Mật khẩu: ",
"authConfirmPassword": "Xác nhận lại mật khẩu: ",
@ -49,16 +49,42 @@
"authRegisterBtn": "Đăng ký",
"authLoginTitle": "Đăng nhập",
"authRegisterTitle": "Đăng ký",
"launchWithoutAuth": "Sử dụng mà không cần đăng nhập",
"launchWithoutAuth": "Khởi chạy không cần hệ thống xác thực",
"alertInvalid": "Tài khoản hoặc mật khẩu không đúng",
"alertNoPass": "Tài khoản này chưa có mật khẩu.",
"alertUnknown": "Lỗi không xác định, báo cáo với người host",
"alertAuthNoLogin": "Hệ thống đăng nhập đã bị tắt, không cần đăng nhập",
"alertLoginSuccess": ã đăng nhập và tự động sao chép token. Dán token vào phần tài khoản trong game để đăng nhập.",
"alertNoPass": "Chưa có mật khẩu. Vui lòng thiết lập mật khẩu",
"alertUnknown": "Lỗi không xác định, báo cáo với người quản lý máy chủ",
"alertAuthNoLogin": "Đã vô hiệu hoá hệ thống xác thực, không cần đăng nhập.",
"alertLoginSuccess": ăng nhập thành công! Token đã được sao chép vào bộ nhớ tạm. Dán token vào phần tài khoản trong game để đăng nhập.",
"alertUserTaken": "Tên tài khoản đã tồn tại",
"alertPassMismatch": "Mật khẩu xác thực không đúng với mật khẩu ban đầu",
"alertAuthNoRegister": "Hệ thống đăng nhập đã bị tắt, không cần đăng ký",
"alertRegisterSuccess": "Đăng ký thành công!"
"alertPassMismatch": "Mật khẩu xác thực không trùng khớp",
"alertAuthNoRegister": "Đã vô hiệu hoá hệ thống xác thực, không cần đăng ký.",
"alertRegisterSuccess": "Đăng ký thành công!",
"downloadTitle": "Tải về",
"grassclipperTitle": "GrassClipper",
"grasscutterTitle": "Grasscutter",
"installerTitle": "Phần cài đặt",
"installerSubtitle": "Cài đặt proxy và những phần khác. Cần thiết cho những máy chủ Grasscutter.",
"downloadStable": "Tải về Grasscutter phiên bản Stable",
"stableSubtitle": "Cài đặt Grasscutter phiên bản Stable. Đây là phiên bản ổn định, tuy nhiên sẽ có ít tính năng.",
"downloadDev": "Tải về Grasscutter phiên bản Development",
"devSubtitle": "Cài đặt Grasscutter phiên bản Development. Đây là phiên bản mới hơn, thường xuyên cập nhập hơn nhưng có thể sẽ xuất hiện lõi trong quá trình sử dụng.",
"downloadResources": "Tài về tài nguyên cho Grasscutter",
"resourceSubtitle": "Tải về phần tài nguyên cần thiết cho Grasscutter. Sử dụng tính năng này để tài về phần tài nguyên tự động nếu bạn không muốn tải về thủ công.",
"gcScriptRunning": "Đang chạy...",
"stableInstall": "Tải về",
"devInstall": "Tải về",
"updateNotifText": "Phiên bản mới nhất đang khả dụng: ",
"foreignCharacterAlert": "Đường dẫn tới tệp tin chứa ký tự phức tạp, có thể gây lỗi!",
"dialogOk": "OK",
"dialogNo": "Không",
"serverEnableDialogTitle": "Đã tìm thấy trình khởi chạy Grasscutter!",
"serverEnableDialogText": "Không tìm thấy phần cài đặt Grasscutter hiện tại, bạn có muốn tải về?"
}

View File

@ -79,5 +79,13 @@
"stableInstall": "安裝",
"devInstall": "安装",
"updateNotifText": "有新的GrassClipper更新可用 最新版本: "
"updateNotifText": "有新的GrassClipper更新可用 最新版本: ",
"foreignCharacterAlert": "此路徑含有中文字體,這可能會導致問題的發生。",
"dialogOk": "好的",
"dialogNo": "不要",
"serverEnableDialogTitle": "您找到了Grasscutter本地伺服器啟動器",
"serverEnableDialogText": "如果你現在還沒有把Grasscutter安裝在電腦上面的話要不要直接從網路上下載"
}

View File

@ -1,5 +1,5 @@
{
"fullLangName": "Simplified Chinese",
"fullLangName": "简体中文",
"appName": "GrassClipper 启动器",
"playOfficial": "启动官方服务器",
@ -60,5 +60,25 @@
"alertUserTaken": "用户名已被占用",
"alertPassMismatch": "密码与确认密码不匹配",
"alertAuthNoRegister": "未启用认证,无需注册!",
"alertRegisterSuccess": "注册成功!"
"alertRegisterSuccess": "注册成功!",
"downloadTitle": "下载",
"grassclipperTitle": "GrassClipper",
"grasscutterTitle": "Grasscutter",
"installerTitle": "安装",
"installerSubtitle": "安装Grasscutter所需的代理和其他工具。",
"downloadStable": "下载Grasscutter稳定版",
"stableSubtitle": "安装稳定版的Grasscutter。此版本更加稳定但是功能相对较少。",
"downloadDev": "下载Grasscutter开发版",
"devSubtitle": "安装开发版的Grasscutter. 这个版本更新更加频繁但是有时会有些bug。使用风险自负.",
"downloadResources": "下载Grasscutter资源",
"resourceSubtitle": "将所需资源下载至当前设置的Grasscutter文件夹。 除非你自己放置了资源,否则你应该执行此操作.",
"gcScriptRunning": "运行中...",
"stableInstall": "下载",
"devInstall": "下载",
"updateNotifText": "有新版本可用!当前最新的版本是: ",
"foreignCharacterAlert": "当前文件路径含有中文字符,可能会导致一些问题。"
}

View File

@ -1,5 +1,5 @@
{
"applicationId": "js.grassclipper.app",
"version": "0.9.1",
"version": "0.9.9",
"resourcesURL": "https://github.com/Grasscutters/GrassClipper/releases/latest/download/resources.neu"
}

View File

@ -1,6 +1,6 @@
{
"applicationId": "js.grassclipper.app",
"version": "0.9.1",
"version": "0.9.9",
"defaultMode": "window",
"port": 0,
"documentRoot": "/resources/",

1585
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "grassclipper",
"version": "0.9.1",
"version": "0.9.9",
"repository": "https://github.com/Grasscutters/GrassClipper.git",
"author": "SpikeHD <spikegdofficial@gmail.com>",
"license": "Apache-2.0",

View File

@ -85,7 +85,8 @@ class MlgmXyysd_Anime_Game_Proxy:
"uspider.yuanshen.com",
"sdk-static.mihoyo.com",
"abtest-api-data-sg.hoyoverse.com",
"log-upload-os.hoyoverse.com"
"log-upload-os.hoyoverse.com",
"webapi-os.account.hoyoverse.com"
]
if flow.request.host in LIST_DOMAINS:

View File

@ -2,20 +2,38 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="style/index.css" />
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/neutralino.js"></script>
<script src="js/init.js"></script>
<script src="js/windowDrag.js"></script>
<script src="js/hoverEvt.js"></script>
<script src="js/helpers.js"></script>
<script src="js/index.js"></script>
<script src="js/debug.js"></script>
<script src="js/gcdownloader.js"></script>
<script src="js/onLoad.js"></script>
<script src="js/alerts.js"></script>
<script src="js/options.js"></script>
<script src="js/login.js"></script>
<script src="js/authAlert.js"></script>
<script src="js/translation.js"></script>
</head>
<body>
<!-- Alert Box -->
<div id="alert">
<span id="alertText">This is a test alert</span>
</div>
<!-- Misc dialog -->
<div id="miscDialog" style="display: none">
<span id="dialogTitle">Dialog!</span>
<span id="dialogContent">This is dialog content!</span>
<div id="dialogBtns">
<button class="altBtn" id="dialogButtonAffirm">OK</button>
<button class="altBtn" id="dialogButtonNeg">NO</button>
</div>
</div>
<!-- First time setup -->
<div id="firstTimeNotice" style="display: none">
<span>
@ -159,12 +177,21 @@
<div class="downloadRow">
<div class="downloadSection">
<span class="downloadLabel" id="downloadResources">Download Grasscutter Resources</span>
<button class="smolBtn" onclick="downloadGC('development')" id="resourceInstall">Download</button>
<button class="smolBtn" onclick="downloadResources()" id="resourceInstall">Download</button>
</div>
<span class="downloadSubtitle" id="resourceSubtitle">
Downloads Grasscutter resources into the currently set Grasscutter folder. This should be done unless you plan on getting resources externally.
</span>
</div>
<div class="downloadRow">
<div class="downloadSection">
<span class="downloadLabel" id="downloadData">Download Data Files</span>
<button class="smolBtn" onclick="downloadDataFiles()" id="dataInstall">Download</button>
</div>
<span class="downloadSubtitle" id="dataSubtitle">
Downloads Grasscutter data files, such as keys, spawns, and other vital files.
</span>
</div>
</div>
</div>
@ -236,6 +263,13 @@
Choose between using HTTPS or HTTP.
</span>
</div>
<div class="settingsRow">
<div class="settingSection">
<span class="settingLabel", id="debugTitle">Debugging</span>
<input type="checkbox" id="debugOption" onchange="toggleDebugging()" />
</select>
</div>
</div>
</div>
</div>
@ -243,7 +277,7 @@
<div id="controlBar">
<span id="titleSection">
GrassClipper
<span id="version">0.4.5</span>
<span id="version">0.0.0</span>
</span>
<div id="refreshBtn" onclick="window.location.reload()">
<img src="icons/refresh.svg" />

23
resources/js/alerts.js Normal file
View File

@ -0,0 +1,23 @@
function displayAlert(message, clear = 4000) {
const alert = document.getElementById('alert')
const alertText = document.getElementById('alertText')
alert.classList.add('show')
alertText.innerText = message
debug.log('Displaying message: ' + message)
setTimeout(() => {
hideAlert()
}, clear)
}
function hideAlert() {
const alert = document.getElementById('alert')
const alertText = document.getElementById('alertText')
debug.log('Hiding alert')
alert.classList.remove('show')
}

View File

@ -1,14 +1,16 @@
let alertTimeout, alertCooldown = 3000
async function displayLoginAlert(message, type, cooldown = null) {
displayAlert(message, type, cooldown, 'login')
displayAuthAlert(message, type, cooldown, 'login')
debug.log('Login alert: ' + message)
}
async function displayRegisterAlert(message, type, cooldown = null) {
displayAlert(message, type, cooldown, 'register')
displayAuthAlert(message, type, cooldown, 'register')
debug.log('Register alert: ' + message)
}
function displayAlert(message, type, cooldown, name) {
function displayAuthAlert(message, type, cooldown, name) {
const elm = document.getElementById(`${name}Alert`)
const text = document.getElementById(`${name}AlertText`)
@ -41,5 +43,7 @@ function displayAlert(message, type, cooldown, name) {
// Disappear after cooldown
alertTimeout = setTimeout(() => {
elm.style.display = 'none'
debug.log('Hiding auth alert')
}, cooldown || alertCooldown)
}

3
resources/js/axios.min.js vendored Normal file

File diff suppressed because one or more lines are too long

17
resources/js/debug.js Normal file
View File

@ -0,0 +1,17 @@
const debug = {
log: async (...args) => {
const cfg = await getCfg()
if (cfg.debug) console.log('[DEBUG] ', ...args)
},
warn: async (...args) => {
const cfg = await getCfg()
if (cfg.debug) console.log('[WARNING] ', ...args)
},
error: async (...args) => {
const cfg = await getCfg()
if (cfg.debug) console.log('[ERROR] ', ...args)
}
}

View File

@ -1,13 +1,8 @@
async function clearGCInstallation() {
Neutralino.os.execCommand('del /s /q "./gc"')
}
async function setDownloadButtonsToLoading() {
const stableBtn = document.querySelector('#stableInstall')
const devBtn = document.querySelector('#devInstall')
stableBtn.innerText = localeObj.gcScriptRunning || 'Running...'
devBtn.innerText = localeObj.gcScriptRunning || 'Running...'
// Set btns to disabled
@ -16,6 +11,8 @@ async function setDownloadButtonsToLoading() {
devBtn.disabled = true
devBtn.classList.add('disabled')
debug.log('Set download buttons to loading')
}
async function resetDownloadButtons() {
@ -31,72 +28,122 @@ async function resetDownloadButtons() {
devBtn.disabled = false
devBtn.classList.remove('disabled')
debug.log('Reset download buttons')
}
async function downloadGC(branch) {
async function downloadDataFiles(branch) {
const config = await getCfg()
// If we are pulling from a new branch, delete the old installation
if (config.grasscutterBranch !== branch) await clearGCInstallation()
if (!branch) {
debug.warn('Branch not specified')
branch = config.grasscutterBranch || 'development'
}
// Set current installation in config
config.grasscutterBranch = branch
// Set gc path for people with launcher enabled
config.serverFolder = `${NL_CWD}/gc-${branch}/grasscutter.jar`
// Enable server launcher
config.serverLaunchPanel = true
Neutralino.storage.setData('config', JSON.stringify(config))
debug.log('Using branch: ' + branch)
setDownloadButtonsToLoading()
// Keystore for branch (since they can differ)
const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12`
// External service that allows un-authed artifact downloading
const artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip`
// For data files
const dataFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/data?ref=${branch}`)
const dataList = dataFiles.data
.map(file => ({ path: file.path, filename: file.name }))
.map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename }))
debug.log('Downloaded data files')
// For key files
const keyFiles = await axios.get(`https://api.github.com/repos/Grasscutters/Grasscutter/contents/keys?ref=${branch}`)
const keyList = keyFiles.data
.map(file => ({ path: file.path, filename: file.name }))
.map(o => ({ url: `https://raw.githubusercontent.com/Grasscutters/Grasscutter/${branch}/${o.path}`, filename: o.filename }))
debug.log('Downloaded key files')
const serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\')
// Ensure data and key folders exist
debug.log('Server folder fixed: ' + serverFolderFixed)
await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\data`)
await Neutralino.os.execCommand(`mkdir ${serverFolderFixed}\\keys`)
debug.log('Created data and keys folders')
// Download data files
for (const o of dataList) {
const folder = 'data'
await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`)
const e = await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`)
debug.log(e)
}
// Download key files
for (const o of keyList) {
const folder = 'keys'
await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`)
const e = await Neutralino.os.execCommand(`powershell Invoke-WebRequest -Uri ${o.url} -OutFile "${serverFolderFixed}\\${folder}\\${o.filename}"`)
debug.log(e)
}
// Fix buttons
resetDownloadButtons()
}
async function downloadGC(branch) {
const config = await getCfg()
// Set current installation in config
config.grasscutterBranch = branch
debug.log('Branch set to: ' + branch)
// Set gc path for people with launcher enabled
config.serverFolder = `${NL_CWD}\\gc-${branch}\\grasscutter.jar`
debug.log('Server folder automatically set to: ' + config.serverFolder)
// Enable server launcher
config.serverLaunchPanel = true
Neutralino.storage.setData('config', JSON.stringify(config))
// Download data files
downloadDataFiles(branch)
// External service that allows un-authed artifact downloading
let artiUrl = `https://nightly.link/Grasscutters/Grasscutter/workflows/build/${branch}/Grasscutter.zip`
await axios.get(artiUrl).catch(e => {
// Fallback link if artifacts are not being uploaded
debug.warn('Artifacts not available for latest, falling back...')
artiUrl = 'https://nightly.link/Grasscutters/Grasscutter/actions/runs/2284467925/Grasscutter.zip'
})
debug.log('Artifact URL: ' + artiUrl)
// Keystore for branch (since they can differ)
const keystoreUrl = `https://github.com/Grasscutters/Grasscutter/raw/${branch}/keystore.p12`
// Run installer
createCmdWindow(`.\\scripts\\gc_download.cmd ${artiUrl} ${keystoreUrl} ${branch}`)
// Fix buttons
resetDownloadButtons()
debug.log('Created installer window')
// Display folder after saving config
displayServerFolder()
enableServerButton()
displayServerLaunchSection()
}
async function downloadResources() {
const config = await getCfg()
let serverFolderFixed = config.serverFolder.match(/.*\\|.*\//g, '')[0].replace(/\//g, '\\')
// Remove trailing slash, it's important here
serverFolderFixed = serverFolderFixed.endsWith('\\') ? serverFolderFixed.slice(0, -1) : serverFolderFixed
debug.log('Server folder fixed: ' + serverFolderFixed)
// Dont bother with data or keys, just want straight resources
createCmdWindow(`.\\scripts\\resources_download.cmd "${serverFolderFixed}"`)
debug.log('Created resources window')
}

View File

@ -12,6 +12,7 @@ async function getCfg() {
serverLaunchPanel: false,
language: 'en',
useHttps: true,
debug: true,
grasscutterBranch: '',
}
const cfgStr = await Neutralino.storage.getData('config').catch(e => {
@ -20,6 +21,8 @@ async function getCfg() {
// Show the first time notice if there is no config
document.querySelector('#firstTimeNotice').style.display = 'block'
debug.warn('First time opening')
})
const config = cfgStr ? JSON.parse(cfgStr) : defaultConf
@ -36,8 +39,12 @@ async function getFavIps() {
const ipStr = await Neutralino.storage.getData('favorites').catch(e => {
// The data isn't set, so this is our first time opening
Neutralino.storage.setData('favorites', JSON.stringify([]))
debug.warn('No favorites set')
})
debug.log('Favorites:', ipStr)
const ipArr = ipStr ? JSON.parse(ipStr) : []
return ipArr
@ -50,20 +57,27 @@ async function proxyIsInstalled() {
if (curDirList.find(f => f.entry === 'ext')) {
const extFiles = await filesystem.readDirectory(NL_CWD + '/ext')
debug.log('ext/ folder exists')
if (extFiles.find(f => f.entry === 'mitmdump.exe')) {
debug.log('mitmdump exists')
return true
}
}
debug.log('No proxy installed')
return false
}
async function checkForUpdates() {
const url = 'https://api.github.com/repos/Grasscutters/GrassClipper/releases/latest'
const { data } = await axios.get(url)
const { data } = await axios.get(url).catch(e => debug.error('Error getting latest release'))
const latest = data.tag_name
debug.log('Latest release:', latest)
return latest
}
@ -72,8 +86,12 @@ async function displayUpdate() {
const versionDisplay = document.querySelector('#newestVersion')
const notif = document.querySelector('#downloadNotif')
debug.log('Comparing versions: ' + latest + ' vs v' + NL_APPVERSION)
if (latest === `v${NL_APPVERSION}`) return
debug.log('New version available')
versionDisplay.innerText = latest
notif.classList.add('displayed')
@ -86,28 +104,87 @@ async function displayUpdate() {
async function openLatestDownload() {
const downloadLink = 'https://github.com/Grasscutters/GrassClipper/releases/latest/'
debug.log('Opening download link: ', downloadLink)
Neutralino.os.open(downloadLink)
}
async function openGameFolder() {
const config = await getCfg()
const folder = config.gameexe.match(/.*\\/g, '')[0]
const folder = config.gameexe?.match(/.*\\|.*\//g, '')
openInExplorer(folder)
debug.log('Opening game folder: ', folder)
if (folder?.length > 0) openInExplorer(folder[0].replace(/\//g, '\\'))
}
async function openGrasscutterFolder() {
const config = await getCfg()
const folder = config.serverFolder.match(/.*\\|.*\//g, '')[0]
const folder = config.serverFolder?.match(/.*\\|.*\//g, '')
openInExplorer(folder)
debug.log('Opening grasscutter folder: ', folder)
if (folder?.length > 0) openInExplorer(folder[0].replace(/\//g, '\\'))
}
// https://www.jimzhao.us/2015/09/javascript-detect-chinese-character.html
function hasForeignChars(str) {
let re1 = /[^a-z0-9_.,-\\/: ]/g
str = str.replace(/\s/g, '')
debug.log('Checking for foreign chars in path: ', str)
debug.log('Path includes foreign chars? ', re1.test(str))
return re1.test(str)
}
function openDialog(title, message, negBtn = false, affirmBtn = closeDialog) {
const dialog = document.getElementById('miscDialog')
const titleElm = document.getElementById('dialogTitle')
const contents = document.getElementById('dialogContent')
const noBtn = document.getElementById('dialogButtonNeg')
const yesBtn = document.getElementById('dialogButtonAffirm')
debug.log('Opening dialog: ', title, message)
if (!negBtn) {
noBtn.style.display = 'none'
debug.log('No "no" button')
} else {
noBtn.style.removeProperty('display')
noBtn.onclick = () => closeDialog()
}
yesBtn.innerText = localeObj.dialogYes || 'OK'
noBtn.innerText = localeObj.dialogNo || 'NO'
yesBtn.onclick = () => {
debug.log('Affirmative button clicked')
affirmBtn()
closeDialog()
}
// Set title and message
titleElm.innerText = title
contents.innerText = message
// Show the dialog
dialog.style.display = 'block'
}
function closeDialog() {
const dialog = document.getElementById('miscDialog')
debug.log('Closing dialog')
dialog.style.display = 'none'
}
/**
* Minimize the window
*/
function minimizeWin() {
console.log('min')
debug.log('Minimizing window')
Neutralino.window.minimize()
}
@ -115,7 +192,7 @@ function minimizeWin() {
* Close the window
*/
function closeWin() {
console.log('close')
debug.log('Closing window')
Neutralino.app.exit()
window.close()

View File

@ -1,13 +1,14 @@
Neutralino.init()
NL_CWD = NL_CWD.replace(/\//g, '\\')
let localeObj
const filesystem = Neutralino.filesystem
const createCmdWindow = async (command) => {
debug.log('Running command in new window: ' + command)
Neutralino.os.execCommand(`cmd.exe /c start "" ${command}`, { background: true })
}
const openInExplorer = async (path) => {
console.log(`explorer.exe "${path}"`)
debug.log('Opening path in explorer: ' + path)
createCmdWindow(`explorer.exe "${path}"`)
}
@ -18,6 +19,8 @@ async function enableButtons() {
const offBtn = document.querySelector('#playOfficial')
const privBtn = document.querySelector('#playPrivate')
debug.log('Enabling buttons')
offBtn.classList.remove('disabled')
offBtn.disabled = false
@ -34,6 +37,8 @@ async function enableButtons() {
async function enableServerButton() {
const serverBtn = document.querySelector('#serverLaunch')
debug.log('Enabling server button')
serverBtn.classList.remove('disabled')
serverBtn.disabled = false
}
@ -43,7 +48,9 @@ async function enableServerButton() {
*/
async function handleGameNotSet() {
// Set buttons to greyed out and disable
document.querySelector('#gamePath').innerHTML = localeObj.folderNotSet
document.querySelector('#gamePath').innerHTML = localeObj.folderNotSet || 'Not set'
debug.log('Handling game not set')
// Set official server background to default
document.querySelector('#firstPanel').style.backgroundImage = 'url("../bg/private/default.png")'
@ -62,7 +69,9 @@ async function handleGameNotSet() {
async function handleServerNotSet() {
// Set buttons to greyed out and disable
document.querySelector('#serverPath').innerHTML = localeObj.folderNotSet
document.querySelector('#serverPath').innerHTML = localeObj.folderNotSet || 'Not set'
debug.log('Handling server not set')
// Set official server background to default
// document.querySelector('#firstPanel').style.backgroundImage = `url("../bg/private/default.png")`
@ -80,6 +89,8 @@ async function displayGameFolder() {
const elm = document.querySelector('#gamePath')
const config = await getCfg()
debug.log('Displaying game exe')
elm.innerHTML = config.gameexe
}
@ -90,6 +101,8 @@ async function displayServerFolder() {
const elm = document.querySelector('#serverPath')
const config = await getCfg()
debug.log('Displaying server folder')
elm.innerHTML = config.serverFolder
}
@ -108,9 +121,13 @@ async function setBackgroundImage() {
// Set default image, it will change if the bg folder exists
document.querySelector('#firstPanel').style.backgroundImage = 'url("https://webstatic.hoyoverse.com/upload/event/2020/11/04/7fd661b5184e1734f91f628b6f89a31f_7367318474207189623.png")'
debug.log('Setting second panel to: ' + privImage)
// Set the private background image
document.querySelector('#secondPanel').style.backgroundImage = `url("../bg/private/${privImage}")`
debug.log('Setting third panel to: ' + servImage)
// Set the server background image
document.querySelector('#thirdPanel').style.backgroundImage = `url("../bg/server/${servImage}")`
@ -177,6 +194,8 @@ async function handleFavoriteInput() {
const addr = `${ip}:${port}`
debug.log('Checking if IP is a favorite: ' + addr)
if (!ip || !ipArr.includes(addr)) {
document.querySelector('#star').src = 'icons/star_empty.svg'
} else {
@ -196,6 +215,8 @@ async function setIp(ip) {
const parseIp = ip.split(':')[0]
const parsePort = ip.split(':')[1]
debug.log('Setting IP input elm to: ' + parseIp + ' and port to: ' + parsePort)
// Set star
if (ip) {
document.querySelector('#star').src = 'icons/star_filled.svg'
@ -213,6 +234,8 @@ async function handleFavoriteList() {
const ipList = document.querySelector('#ipList')
if (ipList.style.display === 'none') {
debug.log('IP list was closed, opening it')
ipList.innerHTML = ''
const list = ipList.appendChild(
@ -220,11 +243,12 @@ async function handleFavoriteList() {
)
if (ipArr.length < 1) {
console.log('No favorites found')
const listItem = list.appendChild(
document.createElement('li')
)
listItem.innerHTML = localeObj.noFavorites
listItem.innerHTML = localeObj.noFavorites || 'No favorites set'
}
for (const ip of ipArr) {
@ -240,6 +264,8 @@ async function handleFavoriteList() {
const xy = [ transform.split(',')[4], transform.split(',')[5] ]
let newY = (27 * ipArr.length) * window.devicePixelRatio
debug.log('IP list height: 56vh - ' + newY)
if (ipArr.length === 0 || ipArr.length === 1) newY = 0
ipList.style.transform = `translate(${xy[0]}px, calc(56vh - ${newY}px)`
@ -250,23 +276,37 @@ async function openDownloads() {
const downloads = document.querySelector('#downloadPanel')
const config = await getCfg()
debug.log('Opening downloads panel')
if (downloads.style.display === 'none') {
downloads.style.removeProperty('display')
}
// Disable the resource download button if a serverFolder path is not set
if (!config.serverFolder) {
debug.log('Server folder not set, disabling resource download button and data download button')
document.querySelector('#resourceInstall').disabled = true
document.querySelector('#resourceInstall').classList.add('disabled')
// Disable data installer
document.querySelector('#dataInstall').disabled = true
document.querySelector('#dataInstall').classList.add('disabled')
} else {
debug.log('Server folder is set, enabling resource download button and data download button')
document.querySelector('#resourceInstall').disabled = false
document.querySelector('#resourceInstall').classList.remove('disabled')
// Enable data installer
document.querySelector('#dataInstall').disabled = false
document.querySelector('#dataInstall').classList.remove('disabled')
}
}
async function closeDownloads() {
const downloads = document.querySelector('#downloadPanel')
debug.log('Closing downloads panel')
downloads.style.display = 'none'
}
@ -274,6 +314,8 @@ async function openSettings() {
const settings = document.querySelector('#settingsPanel')
const config = await getCfg()
debug.log('Opening settings panel')
if (settings.style.display === 'none') {
settings.style.removeProperty('display')
}
@ -287,6 +329,10 @@ async function openSettings() {
serverLaunch.checked = config.serverLaunchPanel
httpsCheckbox.checked = config.useHttps
debug.log('Set killswitch to: ' + config.enableKillswitch)
debug.log('Set server launch to: ' + config.serverLaunchPanel)
debug.log('Set https to: ' + config.useHttps)
// Load languages
getLanguages()
@ -298,10 +344,14 @@ async function closeSettings() {
const settings = document.querySelector('#settingsPanel')
const config = await getCfg()
debug.log('Closing settings panel')
settings.style.display = 'none'
// In case we installed the proxy server
if (await proxyIsInstalled() && config.gameexe) {
debug.log('Proxy has been installed and EXE is set, enabling playPrivate')
const playPriv = document.querySelector('#playPrivate')
playPriv.classList.remove('disabled')
@ -320,19 +370,28 @@ async function openLogin() {
const useHttps = config.useHttps
const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}`
debug.log('Opening login panel')
debug.log('Url: ' + url)
// Check if we even need to authenticate
try {
const { data } = await axios.get(url + '/authentication/type')
debug.log('Request successful')
if (!data.includes('GCAuthAuthenticationHandler')) {
debug.log('No authentication required')
launchPrivate()
return
}
} catch(e) {
debug.warn('Request failed')
launchPrivate()
return
}
debug.log('Login panel opening')
loginIpDisplay.innerText = ip
registerIpDisplay.innerText = ip
@ -344,6 +403,8 @@ async function openLogin() {
async function closeLogin() {
const login = document.querySelector('#loginPanel')
debug.log('Closing login panel')
login.style.display = 'none'
setLoginSection()
@ -351,16 +412,22 @@ async function closeLogin() {
async function closeFirstTimePopup() {
const firstTimePopup = document.querySelector('#firstTimeNotice')
debug.log('Closing first time popup')
firstTimePopup.style.display = 'none'
}
async function runInstallScript() {
debug.log('Running install script')
createCmdWindow(`.\\scripts\\install.cmd "${NL_CWD}" true`)
// Create an interval that will check for the proxy server installation finish
const interval = setInterval(async () => {
debug.log('Checking if proxy server is installed')
if (await proxyIsInstalled()) {
clearInterval(interval)
debug.log('Proxy server installed')
enableButtons()
}
}, 1000)
@ -380,9 +447,11 @@ async function checkForUpdatesAndShow() {
// Version mismatch? Update!
if (manifest?.version !== NL_APPVERSION) {
debug.log('New update available')
subtitle.innerHTML = 'New update available!'
updateBtn.classList.remove('disabled')
} else {
debug.log('New update not available')
subtitle.innerHTML = 'You are on the latest version! :)'
updateBtn.classList.add('disabled')
}
@ -392,10 +461,14 @@ async function displayServerLaunchSection() {
const serverPanel = document.querySelector('#thirdPanel')
const bottomBtnSection = document.querySelector('#serverPath').parentElement
debug.log('Displaying server launch section')
if (serverPanel.style.display === 'none') {
debug.log('Showing server launch section')
serverPanel.style.removeProperty('display')
bottomBtnSection.style.removeProperty('display')
} else {
debug.log('Hiding server launch section')
serverPanel.style.display = 'none'
bottomBtnSection.style.display = 'none'
}
@ -405,13 +478,16 @@ async function displayServerLaunchSection() {
* Set the game folder by opening a folder picker
*/
async function setGameExe() {
const gameExe = await Neutralino.os.showOpenDialog(localeObj.gameFolderDialog, {
const gameExe = await Neutralino.os.showOpenDialog(localeObj.gameFolderDialog || 'Select game folder', {
filters: [
{ name: 'Executable files', extensions: ['exe'] }
]
})
debug.log('Game exe selected: ' + gameExe[0])
if (!gameExe[0]) return
if (hasForeignChars(gameExe[0])) displayAlert(localeObj.foreignCharacterAlert || 'The file path set contains foreign characters, this may cause problems!')
// Set the folder in our configuration
const config = await getCfg()
@ -419,6 +495,8 @@ async function setGameExe() {
// It's an array of selections, so only get the first one
config.gameexe = gameExe[0].replace(/\//g, '\\')
debug.log('Setting game exe to: ' + config.gameexe)
Neutralino.storage.setData('config', JSON.stringify(config))
// Refresh background and path
@ -428,18 +506,24 @@ async function setGameExe() {
}
async function setGrasscutterFolder() {
const folder = await Neutralino.os.showOpenDialog(localeObj.grasscutterFileDialog, {
const folder = await Neutralino.os.showOpenDialog(localeObj?.grasscutterFileDialog || 'Select Grasscutter server jar file', {
filters: [
{ name: 'Jar files', extensions: ['jar'] }
]
})
debug.log('Grasscutter folder selected: ' + folder[0])
if (!folder[0]) return
if (hasForeignChars(folder[0])) displayAlert(localeObj.foreignCharacterAlert || 'The file path set contains foreign characters, this may cause problems!')
// Set the folder in our configuration
const config = await getCfg()
config.serverFolder = folder[0]
debug.log('Setting grasscutter folder to: ' + config.serverFolder)
Neutralino.storage.setData('config', JSON.stringify(config))
displayServerFolder()
@ -452,6 +536,8 @@ async function setGrasscutterFolder() {
async function launchOfficial() {
const config = await getCfg()
debug.log('Launching game at ' + config.gameexe)
Neutralino.os.execCommand(`"${config.gameexe}"`)
}
@ -464,18 +550,24 @@ async function launchPrivate() {
const config = await getCfg()
console.log('connecting to ' + ip + ':' + port)
debug.log('Connecting to ' + ip + ':' + port)
// Set the last connect
config.lastConnect = ip
Neutralino.storage.setData('config', JSON.stringify(config))
// Pass IP and game folder to the private server launcher
createCmdWindow(`.\\scripts\\private_server_launch.cmd ${ip} ${port} ${config.useHttps} "${config.gameexe}" "${NL_CWD}" ${config.enableKillswitch} true`).catch(e => console.log(e))
Neutralino.os.execCommand(
`.\\scripts\\private_server_launch.cmd ${ip} ${port} ${config.useHttps} "${config.gameexe}" "${NL_CWD}" ${config.enableKillswitch} true`, {
background: true
}
).catch(e => debug.error(e))
}
async function launchLocalServer() {
const config = await getCfg()
debug.log('Launching local server')
createCmdWindow(`.\\scripts\\local_server_launch.cmd "${config.serverFolder}"`).catch(e => console.log(e))
}

2
resources/js/init.js Normal file
View File

@ -0,0 +1,2 @@
// This file is the very first loaded when the app is started.
Neutralino.init()

View File

@ -7,6 +7,8 @@ async function setLoginSection() {
const loginSection = document.getElementById('loginPopupContentBody')
const registerSection = document.getElementById('registerPopupContentBody')
debug.log('Setting to login section')
title.classList.add('selectedTitle')
altTitle.classList.remove('selectedTitle')
@ -23,6 +25,8 @@ async function setRegisterSection(fromLogin = false) {
const loginSection = document.getElementById('loginPopupContentBody')
const registerSection = document.getElementById('registerPopupContentBody')
debug.log('Setting to register section')
title.classList.add('selectedTitle')
altTitle.classList.remove('selectedTitle')
@ -30,6 +34,8 @@ async function setRegisterSection(fromLogin = false) {
registerSection.style.removeProperty('display')
if (fromLogin) {
debug.log('Just registered, setting to login page')
// Take the values from the login section and put them in the register section
const loginUsername = document.getElementById('loginUsername').value
const loginPassword = document.getElementById('loginPassword').value
@ -42,6 +48,9 @@ async function setRegisterSection(fromLogin = false) {
function parseJwt(token) {
const base64Url = token.split('.')[1]
const base64 = base64Url.replace('-', '+').replace('_', '/')
debug.log('Parsed JWT: ' + base64)
return JSON.parse(window.atob(base64))
}
@ -57,12 +66,14 @@ async function login() {
const useHttps = config.useHttps
const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}`
debug.log('Attempting login to ' + url)
const reqBody = {
username,
password,
}
const { data } = await axios.post(url + '/authentication/login', reqBody)
const { data } = await axios.post(url + '/authentication/login', reqBody).catch(e => debug.error('Login request failed: ' + e))
switch(data.message) {
case 'INVALID_ACCOUNT':
@ -92,6 +103,8 @@ async function login() {
const tkData = parseJwt(data.jwt)
await Neutralino.clipboard.writeText(tkData.token)
debug.log('Login success')
displayLoginAlert(localeObj.alertLoginSuccess || 'Login successful! Token copied to clipboard. Paste this token into the username field of the game to log in.', 'success', 8000)
launchPrivate()
break
@ -111,13 +124,15 @@ async function register() {
const useHttps = config.useHttps
const url = `${useHttps ? 'https' : 'http'}://${ip}:${port}`
debug.log('Attempting registration to ' + url)
const reqBody = {
username,
password,
password_confirmation
}
const { data } = await axios.post(url + '/authentication/register', reqBody)
const { data } = await axios.post(url + '/authentication/register', reqBody).catch(e => debug.error('Registration request failed: ' + e))
switch(data.message) {
case 'USERNAME_TAKEN':
@ -147,6 +162,8 @@ async function register() {
const loginUsername = document.getElementById('loginUsername')
loginUsername.value = username
debug.log('Registered with username ' + username)
setLoginSection()
displayLoginAlert(localeObj.alertRegisterSuccess || 'Registration successful!', 'success', 5000)
break

View File

@ -7,6 +7,8 @@ async function toggleKillSwitch() {
config.enableKillswitch = killSwitch.checked
debug.log('Killswitch is now ', config.enableKillswitch)
Neutralino.storage.setData('config', JSON.stringify(config))
}
@ -18,9 +20,25 @@ async function toggleServerLaunchSection() {
displayServerLaunchSection()
debug.log('Toggling server panel')
// Save setting
config.serverLaunchPanel = !config.serverLaunchPanel
Neutralino.storage.setData('config', JSON.stringify(config))
// Show a dialog for those who may want to open the downloads section
if (config.serverLaunchPanel && !config.serverFolder) {
closeSettings()
debug.log('First time server launcher')
openDialog(
localeObj.serverEnableDialogTitle || 'You found the Grasscutter server launcher!',
localeObj.serverEnableDialogText || 'If you do not have an existing Grasscutter installation to set, would you like to download a build?',
true,
openDownloads
)
}
}
/**
@ -30,6 +48,8 @@ async function getLanguages() {
const languageFiles = (await filesystem.readDirectory(`${NL_CWD}/languages`)).filter(file => file.entry.endsWith('.json'))
const config = await getCfg()
debug.log('Grabbing languages')
// Clear language options
const languageSelect = document.querySelector('#languageSelect')
languageSelect.innerHTML = ''
@ -39,12 +59,15 @@ async function getLanguages() {
const fullLanguageName = JSON.parse(await filesystem.readFile(`${NL_CWD}/languages/${file.entry}`)).fullLangName
const lang = file.entry.split('.json')[0]
debug.log('Loading language: ', lang)
const option = document.createElement('option')
option.value = lang
option.innerHTML = fullLanguageName
// Set language selected to config language
if (lang === config.language) {
debug.log('Selected language: ', lang)
option.selected = true
}
@ -65,6 +88,8 @@ async function handleLanguageChange(elm) {
config.language = list.value
Neutralino.storage.setData('config', JSON.stringify(config))
debug.log('Language changed to: ', list.value)
// Force refresh of application, no need for restart!
window.location.reload()
}
@ -78,6 +103,22 @@ async function toggleHttps() {
config.useHttps = httpsCheckbox.checked
debug.log('HTTPS set to: ', config.useHttps)
Neutralino.storage.setData('config', JSON.stringify(config))
}
/**
* Toggle debugging
*/
async function toggleDebugging() {
const debugCheckbox = document.querySelector('#debugOption')
const config = await getCfg()
config.debug = debugCheckbox.checked
debug.log('Debugging set to: ', config.debug)
Neutralino.storage.setData('config', JSON.stringify(config))
}
@ -93,12 +134,16 @@ async function setFavorite() {
const addr = `${ip}:${port}`
debug.log('Handling favorite: ', addr)
// Set star icon
const star = document.querySelector('#star')
if (star.src.includes('filled') && ip) {
star.src = 'icons/star_empty.svg'
debug.log('Removing from list: ', addr)
// remove from list
ipArr.splice(ipArr.indexOf(addr), 1)
} else {
@ -106,6 +151,7 @@ async function setFavorite() {
// add to list
if (ip && !ipArr.includes(addr)) {
debug.log('Adding to list: ', addr)
ipArr.push(addr)
}
}

View File

@ -38,8 +38,8 @@ async function doTranslation() {
set('grasscutterFileSet', 'grasscutterFileSet')
// Private options
document.querySelector('#ip').placeholder = localeObj.ipPlaceholder
document.querySelector('#port').placeholder = localeObj.portPlaceholder
document.querySelector('#ip').placeholder = localeObj.ipPlaceholder || 'IP Address'
document.querySelector('#port').placeholder = localeObj.portPlaceholder || 'Port'
// Settings
set('fullSettingsTitle', 'settingsTitle')
@ -58,6 +58,7 @@ async function doTranslation() {
set('serverSubtitle', 'enableServerLauncherSubtitle')
set('httpsTitle', 'httpsOption')
set('httpsSubtitle', 'httpsSubtitle')
set('debugTitle', 'debugOption')
// Intro popup
const popup = document.getElementById('firstTimeNotice')
@ -100,6 +101,8 @@ async function doTranslation() {
set('stableSubtitle', 'stableSubtitle')
set('downloadDev', 'downloadDev')
set('devSubtitle', 'devSubtitle')
set('dataSubtitle', 'dataSubtitle')
set('downloadData', 'downloadData')
set('downloadResources', 'downloadResources')
set('resourceSubtitle', 'resourceSubtitle')
set('stableInstall', 'stableInstall')

View File

@ -35,6 +35,7 @@ img {
margin: 10px;
}
#miscDialog span,
#firstTimeNotice span {
display: block;
text-align: center;
@ -159,6 +160,7 @@ img {
margin: 10px;
}
#miscDialog,
#firstTimeNotice,
#loginPanel,
#downloadPanel,
@ -601,3 +603,42 @@ img {
#newestVersion {
font-weight: bold;
}
#alert {
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
color: #704a1d;
position: absolute;
top: -100%;
left: 15%;
background: linear-gradient(#ffc61e, #ffd326);
border: 1px solid #704a1d;
border-radius: 6px;
height: 50px;
width: 70%;
z-index: 999;
transition: top 0.15s ease-in-out;
}
#alert.show {
top: 6%;
}
#dialogTitle {
font-weight: bold;
}
#dialogBtns {
display: flex;
justify-content: space-around;
align-items: center;
width: 100%;
margin: 0.6em;
}

View File

@ -14,14 +14,14 @@ if not exist ".\temp" mkdir ".\temp"
echo Downloading Grasscutter prebuilt jar...
:: Download the jar
powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile "./temp/gcjar.zip"
powershell Invoke-WebRequest -Uri %KEYSTORE_URL% -OutFile ".\temp\gcjar.zip"
echo Extracting...
:: Delete old file if there is one there
if exist "%FOLDER_NAME%\grasscutter.jar" del "%FOLDER_NAME%\grasscutter.jar"
powershell Expand-Archive -Path "./temp/gcjar.zip" -DestinationPath "%FOLDER_NAME%" -Force
powershell Expand-Archive -Path ".\temp\gcjar.zip" -DestinationPath "%FOLDER_NAME%" -Force
:: Find the jar file name and rename it, just in case
for %%i in (%FOLDER_NAME%/*) do (
@ -32,7 +32,7 @@ for %%i in (%FOLDER_NAME%/*) do (
echo Downloading keystore.p12...
:: Download the keystore.p12 file
powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile "./%FOLDER_NAME%/keystore.p12"
powershell Invoke-WebRequest -Uri %ARTIFACT_URL% -OutFile ".\%FOLDER_NAME%\keystore.p12"
:: Check java version, this will automatically output some tuff
call .\scripts\javaver.cmd %BRANCH%

View File

@ -14,19 +14,19 @@ if not exist "%ORIGIN%/ext" mkdir "%ORIGIN%/ext"
if not exist "%ORIGIN%/temp" mkdir "%ORIGIN%/temp
:: Begin by retrieving mitmproxy 7.0.4
powershell Invoke-WebRequest -Uri https://snapshots.mitmproxy.org/7.0.4/mitmproxy-7.0.4-windows.zip -OutFile "'%ORIGIN%/temp/mitmproxy-7.0.4-windows.zip'"
powershell Invoke-WebRequest -Uri https://snapshots.mitmproxy.org/7.0.4/mitmproxy-7.0.4-windows.zip -OutFile "'%ORIGIN%\temp\mitmproxy-7.0.4-windows.zip'"
echo Extracting...
:: Extract from temp/ to ext/ with powershell
powershell Expand-Archive -Path "'%ORIGIN%/temp/mitmproxy-7.0.4-windows.zip'" -DestinationPath "'%ORIGIN%/ext/'" -Force
powershell Expand-Archive -Path "'%ORIGIN%\temp\mitmproxy-7.0.4-windows.zip'" -DestinationPath "'%ORIGIN%\ext\'" -Force
del /s /q "%ORIGIN%/temp"
echo Running proxy server in order to generate certificates...
:: Start proxy server
start "Proxy Server" "%ORIGIN%/ext/mitmdump.exe" --ssl-insecure --set ip=%ip%
start "Proxy Server" "%ORIGIN%\ext\mitmdump.exe" --ssl-insecure --set ip=%ip%
:: Allow the proxy server to create the certificates
ping 127.0.0.1 -n 6 > nul
@ -51,3 +51,4 @@ echo Done! You can now open GrassClipper.exe!
pause
taskkill /f /fi "WINDOWTITLE eq Grassclipper Installer"
taskkill /f /fi "WINDOWTITLE eq Administrator: Grassclipper Installer"

View File

@ -9,14 +9,7 @@ if %errorlevel%==1 (
echo =======================================================================================
echo No version of Java was found!
if %BRANCH% EQU stable (
echo To launch the stable branch server, you must install Java 8
)
if %BRANCH% EQU development (
echo To launch the development branch server, you must install Java 17
)
echo To launch the server, you must install Java 17
echo =======================================================================================
exit /b
@ -35,36 +28,13 @@ for /f "delims=. tokens=1-3" %%v in ("%JAVAVER%") do (
set BUILD=%%x
)
if %BRANCH% EQU stable (
:: Ensure java 8
if %MAJOR% EQU 1 (
if %MINOR% LSS 8 (
:: Ensure java 17
if "%MAJOR%" NEQ "17" (
echo =======================================================================================
echo !! Java version is less than 8 !!
echo Please download Java 8 to ensure %BRANCH% branch server launches correctly.
echo !! Java version is not 17 !!
echo Please download Java 17 or later to ensure %BRANCH% branch server launches correctly.
echo =======================================================================================
exit /b
)
)
if %MAJOR% NEQ 1 (
echo =======================================================================================
echo !! Java version is not 8 !!
echo Please download Java 8 to ensure %BRANCH% branch server launches correctly.
echo =======================================================================================
exit /b
)
)
if %BRANCH% EQU development (
:: Ensure java 17
if %MAJOR% LSS 17 (
echo =======================================================================================
echo !! Java version is less than 17 !!
echo Please download Java 17 to ensure %BRANCH% branch server launches correctly.
echo =======================================================================================
exit /b
)
)
echo Java version is compatible

View File

@ -22,6 +22,9 @@ if "%PROXY_IP%" EQU "localhost" (
)
:loop
:: Wait a couple seconds
ping 127.0.0.1 -n 2 > nul
:: Check if the game is even running
:: tasklist /fi "ImageName eq %GAME_EXE_NAME%" /fo csv 2>NUL | find /I "%GAME_EXE_NAME%.exe">NUL
:: IF %ERRORLEVEL% NEQ 0 (
@ -32,6 +35,7 @@ if "%PROXY_IP%" EQU "localhost" (
:: https://stackoverflow.com/questions/162291/how-to-check-if-a-process-is-running-via-a-batch-script
tasklist /fi "ImageName eq mitmdump.exe" /fo csv 2>NUL | find /I "mitmdump.exe">NUL
if "%ERRORLEVEL%" NEQ "0" (
echo "mitmdump not running"
goto killgame
)
@ -62,8 +66,6 @@ if "%PROXY_IP%" EQU "localhost" (
goto killgame
)
ping 127.0.0.1 -n 2 > nul
goto loop
:killgame

View File

@ -26,4 +26,4 @@ echo Starting local Grasscutter server...
:: Change dir to server directory
cd /d "%GRASSCUTTER_ROOT%"
call java -jar %GRASSCUTTER_JAR%
call java -jar "%GRASSCUTTER_JAR%"

View File

@ -9,6 +9,9 @@
:: Use to force task kill
title PS Launcher Script
:: Use a character encoding that allows for use of Chinese characters. This should work but doesn't, but I'm keeping it in here just in case
chcp 65001
echo Starting Proxy Server
set IP=%1
@ -41,7 +44,7 @@ reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v Pr
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /d "127.0.0.1:8080" /f >nul 2>nul
:: Start proxy server
start "Proxy Server" "%ORIGIN%\ext\mitmdump.exe" -s "%ORIGIN%/proxy/proxy.py" -k --allow-hosts ".*\.yuanshen\.com|.*\.mihoyo\.com|.*\.hoyoverse\.com" --ssl-insecure --set ip=%IP% --set port=%PORT% --set use_https=%USE_HTTPS%
start "Proxy Server" "%ORIGIN%\ext\mitmdump.exe" -s "%ORIGIN%\proxy\proxy.py" -k --allow-hosts ".*\.yuanshen\.com|.*\.mihoyo\.com|.*\.hoyoverse\.com" --ssl-insecure --set ip=%IP% --set port=%PORT% --set use_https=%USE_HTTPS%
echo Opening %GAME_PATH%
@ -57,7 +60,7 @@ echo Killswitch: %ENABLE_KILLSWITCH%
if "%ENABLE_KILLSWITCH%" EQU "true" (
echo Killswitch is enabled!
:: Start killswitch
start /b %ORIGIN%\scripts\killswitch.cmd "%GAME_EXE%" %IP%
start /b %ORIGIN%\scripts\killswitch.cmd "%GAME_EXE%" 127.0.0.1
)
:: Launch game

View File

@ -4,22 +4,22 @@ set FOLDER_NAME=%1
set FOLDER_NAME=%FOLDER_NAME:"=%
if not exist ".\temp" mkdir ".\temp"
if not exist ".\resources" mkdir ".\resources"
if not exist "%FOLDER_NAME%\resources" mkdir "%FOLDER_NAME%\resources"
echo Downloading resources, this can take a while...
:: Grab the giant ass resource zip
powershell Invoke-WebRequest -Uri https://github.com/Koko-boya/Grasscutter_Resources/archive/refs/heads/main.zip -OutFile "./temp/resources.zip"
powershell Invoke-WebRequest -Uri https://github.com/Koko-boya/Grasscutter_Resources/archive/refs/heads/main.zip -OutFile ".\temp\resources.zip"
echo Extracting...
:: Extract resources to the folder
powershell Expand-Archive -Path "./temp/resources.zip" -DestinationPath "%FOLDER_NAME%" -Force
powershell Expand-Archive -Path ".\temp\resources.zip" -DestinationPath "%FOLDER_NAME%" -Force
:: Delete old resources folder if there is one there
del /s /q "%FOLDER_NAME%\resources">nul
echo Moving resources to folder...
echo Moving resources to folder (this also takes a bit)...
robocopy "%FOLDER_NAME%\Grasscutter_Resources-main\Resources" "%FOLDER_NAME%\resources" /E /MOVE>nul

View File

@ -3,6 +3,7 @@
set BINARY_URL="https://github.com/SpikeHD/neutralinojs/releases/download/v1337.0.0/neutralino-win_x64.exe"
call npm install
call neu update
:: Use powershell to download the binary
powershell Invoke-WebRequest -Uri %BINARY_URL% -OutFile "./bin/neutralino-win_x64.exe"