Compare commits
241 Commits
Author | SHA1 | Date | |
---|---|---|---|
e201281c36 | |||
cbd81f92f4 | |||
![]() |
f364754092 | ||
8b760e5e9b | |||
3b2bfbb0e6 | |||
2c8691e9ae | |||
![]() |
e6a2d26671 | ||
fafff8090f | |||
![]() |
b37016a49c | ||
6e8c1d4a15 | |||
92f5289576 | |||
![]() |
c62b46850c | ||
3d160f9b90 | |||
79efb9bd51 | |||
ef3c85c6d3 | |||
![]() |
e61fc45ad2 | ||
de53f682f0 | |||
3ddfa189e9 | |||
ddc588c792 | |||
984afbdf0b | |||
56a72ad940 | |||
b62c539bdd | |||
d9272acb44 | |||
5c89eb5a58 | |||
583041c295 | |||
ded10d175f | |||
380682d175 | |||
055bddc22c | |||
5b2442591f | |||
3eb1a08697 | |||
79283f4039 | |||
497b828f2d | |||
41dc3e8fc4 | |||
eb1be4cdb8 | |||
d4655c1e50 | |||
b1debe0aab | |||
f5780a4366 | |||
101e3c5ffc | |||
97b3a57ee1 | |||
0788a32158 | |||
f553ddddd8 | |||
07fb477c3a | |||
f8b920100d | |||
cfdca6f031 | |||
085669e43a | |||
eda70a2aae | |||
c2be92c41b | |||
4bcd23389d | |||
2a51fcb47d | |||
2c2f05c5b2 | |||
ab92469f11 | |||
749f324f7d | |||
1c49c41b71 | |||
1993d3d295 | |||
dce7e54675 | |||
41c644f2af | |||
78be273c7a | |||
c94a7683e4 | |||
b407012bef | |||
bb7d28153f | |||
627d9c7cd2 | |||
53a83fd7a7 | |||
c2ca091662 | |||
738a755353 | |||
dcbd946407 | |||
2a8cebcbb5 | |||
434ec7b2df | |||
c2ff37facf | |||
f48c9b4d0b | |||
1d734479d1 | |||
a989581d59 | |||
6ab9d3842c | |||
b69b2941b6 | |||
90deaa84b4 | |||
403cc3fe52 | |||
dd4eb36c17 | |||
2645e16bee | |||
82668c4c6a | |||
8fce4a8995 | |||
![]() |
4cfbebcc5a | ||
40db4236ba | |||
eef4687ed6 | |||
e9a3f4014e | |||
749aae02ca | |||
fc3fd10081 | |||
65e664f35f | |||
ab9a617619 | |||
f629bc9993 | |||
dc7f48139e | |||
da8c511d60 | |||
eb60f402a4 | |||
c82ce1ea35 | |||
9524ea5ab4 | |||
caf18eaa7a | |||
2cdcb4a599 | |||
![]() |
3407ca61fd | ||
964b7ced8b | |||
![]() |
702267003b | ||
abf970b783 | |||
6855b6299f | |||
b77d242bd9 | |||
01016b1fa1 | |||
b2b656b6cb | |||
aabe6664b4 | |||
![]() |
5869a72645 | ||
df3ab12165 | |||
03fe8909d0 | |||
2ec4bc9333 | |||
c1b89a2b9a | |||
6706525e77 | |||
981b8377d8 | |||
945329d109 | |||
304f3484e3 | |||
47ad6dae6a | |||
0448bb0ea9 | |||
![]() |
5009d148a1 | ||
![]() |
8427103a7e | ||
2767cb44d7 | |||
![]() |
416ffd6435 | ||
ff554ce369 | |||
0698671c05 | |||
67468cf28b | |||
058a6b7ab2 | |||
1ccb3656c2 | |||
6da7e1d4d0 | |||
119c8c87ee | |||
2758b4d896 | |||
d8c7f0ad56 | |||
0d8b51f199 | |||
6e296edf11 | |||
072066ac87 | |||
a359dea603 | |||
29decd4899 | |||
92a5d53d35 | |||
40e33dcb1c | |||
![]() |
2b2757ccff | ||
f57f4097ac | |||
5865441074 | |||
2d916392c1 | |||
dec3b2261f | |||
5b0cb912e4 | |||
5cbdaa7134 | |||
b2f59431a6 | |||
04ec214714 | |||
196b56ab71 | |||
226742776f | |||
f4ec2ee5fa | |||
f33d37cd90 | |||
2394ec7f5d | |||
8baa61b72c | |||
f35ea79475 | |||
46b8ca0b63 | |||
b8cfaf308d | |||
c7d3e5021c | |||
a689b425ca | |||
9bd45157a4 | |||
![]() |
169b8997ec | ||
![]() |
aa6ea882d9 | ||
![]() |
c86b275096 | ||
![]() |
a81985549e | ||
![]() |
f4e9409afa | ||
6647e5bd37 | |||
64b7c25de5 | |||
7c562228c6 | |||
91a194c948 | |||
50a30331e5 | |||
![]() |
da47941564 | ||
![]() |
6e999f92a0 | ||
f4fc0ef3c5 | |||
![]() |
2dc8dc734b | ||
![]() |
98663240de | ||
ba782c85d4 | |||
dea067b21f | |||
d56c73e2a3 | |||
5d208d1220 | |||
47a3a1c7ab | |||
56059b4f4f | |||
09577d5403 | |||
fb77f9432a | |||
0f70405041 | |||
399888f976 | |||
a8a0a14713 | |||
59af1e468d | |||
0d1bad5551 | |||
7eb2ff1624 | |||
72351ba60f | |||
7dc2dcc9db | |||
5b4a7d784d | |||
1d8d199af7 | |||
c4e29dc000 | |||
72ec031f8a | |||
2300b8d5db | |||
7ec81ab146 | |||
cf3ffeb8c6 | |||
118a7fe0f1 | |||
005c68cc5b | |||
70f390c5d7 | |||
65de82a227 | |||
a2494b59f7 | |||
b05269712a | |||
740463f017 | |||
![]() |
30521d068e | ||
c7898401ce | |||
d169de9a9e | |||
74ddb428ee | |||
ba4837f1f8 | |||
cdf25f6b6f | |||
e630c53c9f | |||
db13f82bfc | |||
63ebaa5df8 | |||
7b886ea251 | |||
436c4d809c | |||
6ab7bac20b | |||
![]() |
7f852ffb8e | ||
69e68810ba | |||
a63f79230b | |||
3b01c62ed2 | |||
cdc69d23b9 | |||
92a15afabf | |||
277e265bf1 | |||
473163e7c6 | |||
f1eb40bb0d | |||
6c23915615 | |||
d0361c29aa | |||
9ee1239341 | |||
a2a74980bf | |||
01c7f7d528 | |||
a9c8a667ec | |||
bcfb23a8fb | |||
111a98a916 | |||
784163d816 | |||
ce2a6533f2 | |||
17275e194a | |||
9664c9f11d | |||
8b1e4a3d1a | |||
e7347a1a26 | |||
a4cf38dd71 | |||
c018b23913 | |||
0c003616cb | |||
7bfd6517a7 | |||
42e5c94601 |
32
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
name: Build project
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- Source/**
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- Source/**
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup MSBuild.exe
|
||||||
|
uses: microsoft/setup-msbuild@v1.1.3
|
||||||
|
|
||||||
|
- name: Build release
|
||||||
|
run: msbuild Source/GrasscutterTools.sln /p:Configuration=Release /t:build /restore
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: GrasscutterTools
|
||||||
|
path: Source/GrasscutterTools/bin/Release/GrasscutterTools.exe
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 37 KiB |
BIN
Doc/Screenshots-en/17-ShopEditor.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
Doc/Screenshots-en/18-TaskPage.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
Doc/Screenshots-en/19-AchievementPage.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
Doc/Screenshots-en/20-ActivityEditor.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
Doc/Screenshots-en/21-HotKey.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
Doc/Screenshots-en/22-Proxy.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
Doc/Screenshots-en/23-SceneTag.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
Doc/Screenshots-en/24-Weather.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
Doc/Screenshots-en/25-Settings.png
Normal file
After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 30 KiB |
BIN
Doc/Screenshots-ru/1-Home.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
Doc/Screenshots-ru/10-Mail.png
Normal file
After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 20 KiB |
BIN
Doc/Screenshots-ru/11-Quests.png
Normal file
After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 42 KiB |
BIN
Doc/Screenshots-ru/12-Scenes.png
Normal file
After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 22 KiB |
BIN
Doc/Screenshots-ru/13-Shop.png
Normal file
After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 57 KiB |
BIN
Doc/Screenshots-ru/14-Gachas.png
Normal file
After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 62 KiB |
BIN
Doc/Screenshots-ru/15-Drops.png
Normal file
After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 37 KiB |
BIN
Doc/Screenshots-ru/16-Textmaps.png
Normal file
After Width: | Height: | Size: 7.1 KiB |
BIN
Doc/Screenshots-ru/18-TaskPage.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
Doc/Screenshots-ru/19-AchievementPage.png
Normal file
After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 19 KiB |
BIN
Doc/Screenshots-ru/2-Opencommand.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
Doc/Screenshots-ru/20-ActivityEditor.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
Doc/Screenshots-ru/3-Custom.png
Normal file
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 36 KiB |
BIN
Doc/Screenshots-ru/4-Artifacts.png
Normal file
After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 26 KiB |
BIN
Doc/Screenshots-ru/5-Spawn.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
Doc/Screenshots-ru/6-Give.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
Doc/Screenshots-ru/7-Character.png
Normal file
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 24 KiB |
BIN
Doc/Screenshots-ru/8-Weapons.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
Doc/Screenshots-ru/9-Accounts.png
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 30 KiB |
BIN
Doc/Screenshots-tw/0-Home.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
Doc/Screenshots-tw/1-CustomCommands.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
Doc/Screenshots-tw/10-GachaBannerEditor.png
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
Doc/Screenshots-tw/11-TextMapBrowser.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
Doc/Screenshots-tw/12-Remote.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
Doc/Screenshots-tw/13-Quest.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
Doc/Screenshots-tw/15-DropEditor.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
Doc/Screenshots-tw/16-MailEditor.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
Doc/Screenshots-tw/17-ShopEditor.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
Doc/Screenshots-tw/18-TaskPage.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
Doc/Screenshots-tw/19-AchievementPage.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
Doc/Screenshots-tw/2-CustomArtifact.png
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
Doc/Screenshots-tw/20-ActivityEditor.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
Doc/Screenshots-tw/3-CustomWeapon.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
Doc/Screenshots-tw/4-GiveItem.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
Doc/Screenshots-tw/5-GiveAvatar.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
Doc/Screenshots-tw/6-SpawnEntity.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
Doc/Screenshots-tw/6.1-AttackMod.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
Doc/Screenshots-tw/6.2-AttackInfuse.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
Doc/Screenshots-tw/7-ChangeScene.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
Doc/Screenshots-tw/9-Manage.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
Doc/Screenshots-tw/AttackMod.gif
Normal file
After Width: | Height: | Size: 3.6 MiB |
BIN
Doc/Screenshots-tw/ConfigHttp.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
Doc/Screenshots-tw/GrasscutterLogo.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
Doc/Screenshots-tw/OpenCommand.gif
Normal file
After Width: | Height: | Size: 821 KiB |
BIN
Doc/Screenshots-tw/RunMultipleCommands.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 41 KiB |
BIN
Doc/Screenshots/17-ShopEditor.png
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
Doc/Screenshots/18-TaskPage.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
Doc/Screenshots/19-AchievementPage.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
Doc/Screenshots/20-ActivityEditor.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
Doc/Screenshots/21-HotKey.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
Doc/Screenshots/22-Proxy.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
Doc/Screenshots/23-SceneTag.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
Doc/Screenshots/24-Weather.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
Doc/Screenshots/25-Settings.png
Normal file
After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
BIN
Doc/Screenshots/6.1-AttackMod.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
Doc/Screenshots/6.2-AttackInfuse.png
Normal file
After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 48 KiB |
BIN
Doc/Screenshots/AttackMod.gif
Normal file
After Width: | Height: | Size: 3.6 MiB |
76
README.md
@ -3,26 +3,19 @@
|
|||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/blob/main/LICENSE)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/blob/main/LICENSE)
|
||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/stargazers)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/stargazers)
|
||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases)
|
||||||
[](https://qm.qq.com/cgi-bin/qm/qr?k=PdS9--b-n8LEAmYjX8fNFXtKDcsp4NHN&jump_from=webapi&authKey=7ty3ZCKYMKLGWLmO8O84qiNAZ0EuCnSGF+acP+74xuDMKYXXNjuPP7iUzffHz4r2)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases/latest)
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/actions/workflows/build.yml)
|
||||||
|
[](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=fBizzp6RwJsIY7gFlmd4L-WG0V3aF8X3&authKey=mTjf%2B7jCIZess1HTRi05e5yi%2FHKA1auMwE8%2FJ960PFWk8WMATST654gWPi4OTHTZ&noverify=0&group_code=835489603)
|
||||||
|
|
||||||
English | [简体中文](README_zh-cn.md) | [Русский](README_ru-RU.md)
|
English | [简体中文](README_zh-cn.md) | [繁體中文](README_zh-tw.md) | [Русский](README_ru-RU.md)
|
||||||
|
|
||||||
## Commands Generator
|
## Commands Generator
|
||||||
|
|
||||||
Please download the latest version from [Releases](https://github.com/jie65535/GrasscutterCommandGenerator/releases)
|
Please download the latest committed automated build from [Action](https://github.com/jie65535/GrasscutterCommandGenerator/actions/workflows/build.yml), or a release from [Releases](https://github.com/jie65535/GrasscutterCommandGenerator/releases) (may be behind)
|
||||||
|
|
||||||
Support 简体中文, 繁体中文, English and Русский languages.
|
Support 简体中文, 繁體中文, English and Русский languages.
|
||||||
|
|
||||||
Welcome everyone to improve the [ID Resource](/Source/GrasscutterTools/Resources/en-us).
|
> **Warning**: app look may be different rather than on screenshots. It may also contain translation errors and a lack of certain resources. **We're welcome everyone to contribute to their [improvement](/Source/GrasscutterTools/Resources/en-us)**
|
||||||
|
|
||||||
## Update log
|
|
||||||
### GrasscutterTools-v1.7.0
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Remote command
|
## Remote command
|
||||||
|
|
||||||
@ -39,6 +32,61 @@ The server require [gc-opencommand-plugin](https://github.com/jie65535/gc-openco
|
|||||||
>
|
>
|
||||||
> If you are not using port `80`, specify the port number to access in the url: http://127.0.0.1:443
|
> If you are not using port `80`, specify the port number to access in the url: http://127.0.0.1:443
|
||||||
|
|
||||||
|
## Update log
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.13
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.11
|
||||||
|

|
||||||
|
|
||||||
|
Commandline Usages:
|
||||||
|
```bash
|
||||||
|
GcTools.exe -help
|
||||||
|
GcTools.exe -version
|
||||||
|
GcTools.exe -c "cmd arg"
|
||||||
|
GcTools.exe -c "cmd1 arg" && GcTools -c "cmd2 arg1 arg2"
|
||||||
|
GcTools.exe -host http://127.0.0.1:443 -token 123456 -c "cmd1 arg1 arg2 | cmd2 | cmd3 arg"
|
||||||
|
```
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.10
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.9
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.8
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.3
|
||||||
|

|
||||||
|
|
||||||
|
Added [AttackModifier](https://github.com/NotThorny/AttackModifier), [AttackInfusedWithItem](https://github.com/snoobi-seggs/AttackInfusedWithItem), [SwitchElementTraveller](https://github.com/Penelopeep/SwitchElementTraveller) plugins command generation
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.2
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.1
|
||||||
|
- Gadgets(CHS Only)
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.0
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
107
README_ru-RU.md
@ -3,25 +3,18 @@
|
|||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/blob/main/LICENSE)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/blob/main/LICENSE)
|
||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/stargazers)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/stargazers)
|
||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases)
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases/latest)
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/actions/workflows/build.yml)
|
||||||
|
|
||||||
[English](README.md) | [简体中文](README_zh-cn.md) | Русский - Перевод [Юрий Дворецкий](https://github.com/yurikenjx) (с исправлениями от [EgorBron](https://github.com/EgorBron))
|
[English](README.md) | [简体中文](README_zh-cn.md) | [繁體中文](README_zh-tw.md) | Русский - Перевод [Юрий Дворецкий](https://github.com/yurikenjx) (с исправлениями от [EgorBron](https://github.com/EgorBron))
|
||||||
|
|
||||||
## Генератор команд (GCG)
|
## Генератор команд (GCG)
|
||||||
|
|
||||||
Загрузите последнюю версию из вкладки [Releases](https://github.com/jie65535/GrasscutterCommandGenerator/releases).
|
Пожалуйста, загрузите последнюю подтвержденную автоматизированную сборку из [Action](https://github.com/jie65535/GrasscutterCommandGenerator/actions/workflows/build.yml) или выпуск из [Releases](https://github.com/jie65535/GrasscutterCommandGenerator/releases) (может отставать)
|
||||||
|
|
||||||
GCG поддерживает 简体中文 (китайский упр.), 繁体中文 (китайский трад.), English (английский) и Русский языки.
|
GCG поддерживает 简体中文 (китайский упр.), 繁體中文 (китайский трад.), English (английский) и Русский языки.
|
||||||
|
|
||||||
Приглашаем всех улучшить [ID ресурсов и перевод](/Source/GrasscutterTools/Resources/ru-ru)
|
> **Warning**: вид приложения может отличаться от скриншотов. Также в нём могут присутствовать ошибки в переводе и отсутсвие некоторых ресурсов. **Мы приглашаем всех сделать вклад в их [улучшение](/Source/GrasscutterTools/Resources/ru-ru)**
|
||||||
|
|
||||||
## Update log
|
|
||||||
### GrasscutterTools-v1.7.0
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Удаленная команда (OpenCommand)
|
## Удаленная команда (OpenCommand)
|
||||||
|
|
||||||
@ -39,38 +32,96 @@ GCG поддерживает 简体中文 (китайский упр.), 繁体
|
|||||||
>
|
>
|
||||||
> Если вы не указали порт `80` в конфиге, вам нужно указать свой порт в URL-адресе (например, http://127.0.0.1:443)
|
> Если вы не указали порт `80` в конфиге, вам нужно указать свой порт в URL-адресе (например, http://127.0.0.1:443)
|
||||||
|
|
||||||
|
|
||||||
|
## Лог обновлений
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.13
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.11
|
||||||
|

|
||||||
|
|
||||||
|
Commandline Usages:
|
||||||
|
```bash
|
||||||
|
GcTools.exe -help
|
||||||
|
GcTools.exe -version
|
||||||
|
GcTools.exe -c "cmd arg"
|
||||||
|
GcTools.exe -c "cmd1 arg" && GcTools -c "cmd2 arg1 arg2"
|
||||||
|
GcTools.exe -host http://127.0.0.1:443 -token 123456 -c "cmd1 arg1 arg2 | cmd2 | cmd3 arg"
|
||||||
|
```
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.10
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.9
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.8
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.3
|
||||||
|

|
||||||
|
|
||||||
|
Добавлена поддержка генерации команд для плагинов [AttackModifier](https://github.com/NotThorny/AttackModifier), [AttackInfusedWithItem](https://github.com/snoobi-seggs/AttackInfusedWithItem), [SwitchElementTraveller](https://github.com/Penelopeep/SwitchElementTraveller).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.2
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.1
|
||||||
|
- Гаджеты (пока что только на китайском)
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.0
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Скриншоты
|
## Скриншоты
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|

|
@ -3,31 +3,19 @@
|
|||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/blob/main/LICENSE)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/blob/main/LICENSE)
|
||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/stargazers)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/stargazers)
|
||||||
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases)
|
||||||
[](https://qm.qq.com/cgi-bin/qm/qr?k=PdS9--b-n8LEAmYjX8fNFXtKDcsp4NHN&jump_from=webapi&authKey=7ty3ZCKYMKLGWLmO8O84qiNAZ0EuCnSGF+acP+74xuDMKYXXNjuPP7iUzffHz4r2)
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases/latest)
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/actions/workflows/build.yml)
|
||||||
|
[](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=fBizzp6RwJsIY7gFlmd4L-WG0V3aF8X3&authKey=mTjf%2B7jCIZess1HTRi05e5yi%2FHKA1auMwE8%2FJ960PFWk8WMATST654gWPi4OTHTZ&noverify=0&group_code=835489603)
|
||||||
|
|
||||||
[English](README.md) | 简体中文 | [Русский](README_ru-RU.md)
|
[English](README.md) | 简体中文 | [繁體中文](README_zh-tw.md) | [Русский](README_ru-RU.md)
|
||||||
|
|
||||||
## Commands Generator
|
## Commands Generator
|
||||||
|
|
||||||
请从 [Releases](https://github.com/jie65535/GrasscutterCommandGenerator/releases) 中获取最新版本
|
请从 [Action](https://github.com/jie65535/GrasscutterCommandGenerator/actions/workflows/build.yml) 中下载最新提交的自动构建版本,或者从 [Releases](https://github.com/jie65535/GrasscutterCommandGenerator/releases) 中下载发布版本(可能落后)
|
||||||
|
|
||||||
本工具支持 简体中文, 繁体中文, English 与 Русский 语言。
|
本工具支持 简体中文, 繁體中文, English 与 Русский 语言。
|
||||||
|
|
||||||
欢迎大家一起来完善工具的[内置资源](/Source/GrasscutterTools/Resources/zh-cn)。
|
> **Warning**: 应用程序的外观可能与截图上的不同。它也可能包含翻译错误和缺乏某些资源。**我们欢迎各位为此工具做出贡献并<a href="./Source/GrasscutterTools/Resources/zh-cn">改进</a> : )**
|
||||||
|
|
||||||
## Update log
|
|
||||||
|
|
||||||
### GrasscutterTools-v1.7.1
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### GrasscutterTools-v1.7.0
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 远程执行
|
## 远程执行
|
||||||
|
|
||||||
@ -44,6 +32,66 @@
|
|||||||
>
|
>
|
||||||
> 如果使用的不是`80`端口,则要在url中指定访问的端口号:http://127.0.0.1:443
|
> 如果使用的不是`80`端口,则要在url中指定访问的端口号:http://127.0.0.1:443
|
||||||
|
|
||||||
|
|
||||||
|
## 更新概要
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.13
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.11
|
||||||
|

|
||||||
|
|
||||||
|
命令行用法:
|
||||||
|
```bash
|
||||||
|
GcTools.exe -help
|
||||||
|
GcTools.exe -version
|
||||||
|
GcTools.exe -c "cmd arg"
|
||||||
|
GcTools.exe -c "cmd1 arg" && GcTools -c "cmd2 arg1 arg2"
|
||||||
|
GcTools.exe -host http://127.0.0.1:443 -token 123456 -c "cmd1 arg1 arg2 | cmd2 | cmd3 arg"
|
||||||
|
```
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.10
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.9
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.8
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.3
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
新增[攻击修改](https://github.com/NotThorny/AttackModifier)、[攻击注入](https://github.com/snoobi-seggs/AttackInfusedWithItem)、[切换元素](https://github.com/Penelopeep/SwitchElementTraveller)等插件命令生成
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.2
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.1
|
||||||
|
- 增加了 Gadgets
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.0
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 软件截图
|
## 软件截图
|
||||||
|
125
README_zh-tw.md
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# Grasscutter Tools
|
||||||
|
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/blob/main/LICENSE)
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/stargazers)
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases)
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/releases/latest)
|
||||||
|
[](https://github.com/jie65535/GrasscutterCommandGenerator/actions/workflows/build.yml)
|
||||||
|
[](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=fBizzp6RwJsIY7gFlmd4L-WG0V3aF8X3&authKey=mTjf%2B7jCIZess1HTRi05e5yi%2FHKA1auMwE8%2FJ960PFWk8WMATST654gWPi4OTHTZ&noverify=0&group_code=835489603)
|
||||||
|
|
||||||
|
[English](README.md) | [简体中文](README_zh-cn.md) | 繁體中文 | [Русский](README_ru-RU.md)
|
||||||
|
|
||||||
|
## 指令產生工具
|
||||||
|
|
||||||
|
請從 [Action](https://github.com/jie65535/GrasscutterCommandGenerator/actions/workflows/build.yml) 中下載最新提交的自動構建版本,或者從 [Releases](https://github.com/jie65535/GrasscutterCommandGenerator/releases) 中下載發布版本(可能落後)
|
||||||
|
|
||||||
|
本工具支援 简体中文、繁體中文、English 及 Русский 上述語言。
|
||||||
|
|
||||||
|
> **Warning**: 程式中的實際外觀可能會與截圖中的內容不同。其中也可能包含翻譯錯誤及缺乏特定資源。**我們歡迎各位為此工具做出貢獻並[改進](/Source/GrasscutterTools/Resources/zh-tw)**
|
||||||
|
|
||||||
|
## 遠端控制
|
||||||
|
|
||||||
|
伺服器需要安裝 [gc-opencommand-plugin](https://github.com/jie65535/gc-opencommand-plugin) 插件
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> 如果你無法連接至伺服器,請確認輸入的伺服器位址是否正確。
|
||||||
|
>
|
||||||
|
> 建議將伺服器調整為HTTP模式,如下圖所示(config.json):
|
||||||
|
> 
|
||||||
|
>
|
||||||
|
> 你可藉由任何瀏覽器輸入網址 http://127.0.0.1/status/server 以測試伺服器是否正常運作。
|
||||||
|
>
|
||||||
|
> 如果你並非使用`80`端口, 則須在網址後輸入指定端口: http://127.0.0.1:443
|
||||||
|
|
||||||
|
## 更新日誌
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.13
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.11
|
||||||
|

|
||||||
|
|
||||||
|
Commandline Usages:
|
||||||
|
```bash
|
||||||
|
GcTools.exe -help
|
||||||
|
GcTools.exe -version
|
||||||
|
GcTools.exe -c "cmd arg"
|
||||||
|
GcTools.exe -c "cmd1 arg" && GcTools -c "cmd2 arg1 arg2"
|
||||||
|
GcTools.exe -host http://127.0.0.1:443 -token 123456 -c "cmd1 arg1 arg2 | cmd2 | cmd3 arg"
|
||||||
|
```
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.10
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.9
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.8
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.3
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
新增 [攻擊修改](https://github.com/NotThorny/AttackModifier)、[攻擊注入](https://github.com/snoobi-seggs/AttackInfusedWithItem)、[主角切換元素](https://github.com/Penelopeep/SwitchElementTraveller)等插件指令產生
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.2
|
||||||
|

|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.1
|
||||||
|
- 新增 Gadgets
|
||||||
|
|
||||||
|
### GrasscutterTools-v1.7.0
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## 工具截圖
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
@ -29,7 +29,7 @@
|
|||||||
<value>10001</value>
|
<value>10001</value>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="Host" serializeAs="String">
|
<setting name="Host" serializeAs="String">
|
||||||
<value>https://127.0.0.1</value>
|
<value>http://127.0.0.1:443</value>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="CheckedLastVersion" serializeAs="String">
|
<setting name="CheckedLastVersion" serializeAs="String">
|
||||||
<value />
|
<value />
|
||||||
@ -52,6 +52,39 @@
|
|||||||
<setting name="ShopJsonPath" serializeAs="String">
|
<setting name="ShopJsonPath" serializeAs="String">
|
||||||
<value />
|
<value />
|
||||||
</setting>
|
</setting>
|
||||||
|
<setting name="MainFormLocation" serializeAs="String">
|
||||||
|
<value>0, 0</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="MainFormSize" serializeAs="String">
|
||||||
|
<value>0, 0</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="BannersJsonPath" serializeAs="String">
|
||||||
|
<value />
|
||||||
|
</setting>
|
||||||
|
<setting name="IsIncludeUID" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="NavContainerSplitterDistance" serializeAs="String">
|
||||||
|
<value>0</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="ActivityConfigJsonPath" serializeAs="String">
|
||||||
|
<value />
|
||||||
|
</setting>
|
||||||
|
<setting name="ProjectResourcePath" serializeAs="String">
|
||||||
|
<value />
|
||||||
|
</setting>
|
||||||
|
<setting name="IsUpgraded" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="IsHotkeyEenabled" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="AutoStartProxy" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="WindowOpacity" serializeAs="String">
|
||||||
|
<value>100</value>
|
||||||
|
</setting>
|
||||||
</GrasscutterTools.Properties.Settings>
|
</GrasscutterTools.Properties.Settings>
|
||||||
</userSettings>
|
</userSettings>
|
||||||
</configuration>
|
</configuration>
|
@ -1,186 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
|
|
||||||
namespace GrasscutterTools.Controls
|
|
||||||
{
|
|
||||||
[ToolboxItem(true)]
|
|
||||||
public class TextBoxXP : TextBox
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获得当前进程,以便重绘控件
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hWnd"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
private static extern IntPtr GetWindowDC(IntPtr hWnd);
|
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
|
||||||
|
|
||||||
private const int EM_SETCUEBANNER = 0x1501;
|
|
||||||
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
||||||
private static extern Int32 SendMessage
|
|
||||||
(IntPtr hWnd, int msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 水印文本
|
|
||||||
/// </summary>
|
|
||||||
private string _Watermark = "";
|
|
||||||
|
|
||||||
private float maximum;
|
|
||||||
private float minimum;
|
|
||||||
|
|
||||||
#region 属性
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否启用热点效果
|
|
||||||
/// </summary>
|
|
||||||
[Category("外观")]
|
|
||||||
[Browsable(true)]
|
|
||||||
[Localizable(true)]
|
|
||||||
[Description("获取或设置输入框水印文本")]
|
|
||||||
[DefaultValue("")]
|
|
||||||
public string Watermark
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return this._Watermark;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
this._Watermark = value;
|
|
||||||
SendMessage(Handle, EM_SETCUEBANNER, 0, _Watermark);
|
|
||||||
this.Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否只能输入数字
|
|
||||||
/// </summary>
|
|
||||||
[Category("行为")]
|
|
||||||
[Browsable(true)]
|
|
||||||
[Description("获取或设置TextBox是否只允许输入数字")]
|
|
||||||
[DefaultValue(false)]
|
|
||||||
public bool DigitOnly { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 转为数值
|
|
||||||
/// </summary>
|
|
||||||
public float Number
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (float.TryParse(Text, out float value))
|
|
||||||
return value;
|
|
||||||
else
|
|
||||||
return 0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Category("数据")]
|
|
||||||
[Browsable(true)]
|
|
||||||
[DefaultValue(0)]
|
|
||||||
[Description("指示小数点后位数")]
|
|
||||||
public int DecimalPlaces { get; set; }
|
|
||||||
|
|
||||||
[Category("数据")]
|
|
||||||
[Description("获取或设置限制的最大值")]
|
|
||||||
public float Maximum
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return maximum;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
maximum = value;
|
|
||||||
if (minimum > maximum)
|
|
||||||
{
|
|
||||||
minimum = maximum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Category("数据")]
|
|
||||||
[Browsable(true)]
|
|
||||||
[Description("获取或设置限制的最小值")]
|
|
||||||
public float Minimum
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
minimum = value;
|
|
||||||
if (minimum > maximum)
|
|
||||||
{
|
|
||||||
maximum = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion 属性
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
public TextBoxXP()
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
//BorderStyle = BorderStyle.FixedSingle;
|
|
||||||
//Font = Styles.StaticResources.DefaultFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnKeyPress(KeyPressEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnKeyPress(e);
|
|
||||||
// 如果只允许输入数字,则判断输入是否为退格或者数字
|
|
||||||
if (DigitOnly)
|
|
||||||
{
|
|
||||||
//IsNumber:指定字符串中位于指定位置的字符是否属于数字类别
|
|
||||||
//IsPunctuation:指定字符串中位于指定位置的字符是否属于标点符号类别
|
|
||||||
//IsControl:指定字符串中位于指定位置的字符是否属于控制字符类别
|
|
||||||
if (!Char.IsNumber(e.KeyChar) && !Char.IsPunctuation(e.KeyChar) && !Char.IsControl(e.KeyChar))
|
|
||||||
{
|
|
||||||
e.Handled = true; //获取或设置一个值,指示是否处理过System.Windows.Forms.Control.KeyPress事件
|
|
||||||
}
|
|
||||||
else if (Char.IsPunctuation(e.KeyChar) && DecimalPlaces > 0)
|
|
||||||
{
|
|
||||||
if (e.KeyChar == '.')
|
|
||||||
{
|
|
||||||
if (Text.LastIndexOf('.') != -1)
|
|
||||||
{
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e.Handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnLeave(EventArgs e)
|
|
||||||
{
|
|
||||||
base.OnLeave(e);
|
|
||||||
|
|
||||||
if (DigitOnly)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrWhiteSpace(Text))
|
|
||||||
{
|
|
||||||
if (Number > Maximum)
|
|
||||||
Text = Maximum.ToString("F" + DecimalPlaces);
|
|
||||||
if (Number < Minimum)
|
|
||||||
Text = Minimum.ToString("F" + DecimalPlaces);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,8 +14,9 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using GrasscutterTools.DispatchServer.Model;
|
using GrasscutterTools.DispatchServer.Model;
|
||||||
@ -23,7 +24,7 @@ using GrasscutterTools.Utils;
|
|||||||
|
|
||||||
namespace GrasscutterTools.DispatchServer
|
namespace GrasscutterTools.DispatchServer
|
||||||
{
|
{
|
||||||
public static class DispatchServerAPI
|
internal static class DispatchServerAPI
|
||||||
{
|
{
|
||||||
public static async Task<ServerStatus> QueryServerStatus(string host)
|
public static async Task<ServerStatus> QueryServerStatus(string host)
|
||||||
{
|
{
|
||||||
|
@ -14,13 +14,14 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace GrasscutterTools.DispatchServer.Model
|
namespace GrasscutterTools.DispatchServer.Model
|
||||||
{
|
{
|
||||||
public class ServerStatus
|
internal class ServerStatus
|
||||||
{
|
{
|
||||||
[JsonProperty("playerCount")]
|
[JsonProperty("playerCount")]
|
||||||
public int PlayerCount { get; set; }
|
public int PlayerCount { get; set; }
|
||||||
@ -32,7 +33,7 @@ namespace GrasscutterTools.DispatchServer.Model
|
|||||||
public string Version { get; set; }
|
public string Version { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServerStatusResponse
|
internal class ServerStatusResponse
|
||||||
{
|
{
|
||||||
[JsonProperty("retcode")]
|
[JsonProperty("retcode")]
|
||||||
public int RetCode { get; set; }
|
public int RetCode { get; set; }
|
||||||
|
202
Source/GrasscutterTools/Eavesdrop/Certifier.cs
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
|
namespace Eavesdrop;
|
||||||
|
|
||||||
|
public sealed class Certifier : IDisposable
|
||||||
|
{
|
||||||
|
private readonly X509Store _rootStore, _myStore;
|
||||||
|
private readonly IDictionary<string, X509Certificate2> _certificateCache;
|
||||||
|
|
||||||
|
public string Issuer { get; }
|
||||||
|
public string CertificateAuthorityName { get; }
|
||||||
|
|
||||||
|
public DateTime NotAfter { get; set; }
|
||||||
|
public DateTime NotBefore { get; set; }
|
||||||
|
public int KeyLength { get; set; } = 1024;
|
||||||
|
public bool IsCachingSignedCertificates { get; set; }
|
||||||
|
|
||||||
|
public X509Certificate2? Authority { get; private set; }
|
||||||
|
|
||||||
|
public Certifier()
|
||||||
|
: this("Eavesdrop")
|
||||||
|
{ }
|
||||||
|
public Certifier(string issuer)
|
||||||
|
: this(issuer, $"{issuer} Root Certificate Authority", StoreLocation.CurrentUser)
|
||||||
|
{ }
|
||||||
|
public Certifier(string issuer, string certificateAuthorityName)
|
||||||
|
: this(issuer, certificateAuthorityName, StoreLocation.CurrentUser)
|
||||||
|
{ }
|
||||||
|
public Certifier(string issuer, string certificateAuthorityName, StoreLocation location)
|
||||||
|
{
|
||||||
|
_myStore = new X509Store(StoreName.My, location);
|
||||||
|
_rootStore = new X509Store(StoreName.Root, location);
|
||||||
|
_certificateCache = new Dictionary<string, X509Certificate2>();
|
||||||
|
|
||||||
|
NotBefore = DateTime.Now;
|
||||||
|
NotAfter = NotBefore.AddMonths(1);
|
||||||
|
|
||||||
|
Issuer = issuer;
|
||||||
|
CertificateAuthorityName = certificateAuthorityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CreateTrustedRootCertificate()
|
||||||
|
{
|
||||||
|
return (Authority = InstallCertificate(_rootStore, CertificateAuthorityName)) != null;
|
||||||
|
}
|
||||||
|
public bool DestroyTrustedRootCertificate()
|
||||||
|
{
|
||||||
|
return DestroyCertificates(_rootStore);
|
||||||
|
}
|
||||||
|
public bool ExportTrustedRootCertificate(string path)
|
||||||
|
{
|
||||||
|
X509Certificate2? rootCertificate = InstallCertificate(_rootStore, CertificateAuthorityName);
|
||||||
|
|
||||||
|
path = Path.GetFullPath(path);
|
||||||
|
if (rootCertificate != null)
|
||||||
|
{
|
||||||
|
byte[] data = rootCertificate.Export(X509ContentType.Cert);
|
||||||
|
File.WriteAllBytes(path, data);
|
||||||
|
}
|
||||||
|
return File.Exists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public X509Certificate2? GenerateCertificate(string certificateName)
|
||||||
|
{
|
||||||
|
return InstallCertificate(_myStore, certificateName);
|
||||||
|
}
|
||||||
|
public X509Certificate2 CreateCertificate(string subjectName, string alternateName)
|
||||||
|
{
|
||||||
|
using var rsa = RSA.Create(KeyLength);
|
||||||
|
var certificateRequest = new CertificateRequest(subjectName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||||
|
if (Authority == null)
|
||||||
|
{
|
||||||
|
certificateRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
|
||||||
|
certificateRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(certificateRequest.PublicKey, false));
|
||||||
|
|
||||||
|
using X509Certificate2 certificate = certificateRequest.CreateSelfSigned(NotBefore.ToUniversalTime(), NotAfter.ToUniversalTime());
|
||||||
|
|
||||||
|
certificate.FriendlyName = alternateName;
|
||||||
|
return new X509Certificate2(certificate.Export(X509ContentType.Pfx, string.Empty), string.Empty, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var sanBuilder = new SubjectAlternativeNameBuilder();
|
||||||
|
sanBuilder.AddDnsName(alternateName);
|
||||||
|
|
||||||
|
certificateRequest.CertificateExtensions.Add(sanBuilder.Build());
|
||||||
|
certificateRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
|
||||||
|
certificateRequest.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(certificateRequest.PublicKey, false));
|
||||||
|
|
||||||
|
using X509Certificate2 certificate = certificateRequest.Create(Authority, Authority.NotBefore, Authority.NotAfter, Guid.NewGuid().ToByteArray());
|
||||||
|
using X509Certificate2 certificateWithPrivateKey = certificate.CopyWithPrivateKey(rsa);
|
||||||
|
|
||||||
|
certificateWithPrivateKey.FriendlyName = alternateName;
|
||||||
|
return new X509Certificate2(certificateWithPrivateKey.Export(X509ContentType.Pfx, string.Empty), string.Empty, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private X509Certificate2? InstallCertificate(X509Store store, string certificateName)
|
||||||
|
{
|
||||||
|
if (_certificateCache.TryGetValue(certificateName, out X509Certificate2? certificate))
|
||||||
|
{
|
||||||
|
if (DateTime.Now >= certificate.NotAfter)
|
||||||
|
{
|
||||||
|
_certificateCache.Remove(certificateName);
|
||||||
|
}
|
||||||
|
else return certificate;
|
||||||
|
}
|
||||||
|
lock (store)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
store.Open(OpenFlags.ReadWrite);
|
||||||
|
string subjectName = $"CN={certificateName}, O={Issuer}";
|
||||||
|
|
||||||
|
certificate = FindCertificates(store, subjectName)?[0];
|
||||||
|
if (certificate != null && DateTime.Now >= certificate.NotAfter)
|
||||||
|
{
|
||||||
|
if (Authority == null)
|
||||||
|
{
|
||||||
|
DestroyCertificates();
|
||||||
|
store.Open(OpenFlags.ReadWrite);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
store.Remove(certificate);
|
||||||
|
}
|
||||||
|
certificate = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (certificate == null)
|
||||||
|
{
|
||||||
|
certificate = CreateCertificate(subjectName, certificateName);
|
||||||
|
if (certificate != null)
|
||||||
|
{
|
||||||
|
if (store == _rootStore || IsCachingSignedCertificates)
|
||||||
|
{
|
||||||
|
store.Add(certificate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return certificate;
|
||||||
|
}
|
||||||
|
catch { return certificate = null; }
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
store.Close();
|
||||||
|
if (certificate != null && !_certificateCache.ContainsKey(certificateName))
|
||||||
|
{
|
||||||
|
_certificateCache.Add(certificateName, certificate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool DestroyCertificates(X509Store store)
|
||||||
|
{
|
||||||
|
lock (store)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
store.Open(OpenFlags.ReadWrite);
|
||||||
|
X509Certificate2Collection certificates = store.Certificates.Find(X509FindType.FindByIssuerName, Issuer, false);
|
||||||
|
|
||||||
|
store.RemoveRange(certificates);
|
||||||
|
IEnumerable<string> subjectNames = certificates.Cast<X509Certificate2>().Select(c => c.GetNameInfo(X509NameType.SimpleName, false));
|
||||||
|
|
||||||
|
foreach (string subjectName in subjectNames)
|
||||||
|
{
|
||||||
|
if (!_certificateCache.ContainsKey(subjectName)) continue;
|
||||||
|
_certificateCache.Remove(subjectName);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch { return false; }
|
||||||
|
finally { store.Close(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool DestroyCertificates() => DestroyCertificates(_myStore) && DestroyCertificates(_rootStore);
|
||||||
|
|
||||||
|
private static X509Certificate2Collection? FindCertificates(X509Store store, string subjectName)
|
||||||
|
{
|
||||||
|
X509Certificate2Collection certificates = store.Certificates
|
||||||
|
.Find(X509FindType.FindBySubjectDistinguishedName, subjectName, false);
|
||||||
|
|
||||||
|
return certificates.Count > 0 ? certificates : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_myStore.Close();
|
||||||
|
_rootStore.Close();
|
||||||
|
|
||||||
|
_myStore.Dispose();
|
||||||
|
_rootStore.Dispose();
|
||||||
|
}
|
||||||
|
}
|