Compare commits

...

1497 Commits

Author SHA1 Message Date
Yumao
d59aa5392c
Merge pull request #1567 from MCSManager/dependabot/npm_and_yarn/frontend/vite-4.5.13
chore(deps-dev): bump vite from 4.5.10 to 4.5.13 in /frontend
2025-04-15 11:17:28 +08:00
Yumao
fe7992c698
Merge pull request #1561 from MCSManager/dependabot/npm_and_yarn/frontend/axios-1.8.2
chore(deps): bump axios from 1.7.4 to 1.8.2 in /frontend
2025-04-15 11:17:11 +08:00
Yumao
c614b59445
Merge pull request #1559 from MCSManager/dependabot/npm_and_yarn/daemon/koa-2.16.1
chore(deps): bump koa from 2.15.4 to 2.16.1 in /daemon
2025-04-15 11:16:57 +08:00
dependabot[bot]
079f046d03
chore(deps-dev): bump vite from 4.5.10 to 4.5.13 in /frontend
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.10 to 4.5.13.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.13/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.13/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 4.5.13
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 09:19:17 +00:00
YuMao
6c039af16f chore: i18n text 2025-04-14 17:13:18 +08:00
YuMao
cb767de61f chore: sort language keys 2025-04-14 14:26:11 +08:00
YuMao
1bd34c70e7 chore: sort lang script 2025-04-14 14:24:18 +08:00
YuMao
4d44129424 chore: i18n text 2025-04-14 11:47:17 +08:00
Yumao
660c42e4d7
Merge pull request #1558 from MCSManager/dependabot/npm_and_yarn/daemon/multi-b29f0fd473
chore(deps): bump tar-fs and dockerode in /daemon
2025-04-11 10:43:09 +08:00
dependabot[bot]
23e5eded55
chore(deps): bump axios from 1.7.4 to 1.8.2 in /frontend
Bumps [axios](https://github.com/axios/axios) from 1.7.4 to 1.8.2.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.4...v1.8.2)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.8.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-09 14:47:43 +00:00
dependabot[bot]
39ac65a425
chore(deps): bump koa from 2.15.4 to 2.16.1 in /daemon
Bumps [koa](https://github.com/koajs/koa) from 2.15.4 to 2.16.1.
- [Release notes](https://github.com/koajs/koa/releases)
- [Changelog](https://github.com/koajs/koa/blob/master/History.md)
- [Commits](https://github.com/koajs/koa/compare/2.15.4...v2.16.1)

---
updated-dependencies:
- dependency-name: koa
  dependency-version: 2.16.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-09 13:48:13 +00:00
dependabot[bot]
bace05284b
chore(deps): bump tar-fs and dockerode in /daemon
Bumps [tar-fs](https://github.com/mafintosh/tar-fs) to 2.1.2 and updates ancestor dependency [dockerode](https://github.com/apocas/dockerode). These dependencies need to be updated together.


Updates `tar-fs` from 2.0.1 to 2.1.2
- [Commits](https://github.com/mafintosh/tar-fs/compare/v2.0.1...v2.1.2)

Updates `dockerode` from 3.1.0 to 4.0.5
- [Release notes](https://github.com/apocas/dockerode/releases)
- [Commits](https://github.com/apocas/dockerode/compare/v3.1.0...v4.0.5)

---
updated-dependencies:
- dependency-name: tar-fs
  dependency-version: 2.1.2
  dependency-type: indirect
- dependency-name: dockerode
  dependency-version: 4.0.5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-09 03:29:09 +00:00
YuMao
dee299bcf8 feat: change docker default workdir = true 2025-04-09 11:15:16 +08:00
Yumao
e17fb9e2e5
Merge pull request #1551 from MCSManager/dependabot/npm_and_yarn/panel/axios-1.8.2
chore(deps): bump axios from 1.7.4 to 1.8.2 in /panel
2025-03-31 14:09:39 +08:00
Yumao
5a002fc504
Merge pull request #1552 from MCSManager/dependabot/npm_and_yarn/frontend/babel/runtime-7.27.0
chore(deps): bump @babel/runtime from 7.22.6 to 7.27.0 in /frontend
2025-03-31 14:09:29 +08:00
Yumao
52888d25ff
Merge pull request #1553 from MCSManager/dependabot/npm_and_yarn/frontend/vite-4.5.10
chore(deps-dev): bump vite from 4.5.9 to 4.5.10 in /frontend
2025-03-31 14:09:18 +08:00
Yumao
4d78bb756a
Merge pull request #1554 from MCSManager/dependabot/npm_and_yarn/daemon/babel/runtime-7.27.0
chore(deps): bump @babel/runtime from 7.18.9 to 7.27.0 in /daemon
2025-03-31 14:09:08 +08:00
Yumao
588beda158
Merge pull request #1555 from zyx006/master
Update zh_CN/TW.json for (Neo)Forge configs
2025-03-27 10:49:51 +08:00
zyx007
572a91c247 Update zh_CN/TW.json for (Neo)Forge configs 2025-03-26 14:47:02 +08:00
dependabot[bot]
bb0632fc1a
chore(deps): bump @babel/runtime from 7.18.9 to 7.27.0 in /daemon
Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.18.9 to 7.27.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.0/packages/babel-runtime)

---
updated-dependencies:
- dependency-name: "@babel/runtime"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-26 03:10:27 +00:00
dependabot[bot]
32968947ae
chore(deps-dev): bump vite from 4.5.9 to 4.5.10 in /frontend
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.9 to 4.5.10.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.10/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.10/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-26 03:10:26 +00:00
dependabot[bot]
fcd1808b73
chore(deps): bump @babel/runtime from 7.22.6 to 7.27.0 in /frontend
Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.22.6 to 7.27.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.0/packages/babel-runtime)

---
updated-dependencies:
- dependency-name: "@babel/runtime"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-26 03:10:20 +00:00
dependabot[bot]
245669f8b8
chore(deps): bump axios from 1.7.4 to 1.8.2 in /panel
Bumps [axios](https://github.com/axios/axios) from 1.7.4 to 1.8.2.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.4...v1.8.2)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-26 03:10:18 +00:00
Yumao
2055a1dd85
Merge pull request #1542 from SkyKingPX/master
feat: Add Forge Config, NeoForge Tag and NeoForge Configs & fix German "MC Bedrock" Translation
2025-03-26 11:09:17 +08:00
Antony Blem
d0a65fe1a1 Revert ch_CN changes 2025-03-25 13:39:43 +01:00
Antony
ff17c03894
feat: Add Forge Config, NeoForge Tag and NeoForge Configs, fix German "MC Bedrock" Translation 2025-03-18 08:10:40 +00:00
Yumao
ac3c30939a
Merge pull request #1541 from MCSManager/OvQ
fix: check processType
2025-03-15 16:49:57 +08:00
Lazy
703a951ffb fix: check processType 2025-03-14 22:29:30 -07:00
Yumao
09a8885d68
Merge pull request #1538 from MCSManager/OvQ
fix: update instance config
2025-03-14 17:36:51 +08:00
Yumao
d00d97cf97
Merge pull request #1540 from MCSManager/dependabot/npm_and_yarn/panel/babel/runtime-7.26.10
chore(deps): bump @babel/runtime from 7.20.7 to 7.26.10 in /panel
2025-03-14 17:35:18 +08:00
Yumao
e875650842
Merge pull request #1539 from MCSManager/dependabot/npm_and_yarn/daemon/axios-1.8.2
chore(deps): bump axios from 1.7.4 to 1.8.2 in /daemon
2025-03-14 17:35:08 +08:00
dependabot[bot]
903c1ae415
chore(deps): bump @babel/runtime from 7.20.7 to 7.26.10 in /panel
Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.20.7 to 7.26.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.10/packages/babel-runtime)

---
updated-dependencies:
- dependency-name: "@babel/runtime"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-14 09:12:37 +00:00
dependabot[bot]
05accb3a91
chore(deps): bump axios from 1.7.4 to 1.8.2 in /daemon
Bumps [axios](https://github.com/axios/axios) from 1.7.4 to 1.8.2.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.4...v1.8.2)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-14 09:12:35 +00:00
YuMao
7d86d1129c chore: optimize vite config 2025-03-14 17:11:24 +08:00
Lazy
77fd7876cc fix: update instance config 2025-03-14 01:41:38 -07:00
Yumao
3175897a6f
Merge pull request #1537 from MCSManager/OvQ
Card iframe offside
2025-03-13 00:44:56 +08:00
Lazy
2e7bf36de8 fix: card iframe offside 2025-03-12 22:00:55 +08:00
Lazy
2ff0f7e29c fix: card iframe offside 2025-03-12 20:54:40 +08:00
Lazy
6962066605 fix: btn text color 2025-03-12 20:53:52 +08:00
YuMao
e57cd413ce Merge branch 'master' of github.com:MCSManager/MCSManager 2025-03-10 17:39:55 +08:00
YuMao
176c8ad02e fix: https://github.com/MCSManager/MCSManager/issues/1533 2025-03-10 17:39:50 +08:00
Yumao
a22621a436
Merge pull request #1531 from grinheckerdev/master
Better Russian translation.
2025-03-10 10:56:18 +08:00
grinheckerdev
186a8fe134 Fix russian translation. 2025-03-07 12:38:13 +03:00
Yumao
3579fe529f
Merge pull request #1527 from MCSManager/OvQ
feat: edit docker env
2025-03-07 12:02:01 +08:00
Yumao
311455c532
Merge pull request #1528 from zyx006/master
Refine zh_CN/TW.json and update bat
2025-03-06 11:07:02 +08:00
zyx007
38744a40ef Refine zh_CN/TW.json and update bat 2025-03-05 23:16:17 +08:00
Yumao
921c01dd2c
Merge pull request #1526 from MCSManager/dev
fix: https://github.com/MCSManager/MCSManager/issues/1523
2025-03-05 16:56:39 +08:00
Lazy
0dd75ac7a7 opt: check instance advanced params 2025-03-05 16:39:29 +08:00
Lazy
96ecc0ce77 feat: edit docker env 2025-03-04 23:09:16 +08:00
YuMao
1e3b99d5c6 fix: https://github.com/MCSManager/MCSManager/issues/1523#issuecomment-2694123018 2025-03-04 11:54:37 +08:00
Yumao
e61f5b3a6e
Merge pull request #1525 from MCSManager/dev
Chore: 第三方翻译内容
2025-03-04 11:12:28 +08:00
Yumao
d801a46e1c
Merge pull request #1521 from WT2024/master
Update version number.
2025-02-28 10:34:15 +08:00
吴桐
3fea34745a Update version number. 2025-02-27 21:28:26 +08:00
Yumao
f757a27738
Merge pull request #1516 from XiaoXinYo/master
Correct:Effective Apache 2
2025-02-26 11:13:11 +08:00
Yang KaiQi
83dbf56ace
Correct:Effective Apache 2 2025-02-26 09:39:39 +08:00
Yumao
ed9af31a97
Merge pull request #1513 from zyx006/master
Update zh_CN.json、zh_TW.json
2025-02-25 11:46:22 +08:00
zyx007
ef818a876d 调整zh_CN与zh_TW的键值对顺序使其与en_US一致,对zh_CN进行了部分精校,对zh_TW补充了大量繁中翻译后文本键值对 2025-02-24 23:26:29 +08:00
Yumao
8982aebc83
Merge pull request #1511 from KenRouKoro/master
Update zh_CN.json
2025-02-24 17:21:05 +08:00
姚凯翔
91aa370a2d
Update zh_CN.json
更新中文翻译,待精校
2025-02-24 17:15:20 +08:00
YuMao
165b337584 chore: update version 2025-02-24 16:40:52 +08:00
YuMao
aad44fa7cb chore: i18n text 2025-02-24 14:42:34 +08:00
Yumao
73ad4a79a5
Merge pull request #1501 from MCSManager/absurd
chore: i18n
2025-02-20 14:08:55 +08:00
Yumao
c96601b8a8
Merge pull request #1502 from ChunghwaMC/master
追隨更新
2025-02-19 11:17:34 +08:00
ChunghwaMC
d6fab115c9
追隨更新 2025-02-18 20:23:18 +08:00
Lazy
2e4b1a979c chore: i18n 2025-02-18 16:27:21 +08:00
YuMao
42e6019427 chore: i18n 2025-02-18 15:58:53 +08:00
Yumao
77316b25ce
Merge pull request #1499 from MCSManager/nya
feat: warning about daemon using local network ip
2025-02-18 15:56:56 +08:00
Yumao
ec69be678f
Merge pull request #1498 from MCSManager/absurd
refactor: copy btn
2025-02-18 10:46:02 +08:00
Yumao
8d68116d97
Merge pull request #1500 from ChunghwaMC/master
追隨更新
2025-02-18 10:45:24 +08:00
ChunghwaMC
483ee5e6b4
追隨更新 2025-02-17 20:12:06 +08:00
alongw
f99cab3f0a
feat: warning about daemon using local network ip 2025-02-17 19:57:00 +08:00
Lazy
c1285cdb10 opt: show details 2025-02-17 17:08:48 +08:00
Lazy
02d986d25e refactor: copy btn 2025-02-17 16:56:56 +08:00
Yumao
1fcef8866d
Merge pull request #1494 from MCSManager/absurd
feat: edit cmd settings
2025-02-14 16:30:17 +08:00
Lazy
e4abb18302 refactor: rename var 2025-02-14 16:10:48 +08:00
Lazy
57cc3ddd4f feat: edit cmd settings 2025-02-14 12:33:52 +08:00
Yumao
8fc6cec023
Merge pull request #1493 from MCSManager/absurd
feat: 普通用户编辑 启动&更新 命令
2025-02-14 11:16:11 +08:00
Lazy
b5aae32f08 delete: unused apis 2025-02-14 00:19:48 +08:00
Lazy
27c0a9b75c fix: i18n 2025-02-14 00:16:10 +08:00
Lazy
e0cdf74da3 feat: instance fundamental details 2025-02-14 00:03:45 +08:00
Lazy
0efa85a162 fix: i18n 2025-02-13 23:56:33 +08:00
Yumao
e2ebd62100
Merge pull request #1491 from MCSManager/dependabot/npm_and_yarn/panel/koa-2.15.4
chore(deps): bump koa from 2.14.1 to 2.15.4 in /panel
2025-02-13 11:51:16 +08:00
dependabot[bot]
ec36b86175
chore(deps): bump koa from 2.14.1 to 2.15.4 in /panel
Bumps [koa](https://github.com/koajs/koa) from 2.14.1 to 2.15.4.
- [Release notes](https://github.com/koajs/koa/releases)
- [Changelog](https://github.com/koajs/koa/blob/2.15.4/History.md)
- [Commits](https://github.com/koajs/koa/compare/2.14.1...2.15.4)

---
updated-dependencies:
- dependency-name: koa
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-13 03:50:55 +00:00
Yumao
b7b6835ff1
Merge pull request #1490 from MCSManager/dependabot/npm_and_yarn/daemon/koa-2.15.4
chore(deps): bump koa from 2.13.1 to 2.15.4 in /daemon
2025-02-13 11:49:48 +08:00
dependabot[bot]
ad45502f56
chore(deps): bump koa from 2.13.1 to 2.15.4 in /daemon
Bumps [koa](https://github.com/koajs/koa) from 2.13.1 to 2.15.4.
- [Release notes](https://github.com/koajs/koa/releases)
- [Changelog](https://github.com/koajs/koa/blob/2.15.4/History.md)
- [Commits](https://github.com/koajs/koa/compare/2.13.1...2.15.4)

---
updated-dependencies:
- dependency-name: koa
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-12 19:44:26 +00:00
Yumao
42a8e8dbfe
Merge pull request #1486 from SkyKingPX/master
Update READMEs and Copyright
2025-02-07 10:45:42 +08:00
Antony Blem
58e06b5221 Update MCSManager Copyright to 2025 2025-02-05 19:45:57 +01:00
Antony Blem
f0a44a4686 Add German README.md (README_DE.md) 2025-02-05 19:42:34 +01:00
Antony Blem
0b19bd7fc1 Update/Correct English README.md 2025-02-05 19:02:37 +01:00
Yumao
c3929d61b8
Merge pull request #1476 from MCSManager/nya
feat: image viewer
2025-01-31 16:35:44 +08:00
alongw
fb0693903e
fix: i18n 2025-01-26 13:50:00 +08:00
alongw
3f28f79368
style: change image viewer style 2025-01-23 22:57:20 +08:00
alongw
76fa65ce25
feat: image viewer
closed #1472
2025-01-23 20:53:20 +08:00
Yumao
61450c41cb
Merge pull request #1474 from MCSManager/dependabot/npm_and_yarn/frontend/vite-4.5.9
chore(deps-dev): bump vite from 4.5.3 to 4.5.9 in /frontend
2025-01-23 11:08:16 +08:00
dependabot[bot]
954f5e3241
chore(deps-dev): bump vite from 4.5.3 to 4.5.9 in /frontend
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.3 to 4.5.9.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.9/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.9/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-22 06:12:16 +00:00
YuMao
d49e800508 fix: https://github.com/MCSManager/MCSManager/issues/1470 2025-01-21 20:27:05 +08:00
YuMao
37c2ee2bcf chore: optimize log info 2025-01-21 20:17:15 +08:00
alongw
2f974e8728
feat: create image viewer 2025-01-21 20:04:29 +08:00
YuMao
1748fcd751 feat: for redeem.mcsmanager.com 2025-01-21 16:53:00 +08:00
alongw
386388822d refactor: click file logic 2025-01-21 16:46:07 +08:00
Yumao
0ba3e32abc
Merge pull request #1469 from ChunghwaMC/master
追隨更新
2025-01-20 11:18:53 +08:00
Yumao
d6cf7323de
Merge pull request #1471 from inactivood/patch-1
Update es_ES.json
2025-01-20 11:15:48 +08:00
inactivo
f0060c3c69
Update es_ES.json 2025-01-19 16:35:27 -03:00
ChunghwaMC
51f2d02eaf
追隨更新 2025-01-19 22:50:55 +08:00
YuMao233
cbe03d0074 chore: optimize quick flow animate 2025-01-19 18:04:02 +08:00
YuMao233
60d3a4a17c fix: https://github.com/MCSManager/MCSManager/issues/1425 2025-01-19 17:30:55 +08:00
YuMao233
ec5beae2a9 fix: https://github.com/MCSManager/MCSManager/issues/1468 2025-01-19 15:01:03 +08:00
YuMao233
2e79b2dcfe chore: optimize ui 2025-01-19 14:38:23 +08:00
Yumao
bd3e2bb711
Merge pull request #1467 from ZoftTy/reverse-proxy-fix
fix: incorrect client IP display in logs under reverse proxy mode
2025-01-19 14:26:26 +08:00
YuMao
47c86b2bc5 fix: toAbsolutePath err for linux 2025-01-19 14:23:34 +08:00
YuMao233
c66c880eb3 fix: toAbsolutePath err for linux 2025-01-19 14:02:19 +08:00
YuMao
f9e6702557 Merge branch 'master' of github.com:MCSManager/MCSManager 2025-01-19 13:19:01 +08:00
YuMao
19f2284c2d feat: delay mission del 2025-01-19 13:18:47 +08:00
YuMao233
89ad69b21f fix: del err path check 2025-01-18 12:56:02 +08:00
YuMao233
56eb8c1640 fix: del err path check 2025-01-18 12:53:19 +08:00
ZoftTy
763943a007
fix: incorrect client IP display in logs under reverse proxy mode (#1442) 2025-01-16 23:50:27 +08:00
YuMao
a060540995 format: lang files 2025-01-13 11:23:35 +08:00
Yumao
8be2efca4c
Merge pull request #1462 from Dominicus0830/Dominicus0830-Korean-lang-file-v1
Korean lang file v1
2025-01-11 18:44:57 +08:00
Dominicus
79f69eba4b
Korean lang file v1 2025-01-11 14:51:10 +09:00
Yumao
457e7d499f
Merge pull request #1455 from OlegFM/master
Update ru_RU.json to use correct translation from en_EN.json
2025-01-07 11:31:57 +08:00
Yumao
3b8017e24c
Merge pull request #1456 from SkyKingPX/master
Add & Correct de_DE translations
2025-01-07 11:31:13 +08:00
Antony Blem
9938a8590e fix: Correct *one* German translation... 2025-01-06 16:02:31 +01:00
Antony Blem
52c8ac4ff9 fix: Correct some German translations, as they made no sense or weren't correct 2025-01-06 15:33:44 +01:00
Oleg Fominsky
d562cb0448
Merge pull request #1 from OlegFM/fix_russian_translation
Add new translations and update existing entries in ru_RU.json
2025-01-06 17:31:07 +03:00
Oleg Fominsky
04031cf2db Add new translations and update existing entries in ru_RU.json
Extended the Russian language JSON file with updated translations, increasing the total number of entries. This update aims to improve localization accuracy and expand language coverage.
2025-01-06 17:29:08 +03:00
Antony Blem
d2be793eea feat: Add German translations 2025-01-06 13:56:13 +01:00
YuMao
853793a964
Merge pull request #1450 from SkyKingPX/master
feat: Add Purpur tag and configuration file
2024-12-24 17:28:00 +08:00
Antony Blem
3146352d85
Merge branch 'master' of https://github.com/SkyKingPX/MCSManager 2024-12-24 09:24:22 +00:00
Antony Blem
0fbc373c94
fix: revert zh_CN Purpur translations 2024-12-24 09:18:48 +00:00
Antony Blem
3bbd01a0ae
fix: revert zh_CN Purpur translations 2024-12-24 08:37:20 +00:00
Antony Blem
b9aff22c5a
fix: Purpur.yml should not be available for Pufferfish users 2024-12-23 07:51:14 +00:00
Antony Blem
ba42e1f6b3
fix: Correct translations 2024-12-23 07:45:10 +00:00
Antony Blem
7e174a3f71
Merge branch 'master' of https://github.com/SkyKingPX/MCSManager 2024-12-23 07:40:18 +00:00
Antony Blem
69459c82d5
feat: Add Purpur tag and Configuration file 2024-12-23 07:17:04 +00:00
YuMao
96f145acdc
Merge pull request #1448 from SkyKingPX/master
feat: Add Pufferfish tag and Configuration file
2024-12-23 14:23:44 +08:00
Antony Blem
0b61eb408e feat: Add Pufferfish tag and Configuration file 2024-12-22 13:28:54 +01:00
YuMao
3a22884898
Merge pull request #1446 from MCSManager/feature/i18n-script
feat: add useless key scanner
2024-12-16 20:30:35 +08:00
YuMao
412f5132fe feat: add useless key scanner 2024-12-16 20:29:45 +08:00
YuMao
fca4690f21 feat: add useless key scanner 2024-12-16 19:37:52 +08:00
YuMao
5c0d98ee74
Merge pull request #1445 from MCSManager/absurd
Scheduled tasks support edit
2024-12-16 15:41:57 +08:00
Lazy
3af2c1437e Update TerminalCore.vue 2024-12-16 15:33:16 +08:00
Lazy
d78deac2a4 fix: time render 2024-12-16 14:31:37 +08:00
Lazy
8a027fb2f1 fix: render terminal color 2024-12-16 02:08:15 +08:00
Lazy
b3c2a4d19c fix: i18n 2024-12-16 01:44:08 +08:00
Lazy
c6222a5f85 Refactor: schedule 2024-12-16 01:33:53 +08:00
YuMao
92e63ee44a
Merge pull request #1444 from MCSManager/dependabot/npm_and_yarn/panel/nanoid-3.3.8
chore(deps): bump nanoid from 3.3.7 to 3.3.8 in /panel
2024-12-15 18:55:14 +08:00
dependabot[bot]
55a39c2b7b
chore(deps): bump nanoid from 3.3.7 to 3.3.8 in /panel
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.7 to 3.3.8.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.7...3.3.8)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-15 05:32:16 +00:00
YuMao
2c24401b4a
Merge pull request #1443 from MCSManager/dependabot/npm_and_yarn/frontend/nanoid-3.3.8
chore(deps): bump nanoid from 3.3.6 to 3.3.8 in /frontend
2024-12-15 13:31:20 +08:00
YuMao
681da12893
Merge pull request #1441 from SkyKingPX/master
fix: Remove visibility from 'Steam Rcon Protocol' when Instance is tagged with 'Minecraft'
2024-12-15 13:31:07 +08:00
dependabot[bot]
2dd1dc384c
chore(deps): bump nanoid from 3.3.6 to 3.3.8 in /frontend
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.6 to 3.3.8.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.6...3.3.8)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-14 05:13:01 +00:00
Antony Blem
086a831cd2 fix: Remove visibility from 'Steam Rcon Protocol' when Instance is tagged with 'Minecraft' 2024-12-13 10:11:40 +01:00
YuMao
3195753e0e feat: update vscode settings 2024-12-01 21:19:37 +08:00
YuMao
cfe70b6be4 feat: update vscode settings 2024-12-01 21:17:57 +08:00
YuMao
4f61f3e5d0 chore: add vscode/settings.json & update readme 2024-12-01 12:41:33 +08:00
YuMao
e521258b9d feat: i18n code 2024-12-01 12:17:42 +08:00
YuMao
5fd3564b47 fix: exchange router bug 2024-12-01 12:16:28 +08:00
YuMao
46ff718a8f
Merge pull request #1434 from MCSManager/feature/business
Feature/business-with-redeem-code
2024-11-30 21:14:47 +08:00
YuMao
d63914eb0b
Merge pull request #1435 from MCSManager/baka
feat: instance list delete button
2024-11-30 11:32:15 +08:00
alongw
1bb3ce33f1 refactor: cancel the independent splitting of API requests 2024-11-29 22:38:30 +08:00
alongw
ed4f68f670 refactor: cancel the independent splitting of API requests 2024-11-29 22:31:56 +08:00
YuMao
629e5fc2e6 feat: hide shop 2024-11-29 18:03:24 +08:00
YuMao
3336b49695 chore: del useless code 2024-11-29 16:40:17 +08:00
YuMao
6a6bdeb220 feat: i18n code 2024-11-29 16:37:01 +08:00
YuMao
8941f34624 Merge branch 'master' into feature/business 2024-11-29 16:18:32 +08:00
YuMao
e17cddf9da feat: auto create host path 2024-11-29 15:52:57 +08:00
alongw
5d6e13f478 refactor: move file 2024-11-27 23:30:34 +08:00
alongw
c0f39d6950 feat: instance list delete button 2024-11-27 23:20:25 +08:00
YuMao
8522fc261e feat: instance list auto sort 2024-11-27 17:27:58 +08:00
YuMao
c0e0e04105 chore: standards code 2024-11-27 16:25:52 +08:00
YuMao
ec79de28df chore: useless import 2024-11-27 16:14:33 +08:00
YuMao
9ade8e9462 fix: default workspace dir 2024-11-27 16:14:09 +08:00
YuMao
a4f871b8fd fix: startTimestamp flow 2024-11-27 15:51:11 +08:00
YuMao
586bc4a9ef fix: DockerStartCommand extends error & optimize create instance UI 2024-11-27 15:31:19 +08:00
YuMao
137808048d feat: changeWorkdir option for docker 2024-11-27 14:35:48 +08:00
YuMao
0bd617d5ed fix: dependency package warnings 2024-11-26 19:58:25 +08:00
YuMao
39a662eb52 fix: https://github.com/MCSManager/MCSManager/issues/1365 & https://github.com/MCSManager/MCSManager/issues/1433 2024-11-26 19:43:22 +08:00
YuMao
d7a5da9261 feat: i18n code 2024-11-25 20:21:22 +08:00
YuMao
1572a6104f feat: i18n code 2024-11-25 20:18:56 +08:00
YuMao
cfd962c159 chore: optimize ui & code 2024-11-25 19:52:30 +08:00
YuMao
46a2192f4a feat: i18n code 2024-11-25 19:29:35 +08:00
YuMao
a7ec8a12b1 feat: error template 2024-11-25 19:22:18 +08:00
YuMao
15ac453054 feat: shopping history query 2024-11-25 17:44:07 +08:00
YuMao
6b7d42e61f feat: shop api 2024-11-25 17:14:36 +08:00
YuMao
8e1c54abef feat: shop api 2024-11-25 17:10:01 +08:00
YuMao
17d8ee3b79 feat: shop api 2024-11-25 17:08:53 +08:00
YuMao
aa33f228a0 feat: renewal instance 2024-11-25 16:09:01 +08:00
YuMao
c74811898b feat: buy instance api 2024-11-25 15:21:21 +08:00
YuMao
38322c38c8 feat: buy instance api 2024-11-25 14:27:30 +08:00
YuMao
6967bb736c feat: shop page request 2024-11-22 17:48:52 +08:00
YuMao
d71592b766 feat: shop page request 2024-11-22 17:30:35 +08:00
YuMao
470d569fec feat: shop page 2024-11-21 20:25:41 +08:00
YuMao
547d1d6c40 feat: shop page 2024-11-21 19:37:45 +08:00
YuMao
8799afb02c feat: business mode 2024-11-21 14:48:05 +08:00
YuMao
76e0bc023c fix: instance.process.write(encode(buf, instance.config.oe)); -> inputCode 2024-11-20 19:40:24 +08:00
YuMao
1dcafd9128 Merge branch 'master' of github.com:MCSManager/MCSManager 2024-11-17 14:38:11 +08:00
YuMao
a141de7cc7 fix: empty remote daemon 2024-11-17 14:37:58 +08:00
YuMao
16d88f768b
Merge pull request #1418 from MCSManager/alongw
fix: user assignment list not cleared when deleting instance
2024-10-31 16:10:58 +08:00
alongw
7c824a419d fix: fix deleteUserInstances method args type error 2024-10-30 21:06:16 +08:00
YuMao
c05038c1f1
Merge pull request #1419 from KagurazakaNyaa/master
chore: reduce web image size
2024-10-30 19:35:11 +08:00
alongw
e2a7e20a49 feat: add type check 2024-10-30 17:05:06 +08:00
alongw
1dd417f05c fix: user assignment list not cleared when deleting instance
fixed #1415
2024-10-30 16:55:05 +08:00
KagurazakaNyaa
ab7bb109e0 fix: alpine build need wget 2024-10-30 16:52:25 +08:00
KagurazakaNyaa
d6f0691828 chore: change base image to node:lts-alpine to reduce image size 2024-10-30 16:41:02 +08:00
YuMao
3822a7bfb4 chore: i18n code 2024-10-30 14:34:57 +08:00
YuMao
78dcc1de4f
Fix: https://github.com/MCSManager/MCSManager/issues/1379 2024-10-30 14:23:01 +08:00
YuMao
4d9959f666
Merge pull request #1414 from KagurazakaNyaa/master
ci: add linux/arm64 platform support for docker
2024-10-30 14:19:12 +08:00
YuMao
b3caf3aa05 Merge branch 'master' of github.com:MCSManager/MCSManager 2024-10-30 14:18:58 +08:00
YuMao
8b21e5feb7 refactor: instance "command exec()" replace to "execPreset()" 2024-10-30 14:18:52 +08:00
Lazy
019ccf04d1 fix: spell check 2024-10-30 00:16:57 +08:00
Lazy
781bd32c48 fix: do not refresh 2024-10-30 00:08:13 +08:00
Lazy
ea49d3f36d fix: operate icon 2024-10-30 00:07:53 +08:00
Lazy
6a4145ae72 fix: terminal color render 2024-10-29 23:52:53 +08:00
YuMao
264b8facaf
Update README.md 2024-10-29 14:34:02 +08:00
YuMao
c3e6fb7f0e
chore: add custom card gif 2024-10-29 14:30:49 +08:00
YuMao
abb20ad0f1 fix: https://github.com/MCSManager/MCSManager/issues/1323 2024-10-29 11:40:49 +08:00
YuMao
92438f876a fix: text typo 2024-10-29 11:05:52 +08:00
KagurazakaNyaa
95973a6c77 chore: Suppress docker build warnings 2024-10-29 10:12:54 +08:00
KagurazakaNyaa
d260e737d8 ci: alway use amd64 on build stage to speed up build 2024-10-29 10:06:23 +08:00
KagurazakaNyaa
0a97ad9d70 ci: Remove unused architectures to speed up builds 2024-10-29 09:39:23 +08:00
KagurazakaNyaa
dd6cc84461 chore: Remove part of the architecture support for daemon due to compatibility issues 2024-10-29 09:38:00 +08:00
KagurazakaNyaa
3934e26e21 ci: docker image support multiple platform 2024-10-29 09:20:41 +08:00
YuMao
a6f6f34e37
Merge pull request #1411 from JackER4565/master
added spanish readme
2024-10-28 10:41:59 +08:00
Fabrizio Rondinella
0e7da93735 added spanish readme 2024-10-26 11:41:39 -03:00
Fabrizio Rondinella
d95b952c77
Create README_ES.md 2024-10-26 11:12:32 -03:00
YuMao
bb825ec931
Merge pull request #1410 from kukinghan/master
fix issues 1409
2024-10-26 10:04:48 +08:00
kukinghan
f0ce2f3bd0 fix: search logic 2024-10-25 22:38:36 +08:00
kukinghan
573fb80f65 fix: search change not retrieving files correctly after pagination 2024-10-25 22:35:38 +08:00
YuMao
d277497861 optimize: placeholder desc 2024-10-21 17:53:27 +08:00
YuMao
3fa9c1e784 Merge branch 'master' of github.com:MCSManager/MCSManager 2024-10-21 17:44:58 +08:00
YuMao
358c7f4402 feat: parseTextParams of instance 2024-10-21 17:44:54 +08:00
YuMao
d3aaeb39f1 feat: parseTextParams of instance 2024-10-21 17:36:20 +08:00
YuMao
ef91fdb2a7
Merge pull request #1407 from KagurazakaNyaa/master
feat: daemon内置java运行时
2024-10-21 16:03:06 +08:00
KagurazakaNyaa
336dd6b19f chore: prevent web build trigger repeatedly 2024-10-21 12:18:49 +08:00
KagurazakaNyaa
b3d6c04b23 chore: dont trigger docker.io image build on test 2024-10-21 12:14:16 +08:00
KagurazakaNyaa
c11910a14e feat: daemon embedded java runtime 2024-10-21 12:05:01 +08:00
YuMao
adf7c50981 fix: MCSM_INSTANCES_BASE_PATH path err 2024-10-17 15:08:31 +08:00
YuMao
90bedcd985
Merge pull request #1403 from MCSManager/feature/docker-push
fix: MCSM_INSTANCES_BASE_PATH path err
2024-10-17 15:05:48 +08:00
YuMao
50c85cc8e3 fix: MCSM_INSTANCES_BASE_PATH path err 2024-10-17 14:50:13 +08:00
YuMao
903417f7b9
Merge pull request #1400 from MCSManager/feature/docker-push
feat: package support docker hub
2024-10-14 14:19:00 +08:00
YuMao
aa28a14ed5 feat: pack support docker hub 2024-10-14 14:16:51 +08:00
YuMao
bf2b3ed439 feat: pack support docker hub 2024-10-14 14:15:19 +08:00
YuMao
b14d594fc2 feat: support docker hub 2024-10-14 14:12:23 +08:00
YuMao
6c97db269f feat: update version 2024-10-14 10:45:31 +08:00
YuMao
fcc082b71d
Merge pull request #1395 from KagurazakaNyaa/master
feat: docker image build
2024-10-14 10:41:27 +08:00
KagurazakaNyaa
3bb4eff36b fix lib perms 2024-10-12 16:45:55 +08:00
KagurazakaNyaa
cb36d76685 lowcase image name 2024-10-12 16:39:43 +08:00
KagurazakaNyaa
4348d72e1c try build docker image 2024-10-12 16:38:48 +08:00
YuMao
43bb852bb6 feat: version check 2024-10-12 15:23:52 +08:00
YuMao
984dee266a feat: Docker instance real path mapping variable 2024-10-08 15:13:41 +08:00
YuMao
da7948b6ad fix: bind "workingDir" tip msg 2024-10-08 14:05:48 +08:00
YuMao
ce94503b96 chore: build.sh add "npm install" 2024-09-30 11:09:50 +08:00
YuMao
fdaa87db68 chore: build.sh add "npm install" 2024-09-30 10:49:00 +08:00
YuMao
6e707e4b6c
chore: release.yml type: published 2024-09-29 19:56:56 +08:00
YuMao
6f49a48655
Merge pull request #1385 from KagurazakaNyaa/master
chore: Auto build when release
2024-09-29 19:51:29 +08:00
KagurazakaNyaa
e705fc5f4e chore: Auto build when release 2024-09-29 18:44:35 +08:00
YuMao
67ca5e00bb fix: "Frontend Connection" localhost error 2024-09-29 14:03:23 +08:00
YuMao
aea1bfcc60 fix: init empty daemon id 2024-09-28 12:55:40 +08:00
YuMao
18af4739fc Revert "chore: Add dependency files"
This reverts commit d85126040769522c39444b4ec257e7aaed1834fe.
2024-09-28 12:34:04 +08:00
YuMao
8fa678ca3f Revert "chore: Add dependency files"
This reverts commit d85126040769522c39444b4ec257e7aaed1834fe.
2024-09-28 12:33:37 +08:00
YuMao
0a05f33936 Merge branch 'master' of github.com:MCSManager/MCSManager 2024-09-27 17:11:03 +08:00
YuMao
8fe62b25b4 chore: update version 2024-09-27 17:10:58 +08:00
YuMao
1d0867d6cb
Merge pull request #1383 from MCSManager/dependabot/npm_and_yarn/frontend/rollup-3.29.5
Build(deps): Bump rollup from 3.29.4 to 3.29.5 in /frontend
2024-09-27 17:00:03 +08:00
YuMao
ca6c1ff18f feat: optimize xhr poll error tip 2024-09-27 16:15:30 +08:00
YuMao
5f400873ff chore: name fix 2024-09-27 15:24:55 +08:00
YuMao
6e06d8145d
Update webpack.yml 2024-09-27 15:09:26 +08:00
YuMao
089f57eff3 chore: optimize build.sh 2024-09-27 15:07:10 +08:00
YuMao
d851260407 chore: Add dependency files 2024-09-27 15:00:00 +08:00
YuMao
42918e64dd feat: file upload log 2024-09-27 14:13:35 +08:00
YuMao
779388daf8 feat: i18n code 2024-09-27 11:07:36 +08:00
dependabot[bot]
66e7ded849
Build(deps): Bump rollup from 3.29.4 to 3.29.5 in /frontend
Bumps [rollup](https://github.com/rollup/rollup) from 3.29.4 to 3.29.5.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v3.29.4...v3.29.5)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-26 21:04:35 +00:00
YuMao
c0fa65fc5a feat: dark theme optimize & fix bugs 2024-09-24 16:31:12 +08:00
YuMao
d9661483c3 feat: support workspace empty 2024-09-24 15:32:22 +08:00
YuMao
ccd50605ea feat: dark theme bg color 2024-09-24 11:46:28 +08:00
Unitwk
43c161c8c7 feat ResponsiveLayoutGroup component 2024-09-24 11:28:44 +08:00
YuMao
c63ecbb6c1
Merge pull request #1378 from rjtop/master
Update README
2024-09-23 10:32:24 +08:00
Misha
59f409551f
Update README_JP.md 2024-09-20 18:07:44 +08:00
Misha
65e3cc8a5f
Update README.md 2024-09-20 18:05:42 +08:00
YuMao
05638596aa
Merge pull request #1375 from MCSManager/dependabot/npm_and_yarn/panel/path-to-regexp-6.3.0
Build(deps): Bump path-to-regexp from 6.2.1 to 6.3.0 in /panel
2024-09-15 13:32:54 +08:00
dependabot[bot]
d1bc1204ad
Build(deps): Bump path-to-regexp from 6.2.1 to 6.3.0 in /panel
Bumps [path-to-regexp](https://github.com/pillarjs/path-to-regexp) from 6.2.1 to 6.3.0.
- [Release notes](https://github.com/pillarjs/path-to-regexp/releases)
- [Changelog](https://github.com/pillarjs/path-to-regexp/blob/master/History.md)
- [Commits](https://github.com/pillarjs/path-to-regexp/compare/v6.2.1...v6.3.0)

---
updated-dependencies:
- dependency-name: path-to-regexp
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-15 03:38:42 +00:00
YuMao
ec3204488b
Merge pull request #1373 from MCSManager/dependabot/npm_and_yarn/daemon/path-to-regexp-6.3.0
Build(deps): Bump path-to-regexp from 6.2.0 to 6.3.0 in /daemon
2024-09-15 11:37:43 +08:00
dependabot[bot]
c07af372cc
Build(deps): Bump path-to-regexp from 6.2.0 to 6.3.0 in /daemon
Bumps [path-to-regexp](https://github.com/pillarjs/path-to-regexp) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/pillarjs/path-to-regexp/releases)
- [Changelog](https://github.com/pillarjs/path-to-regexp/blob/master/History.md)
- [Commits](https://github.com/pillarjs/path-to-regexp/compare/v6.2.0...v6.3.0)

---
updated-dependencies:
- dependency-name: path-to-regexp
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-12 17:38:49 +00:00
Unitwk
1280e3ff2f
Merge pull request #1364 from MCSManager/dependabot/npm_and_yarn/daemon/webpack-5.94.0
Build(deps-dev): Bump webpack from 5.89.0 to 5.94.0 in /daemon
2024-09-04 10:46:50 +08:00
Unitwk
6fef06821a fix: tag search json err 2024-09-03 10:34:03 +08:00
Unitwk
5f25f5d59c feat: loading page support dark mode 2024-09-02 19:30:00 +08:00
Unitwk
06482a7ee1 feat: terminal ui add tag info 2024-09-02 17:56:38 +08:00
Unitwk
31d7637d67 feat: i18n code 2024-09-02 17:29:26 +08:00
Unitwk
ec2963e29d feat: instance tag display 2024-09-02 17:28:06 +08:00
Unitwk
1b02257be8 feat: instance tag search 2024-09-02 17:14:28 +08:00
Unitwk
f35ff84158 feat: tag search 2024-09-02 16:54:14 +08:00
Unitwk
0c8da65d1d feat: instance tag for instance 2024-09-02 15:14:27 +08:00
dependabot[bot]
d3673c7377
Build(deps-dev): Bump webpack from 5.89.0 to 5.94.0 in /daemon
Bumps [webpack](https://github.com/webpack/webpack) from 5.89.0 to 5.94.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.89.0...v5.94.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-02 02:38:23 +00:00
Unitwk
23e083bb06
Merge pull request #1361 from MCSManager/dependabot/npm_and_yarn/panel/webpack-5.94.0
Build(deps-dev): Bump webpack from 5.89.0 to 5.94.0 in /panel
2024-09-02 10:37:24 +08:00
unitwk
0b2f7af67d feat: instance tags btn 2024-09-01 16:47:56 +08:00
unitwk
1f24cded67 refactor: instance node info 2024-09-01 16:08:41 +08:00
unitwk
a8d6947d81 fix: node file manager path err 2024-09-01 15:01:23 +08:00
dependabot[bot]
94874a5a26
Build(deps-dev): Bump webpack from 5.89.0 to 5.94.0 in /panel
Bumps [webpack](https://github.com/webpack/webpack) from 5.89.0 to 5.94.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.89.0...v5.94.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-31 07:59:23 +00:00
Unitwk
2152380d20
Merge pull request #1360 from MCSManager/dependabot/npm_and_yarn/frontend/webpack-5.94.0
Build(deps-dev): Bump webpack from 5.88.2 to 5.94.0 in /frontend
2024-08-31 15:58:20 +08:00
dependabot[bot]
3cffd4c7b3
Build(deps-dev): Bump webpack from 5.88.2 to 5.94.0 in /frontend
Bumps [webpack](https://github.com/webpack/webpack) from 5.88.2 to 5.94.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.88.2...v5.94.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-30 21:34:14 +00:00
Unitwk
23109d98b5
Merge pull request #1358 from MCSManager/abstract
Fix: select disk
2024-08-30 17:45:15 +08:00
Lazy
fbe8e25f82 Fix: select disk 2024-08-30 15:38:20 +08:00
Unitwk
fb5a5a5298 fix: expire time renew 2024-08-30 14:33:38 +08:00
Unitwk
860a5d1e42 chore: interface name 2024-08-30 11:28:43 +08:00
Unitwk
6bc247a98e fix: disk test ignore error 2024-08-30 10:22:23 +08:00
Unitwk
705b4988b0 feat: exchange oss LRU 2024-08-29 14:57:55 +08:00
Unitwk
6c4f49d85e feat: exchange oss 2024-08-29 14:49:13 +08:00
Unitwk
514e921ea4 feat: exchange oss 2024-08-29 11:21:22 +08:00
Unitwk
f539708d8e feat: oss login 2024-08-28 15:25:57 +08:00
Unitwk
83f9b4108c feat: oss login 2024-08-28 15:20:37 +08:00
Unitwk
5bd093ec94 fix: old config update 2024-08-27 16:47:15 +08:00
Unitwk
9170dbc557
Merge pull request #1354 from MCSManager/abstract
Fix: login time
2024-08-27 14:09:45 +08:00
Lazy
cbf5c66d1e Fix: login time 2024-08-27 14:00:24 +08:00
Unitwk
b4e20469ac feat: renew instance check 2024-08-27 11:31:38 +08:00
Unitwk
f54eb4fdb1
Merge pull request #1350 from MCSManager/abstract
Abstract
2024-08-27 10:18:46 +08:00
Lazy
b267922870 Feat: i18n 2024-08-23 22:34:50 +08:00
Lazy
16fe45bd0c Optimize: convert to uppercase 2024-08-23 22:34:37 +08:00
Lazy
6f58cef401 Fix: language 2024-08-23 22:13:47 +08:00
Lazy
8dabd2405f Feat: form rules 2024-08-23 22:08:34 +08:00
Unitwk
98a7097fda feat: getInstancesByUuid() support daemon id 2024-08-23 17:50:12 +08:00
Unitwk
8b79853c47 feat: InstanceInfoProtocol define optimize 2024-08-23 11:39:45 +08:00
Unitwk
51b65b1df6 Feat: protocol Define 2024-08-22 11:39:23 +08:00
Unitwk
c0db6e28e1 Fix: type check 2024-08-21 19:28:18 +08:00
Unitwk
5a54c19806
Merge pull request #1344 from killerprojecte/master
feat: rename duplicate file when user deny overwrite operation
2024-08-21 11:18:53 +08:00
Unitwk
9c41800f53
Merge pull request #1345 from MCSManager/dependabot/npm_and_yarn/frontend/axios-1.7.4
Build(deps): Bump axios from 1.6.2 to 1.7.4 in /frontend
2024-08-19 16:06:40 +08:00
Unitwk
bbb534f703 Feat: get minecraft players (i18n) 2024-08-19 16:06:13 +08:00
Unitwk
27e63eb203 Feat: get minecraft players 2024-08-19 16:04:14 +08:00
dependabot[bot]
f6ab4ed435
Build(deps): Bump axios from 1.6.2 to 1.7.4 in /frontend
Bumps [axios](https://github.com/axios/axios) from 1.6.2 to 1.7.4.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.6.2...v1.7.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-19 03:43:56 +00:00
Unitwk
d9a62e13d0 Refactor: replace "node-disk-info" module 2024-08-19 11:42:55 +08:00
Unitwk
4d74b06b5a Fix: Server-Side Request Forgery in axios 2024-08-19 11:33:15 +08:00
Unitwk
c33a40837b Feat: ping minecraft server support 2024-08-19 11:25:15 +08:00
killerprojecte
43cfca2185 feat: rename duplicate file when user deny overwrite operation 2024-08-18 15:24:39 +08:00
Unitwk
317af39265
Merge pull request #1342 from MCSManager/abstract
Fix: init instance default install path
2024-08-17 20:57:56 +08:00
Lazy
f85ae5eddf Fix: init instance default install path 2024-08-17 14:20:23 +08:00
Unitwk
bcda59c280 Fix: duplicate file uploads 2024-08-14 15:29:34 +08:00
Unitwk
43b39b7544 Fix: pipe name 2024-08-14 14:55:06 +08:00
Unitwk
c2f806e70d Fix: mcping module 2024-08-13 15:03:57 +08:00
Unitwk
aef539633d Fix: https://github.com/MCSManager/MCSManager/issues/1323 2024-08-12 11:43:02 +08:00
unitwk
8958637e08 Feat: i18n 2024-08-12 00:14:00 +08:00
Unitwk
c89a326adf Feat: sponsor tab 2024-08-09 16:30:26 +08:00
Unitwk
45cb00e87b Feat: exchange platform api 2024-08-09 15:34:59 +08:00
Unitwk
e401623e01 Feat: exchange platform api 2024-08-09 10:56:42 +08:00
Unitwk
ea1971b8e2 Fix: nanoId version 2024-08-08 19:36:37 +08:00
Unitwk
b638ee42e4
Merge pull request #1333 from killerprojecte/master
feat: allow users to choose to overwrite existing files
2024-08-08 17:43:12 +08:00
Unitwk
5943039c42
Merge branch 'master' into master 2024-08-08 17:41:18 +08:00
killerprojecte
a89df0266a Improve file overwrite confirm 2024-08-08 16:20:29 +08:00
killerprojecte
65a2664cf7 Optimized implement method, use frontend filemanager to check file 2024-08-08 16:05:32 +08:00
Unitwk
cebd5d281e
Merge pull request #1334 from ChunghwaMC/master
新增 README_JP.md 的連結
2024-08-08 15:14:36 +08:00
Unitwk
d326814e0d Feat: i18n 2024-08-08 12:02:46 +08:00
Unitwk
04c4c97857 Feat: i18n 2024-08-08 12:01:45 +08:00
Unitwk
874ac73a2a Feat: Exchange Platform API 2024-08-08 12:00:10 +08:00
ChunghwaMC
772d9537ee
add README_JP.md link 2024-08-07 23:10:16 +08:00
ChunghwaMC
aed4ac1550
add README_JP.md link 2024-08-07 23:10:03 +08:00
ChunghwaMC
454fdd43bf
add README_JP.md link 2024-08-07 23:09:34 +08:00
ChunghwaMC
cd61d08dc0
add README_JP.md link 2024-08-07 23:09:21 +08:00
killerprojecte
955be538ad feat: allow users to choose to overwrite existing files 2024-08-07 21:56:25 +08:00
Unitwk
5032ce7872
Merge pull request #1325 from LiuMuAoo/maxim-api-key
feat(panel): api-key
2024-08-07 10:25:04 +08:00
Unitwk
2e68959f6c
Merge pull request #1327 from ChunghwaMC/master
補上 zh_TW 的 Feat: Terminal speed limiter 新內容
2024-08-07 10:24:02 +08:00
Unitwk
107dede6b8
Merge pull request #1331 from JianyueLab/master
第一版日语README翻译
2024-08-07 10:23:33 +08:00
JianyueLab
9c2c285f0f
Add files via upload 2024-08-06 14:53:25 -07:00
ChunghwaMC
d6eac1039c
Feat: Terminal speed limiter 2024-08-06 22:33:42 +08:00
LiuMuAoo
7a5c366811 feat(panel): api-key
新增请求头[x-request-api-key]
将apikey放入该请求头中,兼容旧apikey方式
2024-08-06 11:40:24 +08:00
Unitwk
07cde2f488
Merge pull request #1318 from panda2134/docker-socket
feat: compatibility with other docker clients
2024-08-02 16:43:55 +08:00
Unitwk
4dbbba2372 Feat: Terminal speed limiter 2024-08-02 16:33:37 +08:00
Unitwk
3151846809 Fix: type err 2024-08-02 10:47:22 +08:00
Unitwk
1f4e534787 Fix: logout err 2024-08-02 10:41:57 +08:00
Unitwk
7c54c59fc9 Fix: any type check error 2024-08-01 14:59:01 +08:00
Jiangyi Liu
ffecb48b16 fix: typo 2024-08-01 10:25:45 +08:00
Unitwk
f4181c9095
Merge pull request #1317 from XiaoXinYo/master
Fix(frontend):初始化创建账号时弹出错误信息[object Object ]
2024-08-01 10:17:30 +08:00
Jiangyi Liu
3531c17ab3 fix(frontend): refresh network and image list on load
This ensures that if the only network has a name that is not "bridge", the created container still has a valid network assigned
2024-07-31 20:39:29 +08:00
Jiangyi Liu
5bfd42185b feat(daemon): env var for configuring docker host
For compatibility with other container implementations (like podman),
now the docker client respects the value of environment variable
"$DOCKER_HOST", as done by docker CLI.
2024-07-31 18:52:41 +08:00
Yang KaiQi
729709342b
Fix(frontend):初始化创建账号时弹出错误信息[object Object ] 2024-07-31 16:06:11 +08:00
Unitwk
9149c6ecf1
Merge pull request #1312 from UNIkeEN/master
Fix(frontend): use modal to confirm delete user instead of pop-confirm
2024-07-26 18:01:36 +08:00
Unitwk
169397db19 Fix: repoTags null error 2024-07-26 14:47:06 +08:00
UNIkeEN
011061aeb7 Feat: display username on confirm user delete Modal 2024-07-26 09:05:22 +08:00
UNIkeEN
8bbae5a9c2 Fix(frontend): use modal to confirm delete user instead of popconfirm 2024-07-25 22:40:18 +08:00
Unitwk
52ecb939cb
Merge pull request #1307 from MCSManager/abstract
Feat: toml syntax highlight support
2024-07-23 15:14:41 +08:00
Lazy
4c1baf9e25 Feat: toml syntax highlight support 2024-07-23 15:09:03 +08:00
Unitwk
3e03f7d336
Merge pull request #1290 from MCSManager/nya
Feat: node list page add pagination
2024-07-02 20:29:32 +08:00
alongw
02d1fdbf31 Feat: node list page add pagination 2024-07-02 20:20:51 +08:00
Unitwk
81b8290322
Merge pull request #1287 from MCSManager/baka
Fix: fix use zip deploy instance not unzip
2024-07-02 19:20:17 +08:00
alongw
269113538d Feat: remvoe comment 2024-06-30 20:40:07 +08:00
alongw
8ed4529e81 Fix: fix use zip deploy instance not unzip
fixed #1262
2024-06-28 21:50:51 +08:00
Unitwk
a21d92b09f
Merge pull request #1286 from MCSManager/dependabot/npm_and_yarn/daemon/braces-3.0.3
Build(deps-dev): Bump braces from 3.0.2 to 3.0.3 in /daemon
2024-06-28 14:12:54 +08:00
dependabot[bot]
901ec82a24
Build(deps-dev): Bump braces from 3.0.2 to 3.0.3 in /daemon
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-28 06:02:16 +00:00
Unitwk
167c319a51
Merge pull request #1285 from MCSManager/dependabot/npm_and_yarn/common/multi-e091cc75b0
Build(deps): Bump ws, engine.io and socket.io-adapter in /common
2024-06-27 11:25:43 +08:00
dependabot[bot]
5af8827db6
Build(deps): Bump ws, engine.io and socket.io-adapter in /common
Bumps [ws](https://github.com/websockets/ws), [engine.io](https://github.com/socketio/engine.io) and [socket.io-adapter](https://github.com/socketio/socket.io-adapter). These dependencies needed to be updated together.

Updates `ws` from 8.11.0 to 8.17.1
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.11.0...8.17.1)

Updates `engine.io` from 6.5.4 to 6.5.5
- [Release notes](https://github.com/socketio/engine.io/releases)
- [Changelog](https://github.com/socketio/engine.io/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/engine.io/compare/6.5.4...6.5.5)

Updates `socket.io-adapter` from 2.5.2 to 2.5.5
- [Release notes](https://github.com/socketio/socket.io-adapter/releases)
- [Changelog](https://github.com/socketio/socket.io-adapter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io-adapter/compare/2.5.2...2.5.5)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
- dependency-name: engine.io
  dependency-type: indirect
- dependency-name: socket.io-adapter
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-27 03:24:55 +00:00
Unitwk
7f218daf54
Merge pull request #1284 from MCSManager/dependabot/npm_and_yarn/daemon/multi-99ca4f73d8
Build(deps): Bump ws and socket.io-adapter in /daemon
2024-06-27 11:24:12 +08:00
dependabot[bot]
7aa44df4cb
Build(deps): Bump ws and socket.io-adapter in /daemon
Bumps [ws](https://github.com/websockets/ws) and [socket.io-adapter](https://github.com/socketio/socket.io-adapter). These dependencies needed to be updated together.

Updates `ws` from 8.11.0 to 8.17.1
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.11.0...8.17.1)

Updates `socket.io-adapter` from 2.5.2 to 2.5.5
- [Release notes](https://github.com/socketio/socket.io-adapter/releases)
- [Changelog](https://github.com/socketio/socket.io-adapter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io-adapter/compare/2.5.2...2.5.5)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
- dependency-name: socket.io-adapter
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-27 03:23:33 +00:00
Unitwk
3671a7df11
Merge pull request #1281 from Bluemangoo/fix/1183
Fix: several href with prefix
2024-06-27 11:15:07 +08:00
Bluemangoo
3485afa983
Fix: several href with prefix 2024-06-25 12:41:33 +08:00
Unitwk
08d8553fa4
Merge pull request #1276 from MCSManager/dependabot/npm_and_yarn/frontend/braces-3.0.3
Build(deps-dev): Bump braces from 3.0.2 to 3.0.3 in /frontend
2024-06-24 10:42:37 +08:00
Unitwk
90c54d96b2
Merge pull request #1277 from ChunghwaMC/master
修正了中文 Readme 的 Linux 手動安裝錯誤與語意
2024-06-24 10:42:17 +08:00
ChunghwaMC
707cfd87d2
修正 Linux 手动安装 - 安装依赖库 的錯誤 2024-06-23 23:16:02 +08:00
ChunghwaMC
91ba633341
修改錯誤與語意 2024-06-23 23:13:47 +08:00
dependabot[bot]
3ff0df8ae8
Build(deps-dev): Bump braces from 3.0.2 to 3.0.3 in /frontend
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-23 11:53:27 +00:00
Unitwk
33f4ceee4c
Merge pull request #1273 from MCSManager/dependabot/npm_and_yarn/daemon/multi-04f04fdf5e
Build(deps): Bump ws, socket.io and socket.io-client in /daemon
2024-06-23 19:52:57 +08:00
dependabot[bot]
10deb88e38
Build(deps): Bump ws, socket.io and socket.io-client in /daemon
Bumps [ws](https://github.com/websockets/ws) to 8.17.1 and updates ancestor dependencies [ws](https://github.com/websockets/ws), [socket.io](https://github.com/socketio/socket.io) and [socket.io-client](https://github.com/socketio/socket.io-client). These dependencies need to be updated together.


Updates `ws` from 8.11.0 to 8.17.1
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.11.0...8.17.1)

Updates `socket.io` from 4.6.1 to 4.7.5
- [Release notes](https://github.com/socketio/socket.io/releases)
- [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io/compare/4.6.1...4.7.5)

Updates `socket.io-client` from 4.6.1 to 4.7.5
- [Release notes](https://github.com/socketio/socket.io-client/releases)
- [Changelog](https://github.com/socketio/socket.io-client/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io-client/compare/4.6.1...4.7.5)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
- dependency-name: socket.io
  dependency-type: indirect
- dependency-name: socket.io-client
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-22 11:45:59 +00:00
Unitwk
a22ad88ddb
Merge pull request #1272 from ChunghwaMC/master
補上 zh_TW 的 Feat i18n 新內容
2024-06-22 19:44:30 +08:00
ChunghwaMC
64324f268b
Feat i18n 2024-06-22 00:28:31 +08:00
Unitwk
5f7965db64
Merge pull request #1269 from MCSManager/dependabot/npm_and_yarn/panel/braces-3.0.3
Build(deps-dev): Bump braces from 3.0.2 to 3.0.3 in /panel
2024-06-20 19:14:06 +08:00
Unitwk
2b355ba5a2
Merge pull request #1270 from MCSManager/dependabot/npm_and_yarn/frontend/multi-1729a3ee87
Build(deps): Bump ws and engine.io-client in /frontend
2024-06-20 19:13:31 +08:00
dependabot[bot]
be6a904ea1
Build(deps): Bump ws and engine.io-client in /frontend
Bumps [ws](https://github.com/websockets/ws) and [engine.io-client](https://github.com/socketio/engine.io-client). These dependencies needed to be updated together.

Updates `ws` from 8.13.0 to 8.17.1
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.13.0...8.17.1)

Updates `engine.io-client` from 6.5.2 to 6.5.4
- [Release notes](https://github.com/socketio/engine.io-client/releases)
- [Changelog](https://github.com/socketio/engine.io-client/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/engine.io-client/compare/6.5.2...6.5.4)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
- dependency-name: engine.io-client
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-20 03:50:30 +00:00
dependabot[bot]
d7689201a0
Build(deps-dev): Bump braces from 3.0.2 to 3.0.3 in /panel
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-20 03:50:21 +00:00
Unitwk
3c3f5060e7
Merge pull request #1268 from MCSManager/dependabot/npm_and_yarn/panel/multi-d143a95b26
Build(deps): Bump ws, engine.io, socket.io-adapter and engine.io-client in /panel
2024-06-20 11:49:53 +08:00
Unitwk
3fad403b22 Feat: add socket.io error handler 2024-06-20 11:49:02 +08:00
dependabot[bot]
83e9829c6d
Build(deps): Bump ws, engine.io, socket.io-adapter and engine.io-client
Bumps [ws](https://github.com/websockets/ws), [engine.io](https://github.com/socketio/engine.io), [socket.io-adapter](https://github.com/socketio/socket.io-adapter) and [engine.io-client](https://github.com/socketio/engine.io-client). These dependencies needed to be updated together.

Updates `ws` from 8.11.0 to 8.17.1
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.11.0...8.17.1)

Updates `engine.io` from 6.5.4 to 6.5.5
- [Release notes](https://github.com/socketio/engine.io/releases)
- [Changelog](https://github.com/socketio/engine.io/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/engine.io/compare/6.5.4...6.5.5)

Updates `socket.io-adapter` from 2.5.2 to 2.5.5
- [Release notes](https://github.com/socketio/socket.io-adapter/releases)
- [Changelog](https://github.com/socketio/socket.io-adapter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/socket.io-adapter/compare/2.5.2...2.5.5)

Updates `engine.io-client` from 6.5.3 to 6.5.4
- [Release notes](https://github.com/socketio/engine.io-client/releases)
- [Changelog](https://github.com/socketio/engine.io-client/blob/main/CHANGELOG.md)
- [Commits](https://github.com/socketio/engine.io-client/compare/6.5.3...6.5.4)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
- dependency-name: engine.io
  dependency-type: indirect
- dependency-name: socket.io-adapter
  dependency-type: indirect
- dependency-name: engine.io-client
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-20 03:47:20 +00:00
Unitwk
7f761c6183 Feat i18n 2024-06-19 17:43:54 +08:00
Unitwk
2faefa83c4 Feat i18n 2024-06-19 17:43:36 +08:00
Unitwk
3a725bfb74 Feat: Frontend socket check 2024-06-19 17:04:53 +08:00
Unitwk
8441d9591c Merge branch 'master' of github.com:MCSManager/MCSManager 2024-06-19 15:17:55 +08:00
Unitwk
ef63996eac Optimize: Comment Code 2024-06-19 15:17:50 +08:00
Unitwk
ad07fe69b7
Merge pull request #1267 from MCSManager/abstract
Feat: batch restart
2024-06-19 15:12:08 +08:00
Lazy
e0a4b9a9f4 Feat: batch restart 2024-06-19 14:59:57 +08:00
Unitwk
069f6d078d
Merge pull request #1258 from MCSManager/abstract
Abstract
2024-06-12 10:37:12 +08:00
Unitwk
3cc2bc718c
Merge pull request #1255 from luisgbr1el/master
Translating project to Brazilian Portuguese
2024-06-12 10:31:59 +08:00
Lazy
67d7429bf0 Feat: return uuid after creating a user 2024-06-11 22:16:28 +08:00
Lazy
44156a4829 Fix: reset pagination 2024-06-11 22:10:04 +08:00
Unitwk
377ca75aef
Merge pull request #1257 from littleblacklb/master
fix: a wrong word spelling
2024-06-11 18:50:40 +08:00
littleblack LB
dc89a6c9b9
fix: a wrong word spelling 2024-06-10 18:03:51 +08:00
Luis Gabriel Araújo
c95f12f518
Translating README to brazilian portuguese, creating a new README_PTBR.md 2024-06-07 19:11:01 -03:00
Júnior Veras
885429dead
Update README_ZH.md (ADD PORTUGUESE LINK) 2024-06-07 19:01:32 -03:00
Júnior Veras
b094f1de74
Update README_TW.md (ADD PORTUGUESE LINK) 2024-06-07 19:01:29 -03:00
Júnior Veras
8222bbe7c9
Update README.md (ADD PORTUGUESE LINK) 2024-06-07 19:01:27 -03:00
Luis Gabriel Araújo
eba1fb5d0c
Update i18n.ts 2024-06-07 18:41:47 -03:00
Luis Gabriel Araújo
ab4e60485d
Doing some adjusts on brazilian portuguese name and order 2024-06-07 18:30:16 -03:00
Luis Gabriel Araújo
e3e190ec3f
Adding pt_BR language to web backend code 2024-06-07 18:27:43 -03:00
Luis Gabriel Araújo
b8477f851d
Adding lang pt_BR to daemon code 2024-06-07 18:25:24 -03:00
Júnior Veras
4d5e820e92
Update pt_BR.json 2024-06-07 12:53:10 -03:00
Júnior Veras
10942ab81a
Update pt_BR.json 2024-06-07 11:50:09 -03:00
Júnior Veras
98778fbe60
Update pt_BR.json 2024-06-07 11:17:17 -03:00
Júnior Veras
af84b7d8d8
Update pt_BR.json 2024-06-07 10:16:40 -03:00
Luis Gabriel Araújo
6dc5fd7689
Merge pull request #1 from luisgbr1el/patch-1
Adding "Português" language option to frontend
2024-06-05 23:06:13 -03:00
Luis Gabriel Araújo
a2c0605148
Adding "Português" language option to frontend 2024-06-05 23:03:47 -03:00
Luis Gabriel Araújo
63f3eb7be7
Starting to translate to pt_BR 2024-06-05 22:54:00 -03:00
Unitwk
5aa182675e
Merge pull request #1248 from Angels-D/Angels-D
Fixes: Bind2FA Request parameters are incorrect
2024-06-03 19:44:06 +08:00
Angels-D
969030b6e7 Fixes #1243 2024-06-03 18:37:52 +08:00
Unitwk
b7995a77e4
Merge pull request #1238 from Ptr147/master
feat: FileManager Multiple Choice Quantity Tip - resolves #1237
2024-05-27 10:29:10 +08:00
Ptr
ab5ae5f5ac feat: FileManager Multiple Choice Quantity Tip 2024-05-27 07:13:55 +08:00
Unitwk
c4f7816ec3
Merge pull request #1226 from 320778963/master
Fix: 当有配置prefix的时候面包屑跳转错误
2024-05-26 22:36:44 +08:00
Unitwk
c85ca51929
Merge pull request #1225 from MCSManager/abstract
Fix: zip
2024-05-26 22:11:52 +08:00
Mint
da549c53be Fix: 当有配置prefix的时候面包屑跳转错误 2024-05-23 16:14:51 +08:00
Lazy
bb712730d5 Fix: zip 2024-05-23 15:35:09 +08:00
Unitwk
bd43643729
Merge pull request #1224 from yxc0915/patch-1
Update zh_CN.json
2024-05-23 10:36:42 +08:00
yxc0915
5b4560e1a8
Update zh_CN.json
修复翻译错误
2024-05-22 21:54:33 +08:00
Unitwk
f1cda3f923
Merge pull request #1222 from ilbeypoy/ilbeypoy-patch-1
Turkish language added
2024-05-22 10:41:15 +08:00
Unitwk
5b23d54067
Merge pull request #1221 from chunghwamc/master
修改 README_TW.md 成臺灣用語
2024-05-22 10:39:31 +08:00
ilbeypoy
a095e702af
Add files via upload
Turkish language added
2024-05-21 18:43:28 +03:00
chunghwamc
64b08ed209
使 README_TW.md 部份用詞統一 2024-05-21 14:24:38 +08:00
chunghwamc
bd690cf374
將 README_TW.md 修改成臺灣用語 2024-05-21 14:06:14 +08:00
Unitwk
6b17927cf6
Merge pull request #1217 from MCSManager/abstract
Fix: select file
2024-05-20 10:56:06 +08:00
Lazy
fc2022937b Fix: select file 2024-05-17 11:43:36 +08:00
Unitwk
381c58eaf4
Update README.md 2024-05-14 17:07:07 +08:00
Unitwk
7df503bd1b Feat: global terminal disable reset btn 2024-05-13 15:27:32 +08:00
Unitwk
697624c998 Fix: validator check 2024-05-13 15:20:01 +08:00
unitwk
baee1f1c88 Fix: build bat path err 2024-05-12 21:09:38 +08:00
unitwk
efe0a101ef Feat: update version 2024-05-12 14:41:01 +08:00
unitwk
ca7ecba75f Feat: update version 2024-05-12 14:40:34 +08:00
Unitwk
e28fede6fa
Merge pull request #1213 from MCSManager/refactor/docker-update-cmd
Feat: Update comannd support Docker container
2024-05-12 14:40:13 +08:00
unitwk
d0d9e85d77 Fix: error close stream 2024-05-12 14:38:05 +08:00
unitwk
e335750240 Fix: error close stream 2024-05-12 14:27:50 +08:00
unitwk
a86ce00392 Fix: error wait 2024-05-12 14:22:06 +08:00
unitwk
7820568147 Fix: useless import 2024-05-12 13:39:39 +08:00
Unitwk
790b3f5e0d Test: update command action 2024-05-11 11:36:03 +08:00
Unitwk
2380fc2400 Fix: update command action err 2024-05-11 11:32:11 +08:00
Unitwk
e3a8aa02ac Fix: update command stop action err 2024-05-11 11:24:14 +08:00
Unitwk
146c6a15d8 Refactor: update action with docker 2024-05-10 19:14:06 +08:00
Unitwk
227ffc3493 Refactor: update action with docker 2024-05-10 17:47:48 +08:00
Unitwk
1349d31042 Refactor: update action with docker 2024-05-10 17:23:57 +08:00
Unitwk
ef63ae4528 Optimize: source map 2024-05-09 16:05:56 +08:00
Unitwk
fb030941fd Optimize: source map 2024-05-09 16:05:31 +08:00
Unitwk
176b0eba1d Optimize: lazy load static file 2024-05-09 15:52:12 +08:00
Unitwk
65b8c11a7e Refactor: webpack config 2024-05-09 14:48:04 +08:00
Unitwk
634ab0b964 Refactor: install set lang flow 2024-05-09 11:10:50 +08:00
Unitwk
529b08d77a Feat: allowUsePreset default: false 2024-05-08 10:39:11 +08:00
Unitwk
59f3aeaea6 Refactor: update instance command 2024-05-07 19:43:18 +08:00
Unitwk
9b75954273 Fix: Update Command 2024-05-07 15:39:13 +08:00
Unitwk
4fbadbe259 Feat: Quick install support jar file 2024-05-07 15:05:05 +08:00
Unitwk
f9a4d2e158 Fix: cn text 2024-05-07 10:42:33 +08:00
Unitwk
44f419c11c Feat: add new languages 2024-05-06 19:46:13 +08:00
Unitwk
dfce94d315 Feat: add new languages 2024-05-06 19:38:28 +08:00
Unitwk
ea1be3fb47 Feat: add new languages 2024-05-06 19:32:15 +08:00
Unitwk
f576027de7 Feat: add new languages 2024-05-06 19:23:10 +08:00
Unitwk
61a00a1fd9 Feat: add new languages 2024-05-06 16:05:40 +08:00
Unitwk
4a255c5d39 Fix: error i18n 2024-05-06 15:26:53 +08:00
Unitwk
111539d1e6
Merge pull request #1207 from MCSManager/baka
Fix: create instance repeat select node
2024-05-06 10:34:04 +08:00
alongw
8cdde1a3ad Fix: create instance repeat select node 2024-05-01 01:43:35 +08:00
Unitwk
d8c2405bcc Refactor: quickInstallAddr 2024-04-30 15:10:13 +08:00
Unitwk
6e2f6cfb17 Feat: Instance Template 2024-04-30 14:26:50 +08:00
Unitwk
37737bd456 Feat: i18n 2024-04-30 14:14:49 +08:00
Unitwk
fe2e8477ba
Merge pull request #1205 from MCSManager/abstract
Feat: reinstall setting
2024-04-29 16:45:07 +08:00
Lazy
25c08536eb Fix: save status to store 2024-04-29 14:32:26 +08:00
Lazy
feb784d1ab Fix: copy & move file 2024-04-28 23:51:45 +08:00
Lazy
22b4065873 Feat: reinstall setting 2024-04-28 23:15:21 +08:00
Unitwk
9cdf471348 Del: upload file size 2024-04-28 14:35:27 +08:00
Lazy
e9d251ad47 Fix: i18n text 2024-04-28 13:46:33 +08:00
unitwk
ae16e07e2b Feat: install cmd 2024-04-27 22:37:18 +08:00
Unitwk
86dfbc6bde
Update README.md 2024-04-27 22:33:58 +08:00
Unitwk
a9793ce875 Fix: input:-webkit-autofill 2024-04-26 17:05:55 +08:00
Unitwk
80a64250a1
Merge pull request #1200 from IceBrick01/master
Update and Fix Chinese Traditional Translation
2024-04-25 14:21:07 +08:00
Unitwk
8b2c14e017 Feat: Render startCommand with ENV 2024-04-25 14:19:11 +08:00
IceBrick
8c1914e6bb
Feat: Update zh_TW.json 2024-04-25 11:23:31 +08:00
Unitwk
ee19316672 Fix: Modify template process 2024-04-25 11:19:51 +08:00
IceBrick
758c75835c
Merge branch 'MCSManager:master' into master 2024-04-25 11:12:15 +08:00
Unitwk
4b37194ee6 Feat: change text 2024-04-24 19:35:24 +08:00
Unitwk
76e2253529
Merge pull request #1199 from MCSManager/feature/preset-install
Feature/preset install
2024-04-24 17:24:31 +08:00
Unitwk
bf0cd95686 Feat: Select template function 2024-04-24 16:30:22 +08:00
Unitwk
cd8d3777d2 Feat: Select template function 2024-04-24 16:05:26 +08:00
IceBrick
25044f8e22
Update zh_TW.json 2024-04-24 13:31:25 +08:00
IceBrick
0042db539f
Merge branch 'MCSManager:master' into master 2024-04-24 13:30:13 +08:00
Unitwk
7c92b882b6 Feat: i18n 2024-04-24 11:48:03 +08:00
Unitwk
f3380180df Fix: koa-body safe & upgrade formidable 2024-04-24 11:35:36 +08:00
Lazy
6608e25f09 Fix: require daemonId 2024-04-24 09:44:50 +08:00
Lazy
15fa5397a1 Fix: radio style 2024-04-24 09:24:49 +08:00
Lazy
8021f0a9e8 Feat: show all preset list 2024-04-24 09:17:24 +08:00
Lazy
6e04974e6f Opt: component reuse 2024-04-24 00:54:35 +08:00
Lazy
d9bccda215 Feat: reinstall instance ui 2024-04-23 22:24:15 +08:00
Lazy
445e2d2273 Fix: IQuickStart types 2024-04-23 22:22:49 +08:00
Lazy
edc22a6ae3 Fix: validate parameters 2024-04-23 21:04:08 +08:00
Unitwk
5967321ef6 Feat: add instance install function 2024-04-23 17:19:32 +08:00
Unitwk
48628c5c0b Fix: Input Component Type 2024-04-23 14:46:16 +08:00
Unitwk
1c976f944f Optimize: English 2024-04-23 11:04:57 +08:00
IceBrick
8f55e9341b
Update zh_TW.json 2024-04-23 09:41:16 +08:00
Unitwk
321cb77477 Feat: quick install support setupInfo field 2024-04-22 20:16:36 +08:00
Unitwk
86b3c9fddc Feat: quick install support setupInfo field 2024-04-22 20:15:05 +08:00
Unitwk
d219ca3ee0 Fix: two-line-height 2024-04-22 15:42:14 +08:00
Unitwk
7f29aeb5f9
Merge pull request #1195 from MCSManager/abstract
Abstract
2024-04-22 14:12:05 +08:00
Lazy
21bb4d390d Feat: rename emits 2024-04-21 17:02:51 +08:00
unitwk
f1566913c2 Feat: change version 2024-04-21 14:38:04 +08:00
unitwk
18e7b13a37 Feat: i18n code 2024-04-21 14:34:59 +08:00
unitwk
1d34bf7789 Optimize: quickstart for english 2024-04-21 14:29:24 +08:00
unitwk
be0d6152fc Feat: checkDependencies check 2024-04-21 14:15:35 +08:00
unitwk
e925dccf61 Fix: update command err 2024-04-21 12:46:10 +08:00
Lazy
feba4a1315 Fix: save then submit 2024-04-19 11:39:49 +08:00
Lazy
8ada692db6 Fix: save file 2024-04-19 11:35:04 +08:00
Lazy
65681abe3b Feat: get file list when saved file 2024-04-19 11:22:21 +08:00
Lazy
39c9010103 Fix: max edit size 2024-04-19 11:12:24 +08:00
Lazy
a14a72e2e5 Feat: file editor save btn loading 2024-04-18 23:16:32 +08:00
Unitwk
375dc888eb Update: readme.md files 2024-04-18 14:46:19 +08:00
Unitwk
b7d6777648
Create CODE_OF_CONDUCT.md 2024-04-18 11:54:04 +08:00
Unitwk
e62df7c655 Update: readme.md 2024-04-18 11:50:41 +08:00
Unitwk
8cddacdaec
Update README.md 2024-04-18 11:47:48 +08:00
Unitwk
1bcbb075e2
Create SECURITY.md 2024-04-18 11:46:56 +08:00
Unitwk
8f69298407
Create CONTRIBUTING.md 2024-04-18 11:45:02 +08:00
Unitwk
82e77acba8
Update webpack.yml 2024-04-18 11:32:09 +08:00
Unitwk
7843ac7b90 Merge branch 'master' of github.com:MCSManager/MCSManager 2024-04-18 11:28:14 +08:00
Unitwk
c5c59677c5 Optimize: build sh 2024-04-18 11:28:09 +08:00
Unitwk
61736e50cd
Update webpack.yml 2024-04-18 11:15:15 +08:00
Unitwk
b717ac5546
Merge pull request #1187 from Bluemangoo/relative-path
Feat: request api using reletive path
2024-04-18 11:03:56 +08:00
Unitwk
1a51f39a59 Fix: API UUID Err 2024-04-18 10:57:14 +08:00
Bluemangoo
93879d9729
Optimise: path prefix 2024-04-17 12:24:14 +00:00
Unitwk
5557f69dec
Merge pull request #1192 from eya46/py
给editor添加python支持
2024-04-16 10:45:19 +08:00
eya46
b1bc822d2e 添加支持的后缀 pyw 2024-04-15 16:52:35 +08:00
eya46
c01aead34c editor添加python支持 2024-04-15 16:28:38 +08:00
Bluemangoo
0022f54c6f
Feat: path prefix of daemon 2024-04-14 16:17:05 +08:00
Bluemangoo
806cf04034
Feat: path pref config 2024-04-14 08:33:25 +08:00
Bluemangoo
1df59f41a2
Feat: request api using reletive path 2024-04-14 08:18:02 +08:00
Unitwk
0f0c4f4d03 Optimize: issue template 2024-04-09 20:51:02 +08:00
Unitwk
3b9ff531e2 Optimize: issue template 2024-04-09 20:50:28 +08:00
Unitwk
28315bb916 Optimize: issue template 2024-04-09 20:44:39 +08:00
Unitwk
b1d1cd965c Optimize: issue template 2024-04-09 20:40:30 +08:00
Unitwk
c5013b1d33 Optimize: issue template 2024-04-09 20:38:26 +08:00
Unitwk
166bc0006b Optimize: issue template 2024-04-09 20:36:48 +08:00
Unitwk
4aadd9efa4 Optimize issue 2024-04-09 20:35:23 +08:00
Unitwk
d31dbd1435 Feat: optimize issue 2024-04-09 20:30:13 +08:00
Unitwk
d034dad522 Feat: optimize issue 2024-04-09 20:29:05 +08:00
Unitwk
cacc01e644
Update issue templates 2024-04-09 20:16:11 +08:00
Unitwk
3cb4480d64
Merge pull request #1189 from MCSManager/abstract
Abstract
2024-04-09 19:59:16 +08:00
Lazy
627bcd8153 Update FileManager.vue 2024-04-09 17:05:13 +08:00
Lazy
cc5b606807 Opt: use computed 2024-04-09 17:01:14 +08:00
Lazy
6fa194ab9e Opt: operation menu 2024-04-09 16:50:38 +08:00
Lazy
aa2b0147be Fix: delete file 2024-04-09 15:36:53 +08:00
Unitwk
5c5f57aa60
Merge pull request #1190 from IceBrick01/master
Update Chinese Traditional Translation
2024-04-09 14:26:43 +08:00
IceBrick
7d9c874f2b
Update zh_TW.json 2024-04-09 12:20:57 +08:00
IceBrick
82bcb48ee8
Update zh_TW.json 2024-04-09 11:46:56 +08:00
Lazy
677c9493ca Fix: component redundant parameters 2024-04-09 11:36:45 +08:00
Lazy
f4c6c3fb79 Fix: search logic 2024-04-09 11:26:50 +08:00
Unitwk
d64d6009d4
Merge pull request #1186 from Bluemangoo/i18n-fix
Fix: i18n of useInstance
2024-04-09 10:39:07 +08:00
Bluemangoo
620c9e4eba Fix: i18n of useInstance 2024-04-08 08:12:32 +00:00
Unitwk
ba0120a2c1
Merge pull request #1184 from MCSManager/neko
Fix: terminal button group blocking scrollbar
2024-04-08 14:09:48 +08:00
alongw
792b9c77d9 Fix: terminal button group blocking scrollbar
Fixed #1182
2024-04-08 12:54:12 +08:00
Umou
389679781d
Merge pull request #1174 from MCSManager/dependabot/npm_and_yarn/frontend/vite-4.5.3
Build(deps-dev): Bump vite from 4.5.2 to 4.5.3 in /frontend
2024-04-07 10:36:23 +08:00
Umou
56887deaa4
Merge pull request #1175 from IceBrick01/master
Fixes for the Chinese Traditional Translation
2024-04-07 10:36:12 +08:00
Umou
de82842bab
Merge pull request #1176 from landmineHQ/patch-1
Wrong size calculation in file manager
2024-04-07 10:35:03 +08:00
landmineHQ
f792dce8e8
Update FileManager.vue
Wrong calculation method
2024-04-05 17:48:13 +08:00
dependabot[bot]
7c168de25a
Build(deps-dev): Bump vite from 4.5.2 to 4.5.3 in /frontend
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.2 to 4.5.3.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.3/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.3/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-04 02:01:27 +00:00
IceBrick
8cb5b099f5
Update zh_TW.json 2024-04-03 15:34:55 +08:00
IceBrick
07e3022512
Merge branch 'MCSManager:master' into master 2024-04-03 15:25:46 +08:00
Unitwk
e0fad03549 Feat: readme.md 2024-04-03 11:28:12 +08:00
Unitwk
f8b23e6915 Feat: update readme.md 2024-04-03 11:26:19 +08:00
Unitwk
cfefd9bafd Feat: update readme.md 2024-04-03 10:53:16 +08:00
IceBrick
494994b9e2
Update zh_TW.json 2024-04-02 16:18:23 +08:00
IceBrick
5f19e3a166
Update zh_TW.json 2024-04-02 16:10:13 +08:00
Umou
ce68bdfe86
Update README_ZH.md 2024-04-02 15:29:13 +08:00
Umou
5135eea8e0
Update README.md 2024-04-02 15:27:35 +08:00
Umou
413b9d41a4
Merge pull request #1169 from IceBrick01/master
Modify the translation according to Chinese Traditional usage habits
2024-04-01 23:02:41 +08:00
IceBrick
69f1dc28a3
Update zh_TW.json 2024-04-01 21:57:02 +08:00
Unitwk
daf2bbd6b4 Merge branch 'master' of github.com:MCSManager/MCSManager 2024-04-01 20:04:43 +08:00
Unitwk
68da0409fd Fix: Index image 2024-04-01 20:04:37 +08:00
Umou
9bc7e789c4
Merge pull request #1167 from IceBrick01/master
Implement Chinese Traditional to MCSManager 10
2024-04-01 19:25:53 +08:00
IceBrick
925a98c78f
Fixes for the translation 2024-04-01 18:15:46 +08:00
IceBrick
2e38633f03
Update i18-scanner.config.js 2024-04-01 16:00:39 +08:00
IceBrick
573aafc1a9
Update index.ts 2024-04-01 15:59:46 +08:00
IceBrick
3fb375e1fd
Create zh_TW.json 2024-04-01 15:59:10 +08:00
IceBrick
5bab302efd
Update Settings.vue 2024-04-01 15:58:38 +08:00
IceBrick
2b909da87f
Update i18n.ts 2024-04-01 15:57:31 +08:00
IceBrick
8c95e6e95b
Update index.ts 2024-04-01 15:56:35 +08:00
Unitwk
0b9a6bf1dc Fix: type define err 2024-04-01 12:41:29 +08:00
Unitwk
198ab5f6c0 Merge branch 'master' of github.com:MCSManager/MCSManager 2024-04-01 12:32:48 +08:00
Unitwk
2a836e9441 Fix: useless files 2024-04-01 12:32:20 +08:00
Umou
d3a65d43e8
Merge pull request #1164 from MCSManager/dependabot/npm_and_yarn/frontend/follow-redirects-1.15.6
Build(deps): Bump follow-redirects from 1.15.4 to 1.15.6 in /frontend
2024-04-01 11:10:11 +08:00
Umou
3bf99ce05b
Merge pull request #1165 from MCSManager/dependabot/npm_and_yarn/panel/follow-redirects-1.15.6
Build(deps): Bump follow-redirects from 1.15.4 to 1.15.6 in /panel
2024-04-01 11:10:02 +08:00
Umou
1f007a7aac
Merge pull request #1163 from MCSManager/dependabot/npm_and_yarn/daemon/follow-redirects-1.15.6
Build(deps): Bump follow-redirects from 1.15.4 to 1.15.6 in /daemon
2024-04-01 11:09:53 +08:00
dependabot[bot]
757a8ac3ba
Build(deps): Bump follow-redirects from 1.15.4 to 1.15.6 in /panel
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 02:40:41 +00:00
dependabot[bot]
25cd33858f
Build(deps): Bump follow-redirects from 1.15.4 to 1.15.6 in /frontend
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 02:40:24 +00:00
dependabot[bot]
d4fc0aae21
Build(deps): Bump follow-redirects from 1.15.4 to 1.15.6 in /daemon
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-01 02:40:23 +00:00
unitwk
2da1b63c95 Fix: install text 2024-03-31 21:19:30 +08:00
unitwk
d6af1d5a9e Fix: unzip text & delete files bug 2024-03-30 10:02:11 +08:00
unitwk
047e87d36d Fix: unzip text & delete files bug 2024-03-30 09:58:15 +08:00
unitwk
d7ebeddc85 Feat: i18n 2024-03-29 20:20:03 +08:00
unitwk
175cfae87b Feat: golang zip pro 2024-03-29 20:10:41 +08:00
unitwk
6b1eb6c084 Fix: Warning Alert 2024-03-29 16:07:29 +08:00
unitwk
80884524c6 Fix: FileManager toAbsolutePath Permission Check 2024-03-29 14:55:08 +08:00
unknown
e2612067f6
[Doc] en_us - update readme, fix minors. 2024-03-28 12:10:03 +08:00
unknown
d85b48f9b2
[Doc] en_us - update readme 2024-03-28 12:00:10 +08:00
unitwk
12be1ec81a Feat: readme.md 2024-03-27 17:08:17 +08:00
unitwk
02a638bd50 Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2024-03-27 17:02:31 +08:00
unitwk
8adfacce4f Feat: readme.md 2024-03-27 17:02:26 +08:00
Umou
4af1effd3b
Merge pull request #71 from unitwk/abstract
Fix: upload file
2024-03-27 16:50:23 +08:00
Lazy
5c05f7225d Fix: upload file 2024-03-27 15:41:46 +08:00
Umou
21512c2715
Merge pull request #70 from unitwk/abstract
Abstract
2024-03-27 14:33:01 +08:00
Lazy
10bdb8a40f Feat: ignore panel public folder 2024-03-23 22:07:13 +08:00
Lazy
cd17503496 Fix: password length 2024-03-23 22:06:04 +08:00
unitwk
f5a6f8a95c Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2024-03-23 15:31:10 +08:00
Umou
ce238baa53
Merge pull request #69 from unitwk/abstract
Abstract
2024-03-22 10:38:28 +08:00
Lazy
a3d8ec539e Feat: reverse proxy mode 2024-03-22 10:14:40 +08:00
Lazy
ae206e4438 Fix: get real ip 2024-03-20 23:44:46 +08:00
unitwk
4e4631442d Fix: Instance PipeName Err 2024-03-20 19:40:31 +08:00
unitwk
3e66a8282a Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2024-03-19 16:39:41 +08:00
unitwk
49589bee11 Fix: https://github.com/MCSManager/MCSManager/issues/1157 2024-03-19 16:39:37 +08:00
Umou
e6538cf930
Merge pull request #67 from unitwk/nya
Fix: path error when file access error occurs & node error alert style bugs
2024-03-19 15:32:20 +08:00
alongw
e38433bf18 Revert: file manager 2024-03-19 15:27:49 +08:00
unitwk
867c43180c Feat: i18n text 2024-03-19 10:46:21 +08:00
unitwk
20239f0813 Feat: i18n text 2024-03-19 10:45:04 +08:00
unitwk
203ea1046c Fix: english text 2024-03-18 19:56:08 +08:00
alongw
88444bc820 Fix: path error when file access error occurs 2024-03-18 17:10:27 +08:00
alongw
2ec80af08e Fix: node error alert style bugs 2024-03-18 16:41:54 +08:00
unitwk
d68647fe40 Compatible with version 9.X API parameters 2024-03-18 15:27:58 +08:00
unitwk
9e5976024b Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2024-03-16 20:45:53 +08:00
unitwk
7709a989be Merge branch 'refactor-ts' 2024-03-14 16:29:18 +08:00
unitwk
8af7777c8c Feat: 2FA flow test 2024-03-14 16:20:38 +08:00
unitwk
e625b2f369
Merge pull request #63 from unitwk/refactor-ts
Refactor: tsconfig strict: true
2024-03-14 15:54:54 +08:00
unitwk
62fd7ccd7c Fix: Reset User By 2fa 2024-03-14 15:53:12 +08:00
unitwk
5a249eca52 Refactor: tsconfig strict: true 2024-03-14 15:06:51 +08:00
unitwk
d441b8edca Refactor: tsconfig strict: true 2024-03-14 15:02:18 +08:00
unitwk
34cbdab6b1 Refactor: tsconfig strict: true 2024-03-14 15:01:03 +08:00
unitwk
e55f93e8dd Refactor: tsconfig strict: true 2024-03-14 14:31:34 +08:00
unitwk
ae4d2d0516 Refactor: tsconfig strict: true 2024-03-14 14:21:31 +08:00
unitwk
994ea2f58a Refactor: start pty flow err 2024-03-14 11:03:11 +08:00
unitwk
147aab6a26 Feat: support v9 preset 2024-03-13 20:30:35 +08:00
unitwk
b9f9166510 Feat: support v9 preset 2024-03-13 20:26:38 +08:00
unitwk
2dcacc6b6a Feat: delete pty install 2024-03-13 19:52:12 +08:00
unitwk
be75b8de2d Fix: Docker Download Images timeout 2024-03-13 17:53:59 +08:00
unitwk
b5aa91d75c Fix: Docker Download Images timeout 2024-03-13 17:44:33 +08:00
unitwk
4d99679e56 Feat: Settings About Info 2024-03-13 17:18:46 +08:00
unitwk
e182397c95 Fix: reportError -> reportErrorMsg 2024-03-13 14:19:30 +08:00
unitwk
42c2199914 Feat: i18n 2024-03-13 11:42:44 +08:00
unitwk
bfbbb305ed Fix: Stop Command Line 2024-03-13 11:37:07 +08:00
unitwk
3e7307e2a3 Fix: Node Request i18n 2024-03-13 11:31:43 +08:00
unitwk
8a8603b46e Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2024-03-13 10:53:43 +08:00
unitwk
16a6235041 Fix: Docker Stop Err 2024-03-13 10:53:37 +08:00
unitwk
40a50fc855 Fix: win pipe name 2024-03-12 23:06:19 +08:00
unitwk
619756527a Fix: UI tips 2024-03-12 22:41:36 +08:00
unitwk
90cced1475 Feat: Change Version 2024-03-12 20:05:48 +08:00
unitwk
e6ac14ff25 Fix: IO Stream close 2024-03-12 15:43:03 +08:00
unitwk
7a821dd7ad Feat: i18n 2024-03-12 14:53:31 +08:00
unitwk
a41584eeab Refactor: Terminal core 2024-03-12 14:51:13 +08:00
unitwk
6c928ba2aa Refactor: Terminal core 2024-03-12 14:29:23 +08:00
unitwk
3b3974cec0 Refactor: Terminal core 2024-03-12 14:16:15 +08:00
unitwk
f3d2a5397b Feat: env for subProcess 2024-03-11 19:57:26 +08:00
unitwk
99ed130baf Feat: Compatible with version 9.X API parameters 2024-03-11 19:17:40 +08:00
unitwk
21019beb24 Feat: term connected number 2024-03-11 18:03:29 +08:00
unitwk
42d073113b Feat: del stream log 2024-03-11 17:47:16 +08:00
unitwk
70019f8701 Feat: Terminal size sync 2024-03-11 17:40:50 +08:00
unitwk
50a7a5cb9e Feat: pty resize via named pipe 2024-03-11 17:17:44 +08:00
unitwk
161909f0e7 Feat: isLoading status 2024-03-11 11:12:04 +08:00
unitwk
ed4795224a
Merge pull request #61 from unitwk/feature/pty
Feature/pty
2024-03-11 10:45:00 +08:00
unitwk
3d74181699 Fix: Schedule Dialog 2024-03-08 16:49:06 +08:00
unitwk
f0fbef118b Feat: Auto Resize win 2024-03-08 15:50:52 +08:00
unitwk
c90bdcd9cb Feat: Auto Resize win 2024-03-08 15:37:43 +08:00
unitwk
3799186b52 Feat: add resize 2024-03-08 15:19:44 +08:00
unitwk
799c9be80e Feat: Add node-pty 2024-03-08 15:05:40 +08:00
unitwk
4b9a919807 Fix: Dark Code 2024-03-07 17:56:55 +08:00
unitwk
6f8b46db13 Fix: No Permission File Click 2024-03-07 17:38:29 +08:00
unitwk
c1831cbf9e
Merge pull request #60 from unitwk/abstract
Fix: type
2024-03-06 16:11:50 +08:00
Lazy
9f1904230d Fix: type 2024-03-05 22:48:41 +08:00
unitwk
570e25b232 Optimize: terminal design 2024-03-05 20:33:16 +08:00
unitwk
39a3cd7ca1 Optimize: animation 2024-03-05 20:20:01 +08:00
unitwk
b662a82923 Feat: i18n 2024-03-05 19:14:57 +08:00
unitwk
96b54d71be Feat: quick install 2024-03-05 17:54:57 +08:00
unitwk
3864ea1c8e Fix: Instance operator btn 2024-03-05 14:47:40 +08:00
unitwk
aab850fd24 Fix: Instance operator btn 2024-03-05 11:23:52 +08:00
unitwk
12a72a1944
Merge pull request #58 from unitwk/dependabot/npm_and_yarn/frontend/sanitize-html-2.12.1
Build(deps): Bump sanitize-html from 2.11.0 to 2.12.1 in /frontend
2024-03-04 10:31:14 +08:00
unitwk
e1f3a34896
Merge pull request #59 from unitwk/abstract
Abstract
2024-03-04 10:31:04 +08:00
Lazy
da9ae21ea3 Opt: code 2024-03-02 22:36:49 +08:00
Lazy
29eba4db25 Opt: code 2024-03-02 22:36:35 +08:00
Lazy
d489dfead2 Opt: instance operation 2024-03-02 22:32:02 +08:00
Lazy
1c5540970a Feat: instance status 2024-03-02 22:21:26 +08:00
Lazy
f6f17cc57e Opt: instance status code 2024-03-02 22:21:13 +08:00
dependabot[bot]
aaf46cbad5
Build(deps): Bump sanitize-html from 2.11.0 to 2.12.1 in /frontend
Bumps [sanitize-html](https://github.com/apostrophecms/sanitize-html) from 2.11.0 to 2.12.1.
- [Changelog](https://github.com/apostrophecms/sanitize-html/blob/main/CHANGELOG.md)
- [Commits](https://github.com/apostrophecms/sanitize-html/compare/2.11.0...2.12.1)

---
updated-dependencies:
- dependency-name: sanitize-html
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 17:32:39 +00:00
unitwk
e3ad658089
Merge pull request #57 from unitwk/i18n
[Doc] Add some English translations
2024-02-28 20:26:04 +08:00
KevinLu
5f90c364e1
add some English translations & fix some minors 2024-02-28 00:25:53 -05:00
unitwk
7dcd5c2835 Feat: i18n 2024-02-26 17:25:44 +08:00
unitwk
fca2e978ae Fix: file manager right menu auto push selected 2024-02-25 14:45:26 +08:00
unitwk
148265ae8f
Merge pull request #56 from unitwk/abstract
Abstract
2024-02-25 12:32:37 +08:00
Lazy
8200b654b2 Feat: upload confirm 2024-02-25 02:23:45 +08:00
Lazy
643b32a2d4 Refactor: menu list 2024-02-25 02:10:20 +08:00
Lazy
8ba4bb99bb Fix; right menu position 2024-02-25 00:34:05 +08:00
Lazy
be4f718ad8 Feat: complete right menu 2024-02-24 22:54:42 +08:00
Lazy
99d4963e22 Opt: function name 2024-02-24 22:04:12 +08:00
Lazy
a82465f466 Feat: drag to upload 2024-02-24 22:01:25 +08:00
Lazy
a8a3f636b2 Fix: reset upload percent complete 2024-02-24 21:39:23 +08:00
Lazy
e886fc8281 Fix: upload failed error message 2024-02-24 21:37:22 +08:00
unitwk
826adb79e0 Feat: add right menus 2024-02-24 14:01:55 +08:00
unitwk
19793255eb Optz: Terminal bg 2024-02-24 13:00:49 +08:00
unitwk
33f936b9fb Refactor: command history UI 2024-02-24 12:28:50 +08:00
unitwk
94847563bc
Merge pull request #55 from unitwk/nya
Feat: Terminal history command
2024-02-24 12:15:06 +08:00
unitwk
f8c90f72e2 Merge branch 'main' into nya 2024-02-24 12:14:04 +08:00
alongw
72a1a997ea Feat: command history hook 2024-02-23 21:14:02 +08:00
unitwk
0b0c43b921 Dev: right menu 2024-02-23 17:23:42 +08:00
alongw
1e9f20b8d9 Feat: command history hook 2024-02-23 16:32:01 +08:00
unitwk
f1b569bd55 Fix: Docker info area 2024-02-23 15:28:17 +08:00
unitwk
b329731838 Fix: update kill & update cmd save err 2024-02-23 15:21:23 +08:00
unitwk
7752ddff5f Refactor: daemon auth func 2024-02-23 15:06:42 +08:00
unitwk
774362c726 Refactor: routers & services rename 2024-02-23 11:09:40 +08:00
unitwk
7cb881e50e Refactor: routers & services rename 2024-02-23 11:07:03 +08:00
unitwk
3cc56edb5a Del: transform action 2024-02-23 10:51:31 +08:00
alongw
dd4a09213c Feat: terminal history list style 2024-02-23 00:12:23 +08:00
alongw
9edf71e175 Feat: Terminal history command 2024-02-22 21:21:17 +08:00
alongw
0ace3c0161 Feat: Terminal history command 2024-02-22 21:11:30 +08:00
unitwk
02b81fbbd5 Feat: add create instance by docker 2024-02-20 10:54:03 +08:00
unitwk
c589312fc7 Feat: add create instance by docker 2024-02-19 20:10:07 +08:00
unitwk
d9eed72a32 Test: Linux docker test 2024-02-19 17:15:01 +08:00
unitwk
73a982955e Fix: double error info 2024-02-19 16:59:54 +08:00
unitwk
81c009465b Test: Linux docker test 2024-02-19 16:47:24 +08:00
unitwk
044c3e0f3a Test: Linux docker test 2024-02-19 16:46:52 +08:00
unitwk
31e99a3192 Test: Linux docker test 2024-02-19 16:39:53 +08:00
unitwk
67230f0858 Test: Linux docker test 2024-02-19 16:35:46 +08:00
unitwk
6193ad54e1 Test: Linux docker test 2024-02-19 16:24:43 +08:00
unitwk
6bafc8030f Test: Linux docker test 2024-02-19 15:50:08 +08:00
unitwk
691230be01 Test: Linux docker test 2024-02-19 15:40:36 +08:00
unitwk
0ca0021835 Test: Linux docker test 2024-02-19 15:24:56 +08:00
unitwk
73d0e2c1b9 Test: Linux docker test 2024-02-19 15:22:51 +08:00
unitwk
810c0a6861 Test: Linux docker test 2024-02-19 15:20:00 +08:00
unitwk
dd5a66e1a4 Fix: await 2024-02-19 15:05:02 +08:00
unitwk
6d5addced8 Fix: Docker Mounts 2024-02-19 14:16:49 +08:00
unitwk
78c9b5701a Feat: Detail tabs 2024-02-19 11:41:59 +08:00
unitwk
8d4eea861b Feat: docker pull func 2024-02-19 10:54:13 +08:00
unitwk
98256db4a1 Feat: 镜像自动拉取功能 2024-02-18 20:27:11 +08:00
unitwk
4aa94256d5 Feat: docker env & docker workspace config 2024-02-18 15:35:44 +08:00
unitwk
6b0f0ea57e Feat: docker workingDir 2024-02-18 14:40:56 +08:00
unitwk
7f8128f994 Fix: InstanceDetail name & Docker cwd mount 2024-02-18 14:12:38 +08:00
unitwk
21cfcdfcd4
Update README.md 2024-02-18 10:37:28 +08:00
unitwk
9f1451b369
Merge pull request #54 from unitwk/i18n
[Doc] Add readme - en_us
2024-02-18 10:34:46 +08:00
KevinLu
cd4484b577
[Doc] update readme - zh_cn 2024-02-17 02:28:37 -05:00
KevinLu
26dc32b48c
updated readme - en_us 2024-02-17 02:10:14 -05:00
unitwk
5bb929c4f8 Refactor: compressing modules 2024-02-13 16:01:02 +08:00
unitwk
7b2ee6e5bc Refactor: compressing modules 2024-02-13 15:56:52 +08:00
unitwk
76da11697a Feat: hasGolangProcess 2024-02-07 17:11:12 +08:00
unitwk
d9710adff6 Refactor: zip 2024-02-07 15:29:39 +08:00
unitwk
725fd1ebdf Feat: 7zip test 2024-02-06 20:55:10 +08:00
unitwk
38a341ec41 Refactor: chmod dialog 2024-02-06 19:20:02 +08:00
unitwk
4d0c64df25 Refactor: zip/unzip command 2024-02-06 18:58:18 +08:00
unitwk
dc000d433e
Merge pull request #53 from unitwk/abstract
Abstract
2024-02-06 10:46:25 +08:00
Lazy
0a9f2d153f Fix: login submit 2024-02-05 22:19:00 +08:00
Lazy
92d28088c9 Fix: url is null 2024-02-05 22:07:46 +08:00
Lazy
caf156bee7 Optimize: set background image 2024-02-05 22:00:50 +08:00
unitwk
086a21f35a Feat: update readme for mcsm 10 2024-02-05 20:03:35 +08:00
Lazy
1a24c7ee78 Delete: debug code 2024-02-05 19:15:47 +08:00
Lazy
1613225cb4 Feat: edieor fullscreen 2024-02-05 16:47:17 +08:00
Lazy
4735c4011c Optimize: bg colorr 2024-02-05 16:09:44 +08:00
unitwk
435ec7687f Fix: wavesurfer.js package.json error 2024-02-05 15:20:23 +08:00
unitwk
2c40b1c2dc Feat: i18n 2024-02-05 15:19:24 +08:00
unitwk
9c086737b0 Feat: i18n 2024-02-05 15:18:30 +08:00
unitwk
c8721e3181 Feat: i18n 2024-02-05 15:16:06 +08:00
unitwk
55a6548f9b Feat: i18n 2024-02-05 15:14:21 +08:00
unitwk
41fbee2317 Feat: background support warp & baseinfo.vue support id copy 2024-02-05 15:07:49 +08:00
unitwk
8a9089c298 Feat: RCON support 2024-02-04 17:31:24 +08:00
unitwk
73cf3d2127 Feat: RCON Protocol 2024-02-02 18:00:19 +08:00
unitwk
17725f66e8 Feat: 2fa done 2024-02-02 15:30:33 +08:00
unitwk
8e82e7045f Feat: 2FA UI 2024-02-01 18:15:20 +08:00
unitwk
807e259549 Feat: my info PERMISSION_MAP 2024-02-01 16:30:16 +08:00
unitwk
d85198b1c5 Feat: 2FA backend 2024-02-01 16:22:52 +08:00
unitwk
b0877b0700 Feat: 2FA backend 2024-02-01 16:02:02 +08:00
unitwk
8740cbc393 Fix: useKeyboardEvents hooks 2024-02-01 14:28:55 +08:00
unitwk
fe17648f7b
Merge pull request #51 from Bluemangoo/manual-chunks
Feat: manual chunks
2024-01-27 23:47:26 +08:00
unitwk
8f4ca196f3
Merge pull request #52 from unitwk/nya
Fix some bugs
2024-01-27 23:43:42 +08:00
alongw
9e80577b9b Fix: Editor not highlighting the selected area 2024-01-27 20:39:38 +08:00
alongw
3ef56bd4d8 Fix: files in subfolders not downloading properly 2024-01-27 19:43:23 +08:00
Bluemangoo
177697f906
Feat: manual chunks
Improve chunking by split chunks into several small chunks.
It improves loading performance.
2024-01-26 19:28:44 +08:00
unitwk
9d7ed246b9 Feat: add $theme env 2024-01-23 10:46:50 +08:00
unitwk
a43b2173b1 Feat: i18n 2024-01-22 17:35:39 +08:00
unitwk
98d3d3ebe0 Fix: text 2024-01-22 17:32:23 +08:00
unitwk
f2b96f5a40
Merge pull request #49 from unitwk/dependabot/npm_and_yarn/frontend/vite-4.5.2
Build(deps-dev): Bump vite from 4.4.7 to 4.5.2 in /frontend
2024-01-22 11:23:10 +08:00
unitwk
b0d6510f27
Merge pull request #50 from unitwk/nya
Fix(frontend): user instance list information not format & music card error
2024-01-22 11:22:58 +08:00
alongw
5eaa2217ce Fix(frontend): user instance list information not formatted & music card error 2024-01-21 14:57:17 +08:00
unitwk
4b436a5349 Fix: Markdown to html 2024-01-21 13:36:34 +08:00
dependabot[bot]
c7dbc8e608
Build(deps-dev): Bump vite from 4.4.7 to 4.5.2 in /frontend
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.4.7 to 4.5.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v4.5.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v4.5.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-20 03:20:07 +00:00
unitwk
0e7a9b6f16 Fix: resize maxZipFileSize 2024-01-17 17:14:48 +08:00
unitwk
e5517e4806 Feat: add try catch 2024-01-17 14:43:12 +08:00
unitwk
28ce9646db Feat: optimize code 2024-01-17 11:36:33 +08:00
unitwk
6ba705e2a7 Feat: delete useless code 2024-01-17 10:51:07 +08:00
unitwk
410957cd0c Feat: i18n 2024-01-17 10:46:03 +08:00
unitwk
521269fe89 Optimize: i18n 2024-01-17 10:34:06 +08:00
unitwk
01ff8e30c6 Optimize: code 2024-01-16 19:38:53 +08:00
unitwk
782ada4f14 Feat: dark&light bg extend theme 2024-01-16 19:13:40 +08:00
unitwk
962989ca88 Feat: dark&light bg extend theme 2024-01-16 16:50:10 +08:00
unitwk
085703fad5 Refactor: clock card 2024-01-16 11:46:39 +08:00
unitwk
f787de5a93 Refactor: music player 2024-01-16 11:09:50 +08:00
unitwk
9751345f57 Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2024-01-16 10:32:49 +08:00
unitwk
fb5332659b
Merge pull request #48 from unitwk/nya
ClockCard & MusicCard
2024-01-16 10:32:32 +08:00
alongw
04d9e7e7b4 Fix: fixes appearing outside of prompts 2024-01-15 22:20:02 +08:00
alongw
e50c4c2613 Fix: fixes appearing outside of prompts 2024-01-15 21:32:31 +08:00
alongw
f9a4224578 Merge branch 'main' into nya 2024-01-15 21:21:09 +08:00
unitwk
880cb9aa1c
Merge pull request #47 from unitwk/abstract
Optimize: code
2024-01-15 21:18:34 +08:00
alongw
a6dd990721 Feat: rename processing time function 2024-01-15 21:14:14 +08:00
alongw
f17fcf9e0c Feat: musiccard 2024-01-15 21:08:15 +08:00
alongw
8355a18c85 Merge branch 'main' into nya 2024-01-15 21:05:42 +08:00
alongw
13b721a5b1 Feat: clockcard 2024-01-15 21:04:16 +08:00
Lazy
5e6119605a Optimize: code 2024-01-15 20:47:52 +08:00
unitwk
72d40f2643 Feat: add dark bg img mode 2024-01-15 20:37:44 +08:00
alongw
1022086740 Style: adjustment MusicCard position 2024-01-15 20:30:06 +08:00
Lazy
be47f7bd94 Optimize: code 2024-01-15 20:18:18 +08:00
alongw
1535a0258b Feat: ClockCard Style2 2024-01-15 20:06:54 +08:00
Lazy
3a0093c35d Feat: iframe full card 2024-01-15 20:06:03 +08:00
alongw
4b06cd42cc Feat: music player card 2024-01-15 19:50:14 +08:00
Lazy
42a61d4123 Feat: useKeyboardEvents 2024-01-15 19:18:01 +08:00
alongw
f1a6051bd8 Fix: button animation repeating 2024-01-15 15:58:03 +08:00
alongw
d5dd4c18f1 Feat: save ClockCard style 2024-01-15 15:49:38 +08:00
alongw
4d1dd85160 Fix: fix ClockCard change error 2024-01-15 15:45:51 +08:00
alongw
1ad1c00710 Feat: ClockCard Change Style 2024-01-15 15:29:41 +08:00
unitwk
6c89c30948 Optimize: login for phone 2024-01-15 14:54:16 +08:00
unitwk
9b07f1568c Fix: auto open page & npm command 2024-01-15 14:41:51 +08:00
Lazy
58d1762e88 Feat: quick save 2024-01-15 13:32:46 +08:00
Lazy
80601bef27 To be optimized 2024-01-15 00:56:53 +08:00
Lazy
b1e12ac813 Fix: file editor 2024-01-14 23:54:46 +08:00
Lazy
0c706badb4 Merge branch 'main' into abstract 2024-01-14 22:48:20 +08:00
unitwk
68659d7dd8 Optimize: jsonToMap 2024-01-14 22:46:00 +08:00
Lazy
89b44df63b Fix: reject error 2024-01-14 21:52:03 +08:00
Lazy
af18883342 Optimize: update button 2024-01-14 21:45:18 +08:00
unitwk
3dc0be8833 Optimize: phone ui 2024-01-14 19:54:30 +08:00
unitwk
aa0023989f Fix: Terminal UI 2024-01-14 19:27:37 +08:00
unitwk
9aa1c1ce62 Fix: terminal socket.io error with phone 2024-01-14 19:13:32 +08:00
unitwk
a0d901b909 Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2024-01-14 17:37:27 +08:00
unitwk
5d70f49502 Feat: disable socket io reconnect 2024-01-14 17:37:19 +08:00
unitwk
a4c584a230
Merge pull request #42 from unitwk/dependabot/npm_and_yarn/panel/follow-redirects-1.15.4
Build(deps): Bump follow-redirects from 1.15.2 to 1.15.4 in /panel
2024-01-14 17:18:41 +08:00
unitwk
316967da42
Merge pull request #43 from unitwk/dependabot/npm_and_yarn/frontend/follow-redirects-1.15.4
Build(deps): Bump follow-redirects from 1.15.2 to 1.15.4 in /frontend
2024-01-14 17:18:31 +08:00
unitwk
b9f583c7eb
Merge pull request #44 from unitwk/dependabot/npm_and_yarn/daemon/follow-redirects-1.15.4
Build(deps): Bump follow-redirects from 1.15.2 to 1.15.4 in /daemon
2024-01-14 17:18:22 +08:00
unitwk
f86ca39fed
Merge pull request #46 from unitwk/abstract
Fix: banned user login
2024-01-14 17:17:42 +08:00
Lazy
8481edb6fc Feat: clear selected 2024-01-14 01:57:08 +08:00
Lazy
dfc26c0495 Optimize: delete user instance 2024-01-14 01:36:05 +08:00
Lazy
835b0c4778 Fix: select the same instance 2024-01-14 01:28:52 +08:00
Lazy
dfb2665530 Opt: instances list filter 2024-01-14 00:52:33 +08:00
Lazy
e379f71efb Fix: banned user login 2024-01-13 20:41:16 +08:00
Lazy
8ef7cd4e4b Delete: "D" 2024-01-13 19:36:01 +08:00
unitwk
52657675b0
Merge pull request #45 from unitwk/abstract
Fix: DefaultCard addr
2024-01-13 18:30:48 +08:00
Lazy
18241c136b Fix: DefaultCard addr 2024-01-13 18:11:30 +08:00
dependabot[bot]
2b4c76c1ef
Build(deps): Bump follow-redirects from 1.15.2 to 1.15.4 in /frontend
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-11 01:34:37 +00:00
dependabot[bot]
38a3d1c573
Build(deps): Bump follow-redirects from 1.15.2 to 1.15.4 in /daemon
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-11 01:34:37 +00:00
dependabot[bot]
4b94a3d24d
Build(deps): Bump follow-redirects from 1.15.2 to 1.15.4 in /panel
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-11 01:34:28 +00:00
unitwk
06aaa6af16 Merge branch 'term2' 2024-01-10 15:14:31 +08:00
unitwk
7a1e108fc6 Feat: Terminal resize optimize 2024-01-10 15:14:16 +08:00
unitwk
bf368fae63
Merge pull request #41 from unitwk/abstract
Feat: instance list filte
2024-01-10 14:21:54 +08:00
Lazy
e574e71784 Fix: select width 2024-01-10 14:12:00 +08:00
Lazy
2c7ebd4e99 Optimize: copy 2024-01-10 13:03:40 +08:00
Lazy
126a37b847 Fix: select all instance 2024-01-10 10:58:56 +08:00
Lazy
087c566c59 Optimize: between-menus 2024-01-10 00:52:16 +08:00
Lazy
8c527f10bf Feat: instance list filter 2024-01-09 20:56:29 +08:00
unitwk
5550c11050 Feat: termin bug 2024-01-09 20:09:07 +08:00
Lazy
15b58d4426 Optimize: code 2024-01-09 19:56:49 +08:00
unitwk
54f2e9df4f Feat: i18n & dark mode 2024-01-09 17:30:58 +08:00
unitwk
a63ece10bc Feat: i18n text 2024-01-09 15:00:37 +08:00
unitwk
2c8adc4253
Merge pull request #40 from unitwk/i18n
Minor Language File Modification - Login Page
2024-01-09 14:56:38 +08:00
unitwk
2873784c7f Merge branch 'main' into i18n 2024-01-09 14:56:20 +08:00
unitwk
46638b233a
Merge pull request #39 from unitwk/abstract
Fix: docker ports parse
2024-01-09 14:53:14 +08:00
unitwk
307e5483ab Merge branch 'main' into abstract 2024-01-09 14:47:37 +08:00
KevinLu
834d4ba664 added some new translation e.g. login page 2024-01-08 22:02:08 -05:00
unitwk
169e57968d Feat: i18n text 2024-01-09 10:32:00 +08:00
Lazy
6723d8fd89 Fix: dropdown icon 2024-01-09 01:06:42 +08:00
Lazy
44cedab976 Fix: login card min-width 2024-01-09 00:24:05 +08:00
Lazy
544bebad96 Fix: clear Interval 2024-01-08 23:41:46 +08:00
Lazy
8b2e658340 Fix: reset current page 2024-01-08 22:53:57 +08:00
Lazy
a97efa50af Feat: ipv6 support 2024-01-08 22:00:43 +08:00
Lazy
f0795c83d9 Fix: docker ports parse 2024-01-08 19:34:32 +08:00
unitwk
dcd4dd095a Fix: Lazy bug 2024-01-08 11:29:21 +08:00
unitwk
a524211300
Merge pull request #37 from unitwk/abstract
Optimize: Copy button & language
2024-01-08 11:16:49 +08:00
unitwk
043d11045a Merge branch 'main' into abstract 2024-01-08 11:08:43 +08:00
unitwk
75644e7ce7 Sync: en us 2024-01-08 11:07:48 +08:00
unitwk
0c1a3dcf15
Merge pull request #38 from unitwk/i18n
Major Language File Modification - English Translation
2024-01-08 10:57:50 +08:00
KevinLu
6ba399157e added first draft of English translation, and fixed some details. 2024-01-07 21:23:07 -05:00
Lazy
a0cdc37a7b Optimize: language 2024-01-07 20:48:54 +08:00
Lazy
e99d2b907c Optimize: Copy button 2024-01-07 20:37:29 +08:00
Lazy
650f080345 Optimize: apikey 2024-01-07 20:37:06 +08:00
Lazy
2dbd456011 Optimize: languages 2024-01-07 20:07:32 +08:00
Lazy
4adf878bc8 Optimize: language setting 2024-01-07 19:23:32 +08:00
Lazy
cd2358000e Fix: capitalize first letter 2024-01-07 19:15:55 +08:00
Lazy
d01d24d653 Feat: docker info dialog 2024-01-07 17:38:45 +08:00
Lazy
05cb8f2c59 Feat: show docker port 2024-01-07 17:15:51 +08:00
Lazy
cb7d0b6115 Fix: delete node 2024-01-07 16:31:02 +08:00
unitwk
eefb7e4c5d Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2024-01-06 16:52:47 +08:00
unitwk
608c8d9de9 Fix: bug 2024-01-05 18:21:37 +08:00
unitwk
d441e5cf9f Fix: Card h-100 2024-01-05 16:48:30 +08:00
unitwk
12f6b7a8d0 Fix: Card h-100 2024-01-05 16:32:49 +08:00
unitwk
55ad4b2b3c Feat: PASSWORD_REGEX 2024-01-05 15:08:14 +08:00
unitwk
766064750f Fix: Editor dark UI 2024-01-05 11:46:37 +08:00
unitwk
8abff6590a Fix: AntdvConfigProvider 2024-01-05 10:59:51 +08:00
unitwk
aafcd324de Fix: instance bug 2024-01-04 18:16:29 +08:00
unitwk
57db900fb9 Feat: del dev logo 2023-12-31 21:12:46 +08:00
unitwk
6c02c21920 Feat: add open func 2023-12-31 21:07:54 +08:00
unitwk
4cd60ecd87 Fix: new card title & plugincard ui 2023-12-29 17:50:17 +08:00
unitwk
aafebeab53 Optimize: Card & UI 2023-12-29 17:45:37 +08:00
unitwk
80052e6afc Refactor: clock card 2023-12-29 16:29:50 +08:00
unitwk
498b92363c Feat: dark css 2023-12-28 22:19:50 +08:00
unitwk
9abbdb1cd7 Fix: build bat 2023-12-28 22:00:45 +08:00
unitwk
b21f50a0c5 Feat: add titl;e 2023-12-28 21:55:33 +08:00
unitwk
43e1187862 Feat: add pluginCard & sandbox 2023-12-28 16:44:52 +08:00
unitwk
d42adcebc3 Feat: optimize login ui 2023-12-27 16:27:54 +08:00
unitwk
300ad76b46 Feat: optimize login ui 2023-12-27 16:27:24 +08:00
unitwk
eeae5c93d0 Feat: i18n code 2023-12-26 19:55:02 +08:00
unitwk
fa2aa095a8 Feat: i18n code 2023-12-26 19:53:51 +08:00
unitwk
5bf3e7bac9 Feat: config version adapter 2023-12-26 19:49:09 +08:00
unitwk
5747603fea Refactor: user instance ui & validator 2023-12-22 17:50:10 +08:00
unitwk
d3e918b9a7 Refactor: user instance ui & validator 2023-12-22 17:47:21 +08:00
unitwk
fe76c7cd96 Refactor: user detail dialog 2023-12-22 17:28:27 +08:00
unitwk
0fcb60e324 Refactor: reportError func 2023-12-22 17:15:01 +08:00
unitwk
9aefac8f71 Refactor: overview info hooks & api cache 2023-12-21 17:41:38 +08:00
unitwk
e17087a2eb Feat: docker volumes dialog 2023-12-21 14:09:01 +08:00
unitwk
2d66ecd419 Feat: add docker config dialog 2023-12-21 11:11:23 +08:00
unitwk
d36361883f Fix: terminal log err 2023-12-20 11:00:47 +08:00
unitwk
3b459f1d4d
Merge pull request #36 from unitwk/refactor--type
Refactor  type
2023-12-18 17:47:14 +08:00
unitwk
3aaffdc195 Refactor: ant type check 2023-12-18 17:41:03 +08:00
unitwk
06742a3f34
Merge pull request #35 from unitwk/nya
Feat: terminal log & terminal button group
2023-12-16 19:47:03 +08:00
alongw
fd1f32655c Feat: more click scope 2023-12-16 14:43:52 +08:00
alongw
e87472550a Feat: more click scope 2023-12-16 14:41:34 +08:00
alongw
f042e7a057 Feat: terminal button group & clear terminal log 2023-12-16 14:39:05 +08:00
alongw
cb3761d077 Feat: terminal button group & clear terminal log 2023-12-16 14:35:59 +08:00
alongw
f6d940d507 Feat: add instanceHistoryLog show 2023-12-16 13:26:09 +08:00
alongw
04bb67d1eb Revert: delete Mcsmanager 9.0 UI from public 2023-12-16 12:54:35 +08:00
alongw
506402e1c4 feat: add Mcsmanager 9 UI file to panel 2023-12-16 12:48:15 +08:00
unitwk
86ea265e7d Refactor 2023-12-15 17:10:15 +08:00
unitwk
fd61337d97 Optimize: server config ui 2023-12-15 16:00:51 +08:00
unitwk
6486e8086c Feat: auto refresh when edit config 2023-12-15 15:22:51 +08:00
unitwk
f69af39be1 Feat: terminal color 2023-12-15 14:57:03 +08:00
unitwk
fa021f9d32 Fix: type check 2023-12-15 11:48:49 +08:00
unitwk
cfd16fdf8a
Merge pull request #34 from unitwk/abstract
Feat: user list filter
2023-12-15 11:46:16 +08:00
unitwk
da0ab86c0c
Merge branch 'main' into abstract 2023-12-15 11:46:11 +08:00
unitwk
2760578f96 Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2023-12-15 11:38:37 +08:00
unitwk
cd10bd9902 Feat: command assist dialog 2023-12-15 11:38:31 +08:00
Lazy
0adeb3f64c Optimize: select instances 2023-12-14 20:13:56 +08:00
unitwk
c062f06978 Feat: account input autocomplete="off" 2023-12-14 17:26:56 +08:00
Lazy
3a3c194484 Feat: user list filter 2023-12-14 17:19:33 +08:00
Lazy
7b4f596f23 Optimize: username maxlength 2023-12-14 17:01:18 +08:00
Lazy
d5aa22cdae Fix: select theme 2023-12-14 14:38:08 +08:00
unitwk
3d82293143
Merge pull request #33 from unitwk/abandon
Optimize: Code
2023-12-14 10:36:02 +08:00
unitwk
03ccafc996 Merge branch 'main' into abandon 2023-12-14 10:34:41 +08:00
Lazy
dcbaf1e7e4 Feat: edit raw file 2023-12-14 10:33:36 +08:00
Lazy
525a04793f Fix: display system load avg 2023-12-14 10:33:36 +08:00
Lazy
6a6a8e0022 Fix: select style 2023-12-14 10:33:36 +08:00
Lazy
5db6bc2225 Feat: display user uuid 2023-12-14 10:33:36 +08:00
Lazy
0e731835cc Feat: delete user confirm 2023-12-14 10:33:36 +08:00
Lazy
2becbe45e7 Feat: refresh node list 2023-12-14 10:33:36 +08:00
Lazy
723b336273 Feat: copy daemon id 2023-12-14 10:33:36 +08:00
Lazy
fc9a1c833b Feat: try connect node 2023-12-14 10:33:36 +08:00
Lazy
5a2453e96a Feat: create tshock server 2023-12-14 10:33:36 +08:00
Lazy
58df8994d2 Feat: Terraria Tshock translate 2023-12-14 10:33:36 +08:00
unitwk
fbed728039 Merge branch 'main' of github.com:unitwk/MCSManager-v10-Dev 2023-12-14 10:32:00 +08:00
unitwk
b7ac2ef8d5 Feat: add command assistant 2023-12-14 10:31:02 +08:00
Lazy
fdea2202ba Merge branch 'main' of https://github.com/unitwk/MCSManager-v10-Dev 2023-12-13 17:28:38 +08:00
unitwk
dab7b39416 Feat: add cmd assistant dialog 2023-12-12 20:27:09 +08:00
unitwk
8a1a8813de Feat: add cmd assistant dialog 2023-12-12 20:22:44 +08:00
unitwk
381ceb6b86 Refactor: useMountComponent().mount() 2023-12-12 20:02:33 +08:00
unitwk
e67db37bfe Refactor: install page 2023-12-12 17:13:03 +08:00
Lazy
e8e4db6586 Optimize: QuickStartFlow.vue max-height 2023-12-12 17:13:03 +08:00
Lazy
5b0393dca4 Feat: create tshock server 2023-12-12 17:13:03 +08:00
Lazy
c730adb413 Feat: Terraria Tshock translate 2023-12-12 17:13:03 +08:00
wangkun
fd2fbd6e6a Feat: remove useless code 2023-12-12 14:13:19 +08:00
wangkun
13b861765a Refactor: file storage 2023-12-12 11:46:24 +08:00
wangkun
f1eae98244 Feat: i18n text 2023-12-12 11:30:46 +08:00
wangkun
fc44b8ef80 Feat: i18n text 2023-12-12 11:25:01 +08:00
wangkun
2c3b02c768 Fix: install page error & linux load 2023-12-11 20:33:50 +08:00
wangkun
ef5568428b Refactor: install flow 2023-12-11 19:51:40 +08:00
unitwk
ddebdc2e0a
Merge pull request #32 from unitwk/abandon
Feat: Terraria(Tshock) support
2023-12-08 14:11:17 +08:00
Lazy
6a38095713 Optimize: QuickStartFlow.vue max-height 2023-12-08 10:58:34 +08:00
Lazy
2c8794065c Feat: create tshock server 2023-12-08 10:49:24 +08:00
Lazy
8c74e2dfff Feat: Terraria Tshock translate 2023-12-08 10:01:10 +08:00
unitwk
6c2c171f20
Merge pull request #31 from unitwk/abandon
Optimize: BetweenMenus.vue
2023-12-08 09:57:33 +08:00
Lazy
96cd9b94a4 Optimize: node list search 2023-12-07 20:01:22 +08:00
Lazy
6d3241c6f3 Feat: node list search 2023-12-07 19:52:51 +08:00
Lazy
e340547008 Feat: node list filter 2023-12-07 19:30:15 +08:00
Lazy
802444e809 Optimize: user list filter 2023-12-07 15:28:37 +08:00
Lazy
5b06184a88 Feat: user list filter 2023-12-07 15:10:36 +08:00
Lazy
345e0bf363 Optimize: BetweenMenus.vue 2023-12-07 14:35:40 +08:00
unitwk
0fc1dd1f46
Merge pull request #1084 from MCSManager/abandon
Feat: Carousel Card
2023-12-03 17:47:09 +08:00
Lazy
b2825e86a7 deleted: frontend/src/views/Login copy.vue 2023-12-03 16:31:23 +08:00
Lazy
d0a3aed0f2 Merge branch 'next' into abandon 2023-12-03 16:31:05 +08:00
unitwk
840af89188
Merge pull request #1083 from Bluemangoo/clock-panel-fix
Fix: clock card
2023-12-03 16:19:24 +08:00
Lazy
dfd0016bdb Fix: no line breaks 2023-12-03 15:49:17 +08:00
Lazy
feb39f9b54 Feat: show total user 2023-12-03 15:42:21 +08:00
Lazy
7514690ece Optimize: select instance 2023-12-03 15:35:41 +08:00
unitwk
762b90a95f Feat: support open page 2023-12-03 11:58:58 +08:00
unitwk
cadc0637a1 Feat: support open page 2023-12-03 11:56:19 +08:00
bluemangoo
6f49364da9
Fix: clock card 2023-12-03 10:54:08 +08:00
unitwk
98f6b93225 Fix: :scroll="{ x: 'max-content' }" 2023-12-03 09:41:05 +08:00
unitwk
0347eb1392 Optimize: phone ui 2023-12-03 09:38:08 +08:00
Lazy
b7ad5f6a03 Fix: close dialog 2023-12-02 23:18:06 +08:00
Lazy
634172bfcc Feat: Carousel Card 2023-12-02 23:01:17 +08:00
unitwk
9e26f9e66e Refactor: login page 2023-12-02 22:25:12 +08:00
unitwk
19ea7177d9 Refactor: login page 2023-12-02 21:30:21 +08:00
unitwk
68fc8c97ce Refactor: login page 2023-12-02 19:11:22 +08:00
Lazy
360db90365 Optimize: img url path 2023-12-02 01:24:59 +08:00
unitwk
a93a3d40d8 Fix: 1 level user breadcrumbs 2023-12-01 20:47:29 +08:00
unitwk
26edaadf5a
Merge pull request #1082 from MCSManager/abandon
Feat: edit user info
2023-12-01 19:59:49 +08:00
Lazy
4d7c9b72cd Optimize: C0de 2023-12-01 19:09:10 +08:00
Lazy
2f73d95985 Feat: refresh user list 2023-12-01 13:28:08 +08:00
Lazy
994d540b9e Feat: edit user info 2023-12-01 11:58:57 +08:00
Lazy
6f41802c9a Refactor: user types 2023-11-30 20:03:21 +08:00
Lazy
c066828a13 Refactor: user resources 2023-11-30 19:49:00 +08:00
Lazy
6824077ef0 Fix: delete upload files 2023-11-30 19:32:19 +08:00
unitwk
58188a8c9d
Merge pull request #1081 from MCSManager/abandon
Feat: uplaod image
2023-11-30 16:54:19 +08:00
Lazy
2f1988ebe3 Refactor: define constants 2023-11-30 16:41:30 +08:00
Lazy
2086277047 Feat: cancel upload 2023-11-30 16:28:02 +08:00
Lazy
c443b2712b Feat: wipe ass 2023-11-30 16:27:40 +08:00
Lazy
1e1549450a Optimize: file manager operation 2023-11-30 14:15:13 +08:00
Lazy
486c59f388 Optimize: node operations 2023-11-30 13:27:12 +08:00
Lazy
2c86663a45 Optimize: file breadcrumbs style 2023-11-30 11:44:06 +08:00
Lazy
3249d95629 Fix: upload timeout 2023-11-30 11:16:11 +08:00
unitwk
8fa8c24d1d Feat: add workspace "npm install" 2023-11-30 11:05:12 +08:00
Lazy
5f78781ecf Feat: remove upload files 2023-11-29 23:09:50 +08:00
Lazy
f390de613e Feat: upload image 2023-11-29 22:48:06 +08:00
Lazy
64dc34e6eb Fix: breadcrumb length 2023-11-29 13:33:53 +08:00
Lazy
e2d035e95e Fix: open select instance dialog 2023-11-28 14:38:02 +08:00
unitwk
55d334aa30 Feat: i18n code 2023-11-28 11:22:51 +08:00
Lazy
fa8370ee45 Fix: button disabled 2023-11-28 10:07:46 +08:00
unitwk
c41af91a9f Fix: Unknown compiler option 'files' 2023-11-27 20:33:39 +08:00
unitwk
223a534ba9 Optimize: zh_cn text 2023-11-27 20:26:59 +08:00
unitwk
f6d158f819 Fix: log4js support to files 2023-11-27 20:21:20 +08:00
unitwk
093140588f Refactor: define ROLE const 2023-11-27 20:14:12 +08:00
unitwk
51cbdd5696 Feat: panel support file upload 2023-11-27 19:50:08 +08:00
unitwk
6e0be288f8
Merge pull request #1070 from MCSManager/nya
Style: something style
2023-11-19 21:31:09 +08:00
alongw
ca5b24bf4f Style: FileManager style 2023-11-19 20:46:13 +08:00
unitwk
98ba5b9587 Feat: showCardOperator 2023-11-19 14:41:05 +08:00
unitwk
65c28c1409 Feat: add new card pool 2023-11-19 13:42:36 +08:00
unitwk
5fab8b9640 Fix: File upload route 2023-11-18 21:12:30 +08:00
unitwk
85365557ce Feat: layout version update func 2023-11-18 16:38:18 +08:00
unitwk
858763c2c3 Fix: disk display 2023-11-18 15:49:07 +08:00
alongw
524049947f Style: instanceList style 2023-11-18 15:38:47 +08:00
alongw
60d2bce003 Style: instanceList style 2023-11-18 15:28:44 +08:00
alongw
c323239990 Style: instanceList style 2023-11-18 15:27:37 +08:00
alongw
dbe5532815 Style: instanceList style 2023-11-18 15:02:55 +08:00
alongw
41ee819aef Style: instanceList style 2023-11-18 14:39:21 +08:00
alongw
7f46cbd1d9 chore: edit npm dev script 2023-11-18 14:09:52 +08:00
unitwk
f5c10aad18 Optimize: icon 2023-11-17 21:41:50 +08:00
unitwk
5643b38631 Feat: innerCard component support icon 2023-11-17 21:25:09 +08:00
unitwk
15fe2c07f3 Refactor: npm run dev script 2023-11-17 21:03:22 +08:00
unitwk
ac9962f622 Fix: windows call err 2023-11-17 20:54:41 +08:00
unitwk
9c9e8927b0
Merge pull request #1069 from MCSManager/abandon
Fix: route path
2023-11-17 15:30:31 +08:00
Lazy
bd9f3272b2 Fix: route path 2023-11-17 15:28:06 +08:00
unitwk
940984b68a
Merge pull request #1068 from MCSManager/abandon
Feat: to nodes page
2023-11-17 15:25:32 +08:00
Lazy
3cdd61234c Feat: to nodes page 2023-11-17 15:21:14 +08:00
unitwk
1aac828b2b
Merge pull request #1067 from MCSManager/abandon
Optimize: shortcut style
2023-11-17 15:17:02 +08:00
Lazy
8e31869591 Optimize: shortcut style 2023-11-17 14:54:21 +08:00
unitwk
0075c65efb Refactor: Unified Daemon variable name 2023-11-17 13:37:39 +08:00
unitwk
adfe2b494b Fix: select len check 2023-11-17 13:32:17 +08:00
unitwk
a09a5e4310
Merge pull request #1066 from MCSManager/abandon
Feat: instance shortcut card
2023-11-17 13:26:59 +08:00
unitwk
112b010c62 Refactor: Unified Daemon variable name 2023-11-17 13:25:06 +08:00
unitwk
39e6ea569f Refactor: Unified Daemon variable name 2023-11-17 12:59:21 +08:00
unitwk
245462e057 Feat: Get the details of an instance add permission 2023-11-17 12:32:59 +08:00
Lazy
56f3042425 Optimize: restart icon 2023-11-17 00:19:21 +08:00
Lazy
92388b70ba Feat: operation button 2023-11-17 00:18:16 +08:00
Lazy
d7ffd80983 Feat: add instance shortcut 2023-11-16 22:30:46 +08:00
unitwk
a177da765a Feat: del useless logo 2023-11-16 14:07:14 +08:00
unitwk
b6fdd3a707
Merge pull request #1064 from MCSManager/unitwk-patch-3
Update webpack.yml
2023-11-16 11:44:53 +08:00
unitwk
f7e406177b
Update webpack.yml 2023-11-15 21:44:39 -06:00
unitwk
3dcbc6bb51 Fix: delete useless code 2023-11-16 11:37:37 +08:00
unitwk
89b1c9866a
Merge pull request #1063 from MCSManager/refactor-common-module
Refactor common module
2023-11-16 11:15:07 +08:00
unitwk
7a95f640a0 Fix: Severity lib 2023-11-16 11:12:58 +08:00
unitwk
99e93b6f07 Fix: severity lib 2023-11-16 11:02:24 +08:00
unitwk
1a9238033a Fix: Severity lib 2023-11-16 10:57:56 +08:00
unitwk
682fdfd38e Refactor: common code 2023-11-16 10:45:50 +08:00
unitwk
54efaa3e09 Refactor: common code 2023-11-15 21:22:06 +08:00
unitwk
b516b690b8 Refactor: common code 2023-11-15 21:16:25 +08:00
unitwk
ea88552aec Refactor: common code 2023-11-15 21:04:38 +08:00
unitwk
0b6d9950e3 Refactor: common code 2023-11-15 20:38:08 +08:00
unitwk
a0b8944f13 Refactor: common project created 2023-11-15 20:29:31 +08:00
unitwk
ecc77480dc Feat: sync common code 2023-11-15 20:04:52 +08:00
unitwk
adcb208c9f Feat: update en_us 2023-11-15 19:59:48 +08:00
unitwk
34b0949a19 Fix: warning tip 2023-11-15 19:57:57 +08:00
unitwk
01c5d70438 Feat: i18n code 2023-11-15 19:52:58 +08:00
unitwk
a111d6a6c9 Feat: i18n 2023-11-15 19:37:13 +08:00
unitwk
acd6d3db8e Fix: useless code 2023-11-15 19:06:44 +08:00
unitwk
6b923babeb Fix: change ptyWindowCol 2023-11-15 17:54:42 +08:00
unitwk
b1d1759ea2 Fix: upload tmp files not deleted 2023-11-15 17:38:27 +08:00
unitwk
3297bb7066 Refactor: daemon instance dispatcher 2023-11-15 17:28:54 +08:00
unitwk
ecbe25b235
Merge pull request #1062 from MCSManager/abandon
Feat: select disk
2023-11-15 16:57:00 +08:00
unitwk
c145f28b57 Refactor: endtime & dayjs 2023-11-15 16:55:07 +08:00
Lazy
a6e94e4e50 Feat: change disk 2023-11-15 16:43:22 +08:00
Lazy
3914863ff3 Merge branch 'next' into abandon 2023-11-15 12:48:02 +08:00
unitwk
611c66728b Script: i18n code 2023-11-13 20:32:56 +08:00
Lazy
fd4982e08e Optimize: server ip 2023-11-13 20:07:00 +08:00
Lazy
5e3e1042e1 Fix: select offline daemon 2023-11-13 19:45:31 +08:00
unitwk
64a7a2727e
Merge pull request #1060 from MCSManager/abandon
Feat: schedule page
2023-11-13 19:36:33 +08:00
Lazy
eea610aa89 Optimize: code 2023-11-13 19:17:14 +08:00
Lazy
a795a5e735 Optimize: code 2023-11-13 17:36:35 +08:00
Lazy
95020bf62c Optimize: schedule page 2023-11-13 16:21:13 +08:00
Lazy
7b15d519fc Optimize: instance operation menu 2023-11-13 15:45:47 +08:00
Lazy
f2fd7f4146 Feat: update Instance 2023-11-13 15:19:47 +08:00
Lazy
825de48143 Feat: kill instance 2023-11-13 15:03:18 +08:00
Lazy
ddb20ce11d Feat: restart instance 2023-11-13 15:01:34 +08:00
Lazy
d250c298bb Feat: create schedule 2023-11-13 14:01:48 +08:00
Lazy
f42ba4a819 Feat: del schedule 2023-11-12 21:51:46 +08:00
Lazy
649d0147d0 Fix: Capitalize 2023-11-12 21:29:26 +08:00
Lazy
414f0f28ab Feat: get schedules 2023-11-12 21:23:11 +08:00
unitwk
4ca10c3b60 Feat: Fix btn cancel bug 2023-11-12 20:29:42 +08:00
unitwk
99117962d1 Feat: About page & layout btns 2023-11-12 20:19:54 +08:00
unitwk
faf25d8c31 Feat: reset layout btn 2023-11-12 19:23:37 +08:00
unitwk
5713d6caf2 Feat: create card support instance selector 2023-11-11 22:41:16 +08:00
unitwk
ee47fda7d3
Merge pull request #1059 from MCSManager/nya
Refactor: UserList Page
2023-11-11 20:42:55 +08:00
alongw
d03188febb Feat: set spin default indicator 2023-11-11 17:48:35 +08:00
alongw
89b5f9e334 Feat: set spin default indicator 2023-11-11 17:46:04 +08:00
alongw
dbb103d205 Refactor: UserList 2023-11-11 17:15:39 +08:00
alongw
ef26081af9 Refactor: UserList 2023-11-11 17:14:15 +08:00
alongw
d12973a0bc Refactor: UserList 2023-11-11 17:13:30 +08:00
unitwk
c90df420df Feat: add daemon connect error dialog 2023-11-10 20:23:11 +08:00
unitwk
3052764d38 feat: query terminal status 2023-11-10 18:12:44 +08:00
unitwk
fd58b2b7a8 Feat: codemirror support 2023-11-10 17:32:01 +08:00
unitwk
0ce70a22d9 Feat: global terminal support 2023-11-10 15:49:02 +08:00
unitwk
ff850dff74 Feat: new card permission 2023-11-10 11:38:29 +08:00
unitwk
2c80091c0f
Merge pull request #1055 from MCSManager/abandon
Feat: batch operation instance
2023-11-08 22:37:52 +08:00
Lazy
4d0e56a270 Optimize: code 2023-11-08 22:28:08 +08:00
Lazy
13be258283 Fix: find item 2023-11-08 22:10:30 +08:00
unitwk
14b6f82f7b Refactor: language init flow 2023-11-08 15:12:36 +08:00
Lazy
3e5222e53c
Rename usefileManager.ts to useFileManager.ts 2023-11-08 14:13:07 +08:00
unitwk
c287e713f2 Refactor: language flow 2023-11-08 14:08:44 +08:00
Lazy
98847521dc Update components.d.ts 2023-11-08 14:08:32 +08:00
Lazy
fcb0c813ed Optimize: card title 2023-11-08 10:40:31 +08:00
Lazy
347c52c66d Fix: i18n 2023-11-08 10:33:36 +08:00
Lazy
6541549732 Merge branch 'next' into abandon 2023-11-07 20:46:57 +08:00
Lazy
5fd9c3f876 Feat: batch operation instance 2023-11-07 20:29:23 +08:00
unitwk
9d448b61ad Refactor: frontend PageLayoutConfig to backend 2023-11-07 19:08:06 +08:00
unitwk
dac9612397 Refactor: File Manager Hook 2023-11-07 16:16:56 +08:00
unitwk
479b58a57d Feat: add versionChanged status 2023-11-07 15:05:48 +08:00
unitwk
5ad53f11e3 Fix: tsconfig 2023-11-07 14:17:18 +08:00
Lazy
8821002739 Feat: add user icon 2023-11-07 14:10:07 +08:00
unitwk
10adeab6cd Fix: change text 2023-11-06 15:39:36 +08:00
unitwk
d4b9529c5d Refactor: rename mc_process_config files etc 2023-11-06 15:19:51 +08:00
unitwk
af8a25bcb5 Fix: terminal wrapper css 2023-11-06 14:51:03 +08:00
unitwk
083de6e4dc
Merge pull request #1052 from MCSManager/nya
Feat: refactoring configuration files
2023-11-06 10:39:30 +08:00
alongw
71e68dc30c Feat: remove eula tips & edit config type 2023-11-05 22:49:29 +08:00
alongw
6313675130 feat: add more config 2023-11-04 21:41:24 +08:00
alongw
d357a1e940 feat: config add paper.yml 2023-11-04 17:40:32 +08:00
alongw
6bd723aefa feat: add bungeecord/config.yml 2023-11-04 17:23:32 +08:00
alongw
b2eca11db4 feat: server profile editor 2023-11-04 17:03:45 +08:00
alongw
3deabd1707 refactor: server profile editor 2023-11-04 16:36:17 +08:00
unitwk
1fef03da48
Merge pull request #1049 from MCSManager/abandon
Feat: server config overview & edit
2023-10-31 21:48:27 -05:00
Lazy
92badf3483 Optimize: config type 2023-10-31 16:33:01 +08:00
Lazy
717c69e09d Optimize: code 2023-10-31 16:30:41 +08:00
Lazy
798fb85ce9 Merge branch 'abandon' of https://github.com/MCSManager/MCSManager into abandon 2023-10-31 16:26:20 +08:00
Lazy
fa53d5304b Feat: add i18n 2023-10-31 16:26:17 +08:00
Lazy
a64834d3ab Feat: add i18n 2023-10-31 16:25:07 +08:00
Lazy
9e119763d1 Optimize: rename 2023-10-31 16:07:58 +08:00
Lazy
7d47394321 Optimize: LineOption 2023-10-31 16:04:55 +08:00
Lazy
c1a1de639a Delete: 中文注释 2023-10-31 16:01:19 +08:00
Lazy
0ee0b0402f Fix: route to file manager 2023-10-30 19:15:11 +08:00
Lazy
e77cfb50b1 Feat: add bungeecord.config.yml translation 2023-10-30 19:12:06 +08:00
Lazy
ae1a14bab8 Feat: add bds_server.properties translation 2023-10-30 14:01:59 +08:00
Lazy
25a12e37ce Delete: 关于配置兼容与翻译 2023-10-30 13:15:33 +08:00
Lazy
6910cd1b45 Feat: add bukkit.yml translation 2023-10-30 13:11:40 +08:00
Lazy
b69331c960 Fix: get config file 2023-10-30 12:56:01 +08:00
Lazy
00eb53ee8d Feat: add server.properties translation 2023-10-30 00:07:44 +08:00
Lazy
cbfdaaa585 Feat: save config file 2023-10-29 23:04:46 +08:00
Lazy
51d336b973 Fix: misspell 2023-10-29 22:51:39 +08:00
Lazy
ad31e054cf Feat: show config file 2023-10-29 22:33:32 +08:00
Lazy
8dfb6cfc44 Fix: error message 2023-10-28 21:39:20 +08:00
Lazy
dcda4e35bd Optimize: instance config list 2023-10-28 21:35:17 +08:00
Lazy
03760c754c Feat: get instance config list 2023-10-28 10:58:02 +08:00
unitwk
a7f87f59c4 Feat: layout config save function 2023-10-26 17:49:45 +08:00
unitwk
cb949e7bc3 Feat: layout config save 2023-10-24 16:18:51 +08:00
unitwk
a78a586f09 Fix: install page ui 2023-10-24 11:22:57 +08:00
unitwk
95b963f497
Merge pull request #1047 from MCSManager/abandon
Feat: install page
2023-10-24 10:49:20 +08:00
unitwk
66dcd6fc15 Merge branch 'next' into abandon 2023-10-24 10:48:08 +08:00
Lazy
c0faa5e681 Optimize: background skeleton 2023-10-24 09:22:31 +08:00
Lazy
7030ab18c6 Fix: button margin 2023-10-21 20:15:29 +08:00
Lazy
f26cf94c52 Optimize: pwd format verification 2023-10-21 20:09:12 +08:00
Lazy
7f940743b1 Fix: auto login 2023-10-21 20:05:47 +08:00
Lazy
5caa590d6c Feat: panel install 2023-10-21 17:31:06 +08:00
Lazy
bd39cd0ba8 Fix: misspell 2023-10-20 15:02:31 +08:00
Lazy
1c2c1145e8 Merge branch 'abandon' of https://github.com/MCSManager/MCSManager into abandon 2023-10-20 14:48:36 +08:00
unitwk
a90f11867c
Merge pull request #1044 from MCSManager/abandon
Feat: image manager
2023-10-20 14:22:25 +08:00
Lazy
29447daf99 Optimize: get image list error 2023-10-19 20:38:37 +08:00
Lazy
32e29d0d1f Fix: i18n 2023-10-19 20:27:07 +08:00
unitwk
81d0c457e4 Feat: create install page 2023-10-19 20:17:46 +08:00
Lazy
3fa6114bbb Feat: add build progress 2023-10-19 16:53:32 +08:00
Lazy
c1b8343a93 Feat: add new image 2023-10-19 15:59:18 +08:00
Lazy
b91d455e7a Feat: add NewImage page 2023-10-19 13:11:30 +08:00
Lazy
62a468cfa1 Feat: copy id 2023-10-19 12:27:26 +08:00
Lazy
d22b69dc27 Feat: move ImageManager 2023-10-19 12:24:12 +08:00
Lazy
c4a169b1ac Feat: add container list 2023-10-18 23:12:40 +08:00
Lazy
6721f1e271 Feat: delete image 2023-10-18 22:54:33 +08:00
Lazy
eb01bd67a0 Optimize: image list 2023-10-18 21:13:41 +08:00
Lazy
942cc30a86 Feat: add ImageManager 2023-10-18 21:01:04 +08:00
Lazy
26c945b6fc Optimize: rename ImageList api 2023-10-18 17:30:22 +08:00
Lazy
09c1dbd55d Feat: to Page
Terminal, FileManager
2023-10-18 13:54:24 +08:00
unitwk
17b635f9c7
Merge pull request #1042 from MCSManager/abandon
Feat: select instances
2023-10-18 11:19:34 +08:00
Lazy
3ba3d2b293 Optimize: code 2023-10-17 19:59:46 +08:00
unitwk
154b3acdf3
Merge pull request #1038 from MCSManager/nya
Feat: refactoring FileManager & modify file permissions
2023-10-17 17:51:58 +08:00
Lazy
c19ec75232 Optimize: select instances 2023-10-17 16:20:09 +08:00
Lazy
10020b59ad Feat: add custom mount component 2023-10-17 16:16:46 +08:00
Lazy
6abe0c37d0 Optimize: instance status 2023-10-17 11:19:22 +08:00
Lazy
7942f310f7 Feat: select instances 2023-10-17 11:06:23 +08:00
alongw
6929d3a3e2 Feat: remove some code 2023-10-16 23:09:14 +08:00
Lazy
8e651f1c60 Optimize: user list 2023-10-16 12:38:04 +08:00
alongw
b7d4798896 Feat: dialog style object 2023-10-15 13:28:13 +08:00
alongw
cea5fb9664 Feat: dialog style 2023-10-15 13:11:59 +08:00
alongw
befdc7266c Feat: checkbox style 2023-10-15 12:43:39 +08:00
alongw
b98a0adede Feat: optimized code 2023-10-15 02:25:20 +08:00
alongw
f4e5079542 Feat: refactoring FileManager & modify file permissions 2023-10-15 02:04:37 +08:00
alongw
2ad6ab4f4f Feat: extraction code 2023-10-14 23:47:15 +08:00
alongw
870cf20d2f Feat: extraction code 2023-10-14 22:33:17 +08:00
alongw
4ea1cb13ac Feat: extraction code 2023-10-14 22:32:45 +08:00
alongw
b7bc00d8e3 Merge branch 'next' into nya 2023-10-14 20:55:02 +08:00
alongw
4d7583d527 Feat: Extraction code 2023-10-14 20:52:52 +08:00
unitwk
51a4273d42
Merge pull request #1036 from MCSManager/abandon
Feat: file edit
2023-10-14 15:27:35 +08:00
Lazy
8cb053b390 Optimize: fileManager api 2023-10-14 15:12:10 +08:00
Lazy
ff451aaab5 Fix button color 2023-10-14 14:59:02 +08:00
Lazy
7a80a9c6c7 Merge branch 'next' into abandon 2023-10-14 11:28:20 +08:00
Lazy
930deb49ec bad highlight 2023-10-14 11:27:56 +08:00
Lazy
a11fdb45b9 Fix: folder can't edit 2023-10-14 11:27:00 +08:00
Lazy
6a76f8ac3f Feat: save file 2023-10-13 16:26:16 +08:00
Lazy
e310d8a271 Feat: add get file content 2023-10-13 10:50:43 +08:00
Lazy
7bfe043f64 Delete: download confirm 2023-10-13 10:49:39 +08:00
unitwk
31b843488b
Merge pull request #1035 from MCSManager/abandon
Feat: add quick creating minecraft instance
2023-10-12 22:03:05 +08:00
Lazy
50d4a7d3c7 Optimize: code 2023-10-12 22:01:16 +08:00
Lazy
f1853a58e2 Merge branch 'next' into abandon 2023-10-12 17:30:10 +08:00
Lazy
e1baa54639 Feat: add creating mc instance 2023-10-12 17:29:03 +08:00
unitwk
6877b79a27 Feat: 添加基本代码编辑框 2023-10-11 21:52:58 +08:00
Lazy
a861046a3e Optimize: action buttons 2023-10-10 22:39:10 +08:00
Lazy
171082ba50 Optimize: line height 2023-10-10 22:33:48 +08:00
unitwk
7e10c9193b Fix: drag mode error 2023-10-10 21:15:52 +08:00
Lazy
a67783d4ba Feat: add file download 2023-10-10 16:50:50 +08:00
unitwk
2e5b54b19c
Merge pull request #1034 from MCSManager/abandon
Optimize: file manager
2023-10-10 16:26:19 +08:00
Lazy
37a72eb758 Feat: add monaco-editor 2023-10-10 15:52:47 +08:00
Lazy
4ddc3e08cf Feat: open FileEditor dialog 2023-10-10 15:04:01 +08:00
Lazy
c5bc1956e1 Optimize: align left 2023-10-09 16:48:12 +08:00
Lazy
cfa9158c33 Feat: add file icon 2023-10-09 13:38:49 +08:00
Lazy
4bd41fc28c Feat: add get extame 2023-10-09 10:36:01 +08:00
unitwk
84a3923a61
Merge pull request #1032 from yzy613/patch-1
feat(docker_start.ts): sync assign hostname
2023-10-09 09:28:40 +08:00
unitwk
314aec6661
Merge pull request #1031 from MCSManager/abandon
Feat: optimize creation methods
2023-10-09 09:26:48 +08:00
Lazy
245ad7b31c Optimize: progress style 2023-10-09 09:12:35 +08:00
Lazy
2784d4891c Fix: request data 2023-10-09 00:44:34 +08:00
Lazy
78b11b90db Feat: upload file 2023-10-09 00:44:14 +08:00
Lazy
9d9b421e22 Optimize: computeNodeName 2023-10-08 22:06:32 +08:00
Lazy
0fd43ffc86 Feat: change current node 2023-10-08 22:06:07 +08:00
Lazy
6affb4eb8b Optimize: logic 2023-10-08 21:05:52 +08:00
Lazy
1e2b6ec3ce Feat: optimize creation methods 2023-10-08 18:32:11 +08:00
yijiong
9ee690edaa
feat(docker_start.ts): sync assign hostname 2023-10-08 18:30:50 +08:00
unitwk
318205fe94 Optimize: ui 2023-10-08 10:37:42 +08:00
unitwk
49c0cf2193
Merge pull request #1030 from MCSManager/abandon
Feat: create instance
2023-10-08 10:07:27 +08:00
Lazy
f3cb59360f Optimize: zipCode type 2023-10-08 10:07:01 +08:00
Lazy
cc2a11e653 Feat: add unzip option 2023-10-07 22:54:18 +08:00
Lazy
a2792eb6dd Feat: add creating method 2023-10-07 21:53:55 +08:00
Lazy
bddd2f654a Fix: no i18n 2023-10-07 21:51:25 +08:00
Lazy
99702f4146 Feat: create instance 2023-10-07 20:58:23 +08:00
Lazy
888ea09759 Optimize: prompt text 2023-10-07 20:57:16 +08:00
Lazy
82ba10708b Feat: add link to create app page 2023-10-06 22:43:17 +08:00
Lazy
c1b663ba7f Feat: add select unzip code dialog 2023-10-06 22:31:39 +08:00
unitwk
d06bd6f981 Fix: isReady error 2023-10-06 12:15:43 +08:00
unitwk
5287f5dc87
Merge pull request #1025 from MCSManager/nya
Feat: file manager
2023-10-04 21:58:00 +08:00
alongw
9ed671357a Feat: remove comment 2023-10-04 13:21:44 +08:00
alongw
f26190b0ab Feat: remove comment 2023-10-04 13:20:11 +08:00
alongw
2894ec7290 Feat: file manager 2023-10-04 00:06:07 +08:00
alongw
9b773adcc7 Feat: mkdir & file 2023-10-03 16:46:24 +08:00
alongw
4346146b3a Feat: mkdir 2023-10-03 03:08:07 +08:00
alongw
d54327d54a Feat: file interaction 2023-10-03 02:33:21 +08:00
alongw
23448d8d75 Feat: entering and exiting folders 2023-10-03 01:37:36 +08:00
alongw
2c36ee38c1 Feat: optimize table rendering details 2023-10-03 00:26:41 +08:00
alongw
974afd3fe4 Feat: get file list 2023-10-02 23:18:26 +08:00
unitwk
a38c31d771 Feat: permission router 2023-09-27 17:09:51 +08:00
unitwk
dcae252cd3 Fix: api/instance permission 2023-09-25 11:28:54 +08:00
unitwk
2afc06b33f Refactor: remove ErrorCard component 2023-09-24 15:12:46 +08:00
unitwk
7f37fc1c1e Fix: instance text 2023-09-24 15:11:26 +08:00
unitwk
3a36c5c9fa Merge branch 'feature/error' into next 2023-09-24 15:07:53 +08:00
unitwk
5013e61fad feat: quickstart + fade up animation 2023-09-24 15:06:51 +08:00
unitwk
7118a0039d Refactor: instance detail dialog 2023-09-24 14:10:49 +08:00
unitwk
3458dff436 Merge branch 'next' of github.com:MCSManager/MCSManager into next 2023-09-23 20:24:04 +08:00
unitwk
1ea6f5fc8d Feat: 2023-09-23 20:23:54 +08:00
unitwk
2feb07fecf
Merge pull request #1021 from MCSManager/abandon
Feat: something new
2023-09-23 20:09:37 +08:00
unitwk
3eaf6fd06b feat: create flow, itor 1 2023-09-23 19:25:09 +08:00
Lazy
a6547ea109 Optimize: dialog scroll 2023-09-23 16:01:38 +08:00
Lazy
3d11d8f644 Feat: add get docker network mode list 2023-09-23 15:32:14 +08:00
Lazy
61cef923ca Feat: add form validation 2023-09-23 14:37:26 +08:00
Lazy
8637b4010c Optimize: scrollbar 2023-09-22 21:41:42 +08:00
Lazy
41c6d6b5ee Feat: add get docker image list 2023-09-21 21:36:23 +08:00
Lazy
aa4ae683c7 Fix: wrong type 2023-09-21 20:23:13 +08:00
Lazy
68e12b4544 Feat: add require field style 2023-09-21 15:22:33 +08:00
Lazy
f5d0cf0a16 Feat: add save instance config 2023-09-21 15:14:15 +08:00
Lazy
6e2f849321 Feat: add start counts 2023-09-21 13:42:38 +08:00
Lazy
e66cf71ef1 Feat: add instance detail dialog 2023-09-21 11:34:42 +08:00
unitwk
1ffec7046d Fix: del useless code 2023-09-20 20:35:00 +08:00
unitwk
cc1ad3d484 Refactor: ManagerBtns.vue 2023-09-20 20:28:58 +08:00
unitwk
9974bdac23
Merge pull request #1020 from MCSManager/abandon
Feat: add dialogs
2023-09-20 20:10:35 +08:00
Lazy
edf3e30ba6 Feat: optimized code
fix: reactivity
2023-09-20 17:21:26 +08:00
Lazy
d19d8bd0e9 Feat: optimized code 2023-09-20 13:39:40 +08:00
Lazy
c3834dc12b Merge branch 'next' into abandon 2023-09-19 22:08:32 +08:00
Lazy
48319aada3 Feat: optimized code 2023-09-19 22:07:22 +08:00
Lazy
5eedfd536f Feat: optimized code 2023-09-19 21:51:20 +08:00
Lazy
d087c1fac6 Feat: add ping config 2023-09-19 21:36:00 +08:00
Lazy
25fada03e3 Feat: add event config 2023-09-19 20:57:02 +08:00
Lazy
d059dadc12 Feat: interface renaming 2023-09-19 20:56:37 +08:00
Lazy
6eb6eb7990 Feat: fix wrong label 2023-09-19 20:21:12 +08:00
Lazy
693836a678 Feat: move TermConfig.vue 2023-09-19 20:10:58 +08:00
unitwk
e3adbb738b
Merge pull request #1016 from MCSManager/abandon
Feat: add terminal config
2023-09-18 10:24:22 +08:00
Lazy
83290c9083 Merge branch 'chino' into abandon 2023-09-17 16:26:01 +08:00
Lazy
ae295d21f9 Feat: add update terminal config 2023-09-17 16:16:34 +08:00
unitwk
201fea79db feat: merge menu 2023-09-17 14:20:33 +08:00
unitwk
fa3c5adbc3
Merge pull request #1012 from Bluemangoo/instance-list
Instance list
2023-09-17 13:53:23 +08:00
Lazy
8e0722e470 Feat: add terminal config 2023-09-17 12:09:18 +08:00
bluemangoo
d2fc0ccaaf
Feat: instance list - get data & remove 2023-09-17 10:09:41 +08:00
unitwk
0148c58e44
Merge pull request #1014 from MCSManager/chino
Feat: Consumer Page
2023-09-17 00:28:04 +08:00
alongw
66e66ce1f1 Feat: optimized code 2023-09-17 00:15:44 +08:00
alongw
9067ef9e77 Feat: optimized code 2023-09-17 00:10:24 +08:00
alongw
94cf34f09b Feat: optimized code 2023-09-17 00:06:14 +08:00
alongw
6d9885b459 Feat: optimized code 2023-09-16 23:59:25 +08:00
alongw
4a4f900717 Merge branch 'next' into chino 2023-09-16 20:14:29 +08:00
alongw
e30853bec5 Feat: consumer page 2023-09-16 20:13:53 +08:00
alongw
bfe1730fba Feat: userStatusBlock 2023-09-16 19:01:39 +08:00
unitwk
c81d6b4b73 Feat: add onErrorCaptured 2023-09-10 11:26:56 +08:00
bluemangoo
809223ad37
Feat: add error card 2023-09-10 11:01:10 +08:00
unitwk
40ee4bfa89 Fix: auto refreshOverviewInfo 2023-09-09 16:39:16 +08:00
unitwk
bf8791893a
Merge pull request #1010 from MCSManager/chino
Feat: node list
2023-09-09 13:52:38 +08:00
alongw
b0ae78f5f9 Feat: delete node and edit node 2023-09-09 01:14:27 +08:00
alongw
67feaa4f05 Feat: delete node and edit node 2023-09-09 01:11:23 +08:00
alongw
53485dcf67 Feat: add node 2023-09-08 23:57:09 +08:00
alongw
b815af387c Feat: logout 2023-09-08 22:58:07 +08:00
unitwk
ba5fbbf11b Feat: i18n 2023-09-06 15:38:17 +08:00
unitwk
736a71b130 Feat: i18n 2023-09-06 15:30:31 +08:00
unitwk
908037c14a Refactor: i18n key text 2023-09-06 14:54:57 +08:00
unitwk
095911201b Refactor: i18n key text 2023-09-06 11:53:01 +08:00
unitwk
dbd2a672db Fix: i18next scanner config 2023-09-06 11:32:08 +08:00
unitwk
398e51b87a Fix: i18next scanner config 2023-09-06 11:25:24 +08:00
unitwk
df6c7d307f Feat: move i18next config 2023-09-05 20:00:35 +08:00
unitwk
9feda9ceb7
Merge pull request #1008 from MCSManager/feature/language-union
Feat: language files refactor
2023-09-05 19:39:25 +08:00
unitwk
7667fb13e0 Feat: support global languages 2023-09-05 19:31:41 +08:00
unitwk
434aeae3c8 Feat: support global languages 2023-09-05 19:21:23 +08:00
unitwk
07931f899c Feat: daemon support global languages 2023-09-05 18:47:10 +08:00
unitwk
db81fa3334 Feat: vite global support 2023-09-05 16:03:00 +08:00
unitwk
17720d32c0 Feat: add global language 2023-09-05 15:54:19 +08:00
unitwk
73d8020f4d Feat: add global language 2023-09-05 15:18:57 +08:00
unitwk
220f36115c Feat: instance search & overinfo table 2023-09-03 18:06:43 +08:00
unitwk
d5f64afb7f Refactor: overview api 2023-09-03 17:39:58 +08:00
unitwk
7db91a9cf2 Try fix echart build error 2023-09-03 16:47:44 +08:00
unitwk
d83183f0ae Try fix echart build error 2023-09-03 16:46:51 +08:00
unitwk
c2f7c6af47 Fix: echarts import 2023-09-03 12:22:04 +08:00
unitwk
eb09b65ee6 Fix: table delete not refresh 2023-09-03 12:13:47 +08:00
unitwk
73750b1070
Merge pull request #1004 from MCSManager/chino
Feat: user list
2023-09-03 12:06:44 +08:00
unitwk
85340a390d Feat: support errorAlert config 2023-09-03 12:05:05 +08:00
alongw
346fc74b51 Feat: optimized code 2023-09-03 11:58:45 +08:00
alongw
bc7c8f5bb5 Feat: optimized code 2023-09-03 11:58:02 +08:00
alongw
6fbeabae21 Feat: optimized code 2023-09-03 11:54:34 +08:00
unitwk
c3ec7f1326 Feat: Node List Chart 2023-09-03 11:46:54 +08:00
alongw
b79a38a27b Fix: search page does not reset 2023-09-03 00:39:26 +08:00
alongw
025e68b7b1 Feat: optimized code 2023-09-03 00:16:42 +08:00
alongw
6e47a5407e Feat: search user 2023-09-03 00:12:38 +08:00
unitwk
3532be602c Fix: useless code 2023-09-03 00:10:00 +08:00
alongw
539925b21f add user 2023-09-02 23:58:00 +08:00
unitwk
25394dc61a Feat: NodeList 2023-09-02 23:55:35 +08:00
alongw
04464a3200 add user 2023-09-02 23:52:43 +08:00
alongw
02a2fa0aef add user 2023-09-02 23:49:45 +08:00
unitwk
10e66f6a2b Feat: NodeList.vue & border-radius: 6px; 2023-09-02 23:46:02 +08:00
unitwk
a9833f47f0 Fix: chart max error 2023-09-02 22:57:21 +08:00
unitwk
e82ab043cf Refactor: terminal page 2023-09-02 22:37:49 +08:00
unitwk
b042fa481b Feat: Echart support 2023-09-02 21:39:33 +08:00
unitwk
6e1508c912 Optimize: api cache 2023-09-02 20:46:11 +08:00
unitwk
fc3126f141 Fix: api request error flow 2023-09-02 13:56:02 +08:00
unitwk
6bbb5faa8d Feat: status block 2023-09-02 13:35:32 +08:00
unitwk
9a05ee7490 Feat: IPanelOverviewResponse API 2023-09-02 12:21:42 +08:00
alongw
cfd58ad8e4 Feat: optimized code 2023-09-01 22:11:42 +08:00
alongw
f8bb6732d0 Feat: batch delete users 2023-09-01 22:04:23 +08:00
unitwk
20cd9fb06d Feat: API cache optimize 2023-09-01 21:45:46 +08:00
alongw
8109a02116 Feat: delete user 2023-09-01 21:28:11 +08:00
unitwk
e5a04cc759
Merge pull request #1001 from Bluemangoo/clock-card
Feat: Add clock card
2023-09-01 11:51:27 +08:00
bluemangoo
2a28a0042a
Feat: add clock card 2023-09-01 11:45:10 +08:00
unitwk
4ace238f54 Merge branch 'next' of github.com:MCSManager/MCSManager into next 2023-09-01 11:44:16 +08:00
bluemangoo
3b9237b121
Chore: enable IDE Idea 2023-09-01 11:08:36 +08:00
unitwk
00b3837843
Merge pull request #998 from MCSManager/🤣👉📱
Feat: MyselfInfoDialog
2023-09-01 10:58:25 +08:00
unitwk
386dc0c7fb Feat: useInstanceState hook 2023-08-31 23:57:34 +08:00
Lazy
de6e404d9b Optimize: no sleep && flex layout 2023-08-31 23:24:15 +08:00
Lazy
cc538f56be Optimize: async function 2023-08-31 23:23:15 +08:00
unitwk
276dc729ad Feat: prettierrc 2023-08-31 22:19:00 +08:00
unitwk
993df610c3 Feat: send command for instance 2023-08-31 22:16:49 +08:00
Lazy
e5047cca17 Merge branch 'next' into 🤣👉📱 2023-08-31 12:04:49 +08:00
Lazy
3994e69cc7 Feat: extract user api 2023-08-31 12:04:08 +08:00
unitwk
9fbdc8f10f Del useless alg 2023-08-31 11:51:58 +08:00
unitwk
75dbbeec5f Feat: open & stop instance 2023-08-31 11:42:35 +08:00
unitwk
d977350123 Feat: add icon btn 2023-08-31 11:10:46 +08:00
unitwk
b8ca8d1701 Feat: change max width 2023-08-31 10:30:06 +08:00
Lazy
3af138d2fe Feat: add update password 2023-08-31 01:04:51 +08:00
alongw
1b4f01bd8a Feat: User management page to get user data 2023-08-30 23:48:26 +08:00
Lazy
7d5960a558 Feat: add copy button 2023-08-30 22:20:17 +08:00
Lazy
b6f45dd7a7 Feat: add update user apikey 2023-08-30 21:16:27 +08:00
unitwk
a6689cdac2 Feat: terminal window 2023-08-30 20:42:08 +08:00
unitwk
5dae7dd684 Feat: terminal base info component 2023-08-30 11:39:13 +08:00
unitwk
3a52460729 Fix: import type { Socket } from "socket.io-client"; 2023-08-29 10:46:55 +08:00
unitwk
0af37e2f88 Feat: socket.io support 2023-08-28 14:44:01 +08:00
unitwk
fa5c5b8fd6 Feat: socket.io support 2023-08-28 14:41:21 +08:00
unitwk
655c3c27ef Optimize: card operator 2023-08-27 11:53:14 +08:00
unitwk
6993b321e2 optimize LeftMenus 2023-08-27 11:27:44 +08:00
unitwk
b4dd21e861 LeftMenus active support 2023-08-27 11:23:44 +08:00
unitwk
e5304c1f09 Feat: add loading ui & refactor settings 2023-08-27 11:15:03 +08:00
unitwk
8573940e0b Feat: add workflows 2023-08-26 23:18:40 +08:00
unitwk
4f90544ab9
Merge pull request #994 from MCSManager/chino
Feat: settings card
2023-08-26 23:15:03 +08:00
unitwk
0ce48aa186 Feat: add workflows 2023-08-26 23:12:43 +08:00
unitwk
c0c5abe92f Feat: add workflows 2023-08-26 23:06:22 +08:00
alongw
dac1839cca Feat: optimized code 2023-08-26 23:01:12 +08:00
alongw
1214de8702 Feat: optimized code 2023-08-26 22:16:42 +08:00
alongw
3b2348465f Feat: optimized code 2023-08-26 21:54:32 +08:00
alongw
d7916b17af Feat: setting up page data submission 2023-08-26 21:39:21 +08:00
alongw
baf14600f8 Feat: setting up page data submission 2023-08-26 21:33:50 +08:00
alongw
ccf8aa9c57 setting up page data submission 2023-08-26 21:31:28 +08:00
unitwk
5bd92a04eb Feat: instances ui 2023-08-26 19:47:55 +08:00
alongw
cfc5f7000e Feat: setting up page data rendering 2023-08-26 19:17:17 +08:00
alongw
64218faeb9 Feat: settings page refinement 2023-08-26 18:58:09 +08:00
alongw
b809162160 Feat: setting interface 2023-08-26 18:29:34 +08:00
alongw
1802ea915e Merge branch 'next' into chino 2023-08-26 17:29:43 +08:00
unitwk
0be4ea10be Feat: instances & nodes ui 2023-08-26 15:02:49 +08:00
unitwk
21179f6f71 Feat: add remote nodes api 2023-08-26 14:38:50 +08:00
alongw
e283ab154f Feat: i18n 2023-08-26 14:19:56 +08:00
unitwk
400242dba8 Feat: Left menus panel support phone 2023-08-26 13:57:32 +08:00
unitwk
fb21a4942a Refactor: font size & settings 2023-08-25 22:54:46 +08:00
unitwk
0aa7e7bf21 Refactor: font size & settings 2023-08-25 21:59:11 +08:00
unitwk
ab372c057a Refactor: user info dialog 2023-08-25 19:37:01 +08:00
unitwk
0d75af4e91 Feat: components size is large 2023-08-25 18:55:49 +08:00
unitwk
b094bf860f Feat: del useless code 2023-08-25 18:23:29 +08:00
unitwk
86ad7aa188 Fix: interface error 2023-08-25 17:55:20 +08:00
unitwk
97a3d96213 Fix: interface error 2023-08-24 14:27:15 +08:00
unitwk
ed6c0ab620 Feat: login flow ok 2023-08-24 11:43:42 +08:00
unitwk
10fdbe1b3b Refactor: deafult size 2023-08-23 17:53:04 +08:00
unitwk
a35873fc23 Feat: add base info 2023-08-23 17:07:42 +08:00
unitwk
21a6ba64ea Feat: login ok 2023-08-23 11:04:39 +08:00
unitwk
c3dc5ce0de Refactor: api define 2023-08-22 14:17:35 +08:00
unitwk
4e38561ee5 Feat: user info fetch 2023-08-21 23:23:20 +08:00
unitwk
c38e90e12d Feat: user info fetch 2023-08-21 23:19:20 +08:00
unitwk
8c2c1f65b2 Feat: login ok 2023-08-21 22:57:54 +08:00
unitwk
2ec3dd4c02 Refactor: eslint check 2023-08-21 22:40:52 +08:00
unitwk
dc1c8ce471 Merge branch 'next' of github.com:MCSManager/MCSManager into next 2023-08-21 21:51:18 +08:00
unitwk
54cbee7de4 Feat: add old frontend files 2023-08-21 21:51:08 +08:00
unitwk
7aff9c9b2d Feat: tag version 2023-08-21 20:06:50 +08:00
unitwk
92cc11a089 Feat: build script 2023-08-21 12:41:50 +08:00
unitwk
7310638661 Feat: build script for windows 2023-08-21 12:39:23 +08:00
unitwk
323de1726a Feat: windows build script 2023-08-21 12:31:57 +08:00
unitwk
2bd2a67127 Feat: add npmrc 2023-08-21 11:43:19 +08:00
unitwk
9683addf56 Feat: windows build script 2023-08-21 11:06:09 +08:00
unitwk
cf02114970 Refactor: project structure 2023-08-21 10:49:37 +08:00
unitwk
dbbfdc7227 Feat: vite dev server 2023-08-20 23:38:22 +08:00
unitwk
3d149d59e2 Refactor: rename project 2023-08-20 23:20:11 +08:00
unitwk
3c106f642a Refactor: project structure 2023-08-20 23:06:38 +08:00
unitwk
cdcdfea6f9 Refactor: project structure 2023-08-20 22:59:52 +08:00
unitwk
c059d6222f Refactor: project structure 2023-08-20 22:57:10 +08:00
unitwk
ab42daba1b
Merge pull request #977 from WakerPT/master
Update en_us.json
2023-08-13 09:21:41 +08:00
Leandro Guerra
7f451ac1b4 Update en_us.json
Some very minor fixes
2023-08-12 17:13:28 +01:00
unitwk
20dab89096
Merge pull request #976 from WakerPT/master
Update en_us.json
2023-08-12 22:58:52 +08:00
Leandro Guerra
83b3217064 Update en_us.json
English fixes
2023-08-12 13:30:48 +01:00
unitwk
40f7e2388d
Update -bug-report-.md 2023-08-11 20:29:57 +08:00
unitwk
b742d51965
Merge pull request #950 from Zhou-Shilin/master
Fix: Typo `donwload`
2023-07-21 17:55:27 +08:00
unitwk
7fe298b051
Merge pull request #944 from MCSManager/dependabot/npm_and_yarn/word-wrap-1.2.4
Build(deps-dev): Bump word-wrap from 1.2.3 to 1.2.4
2023-07-21 15:27:32 +08:00
BaimoQilin
02b28fa932
Fix: typo Donwload 2023-07-21 08:23:24 +08:00
BaimoQilin
09129bbfee
Fix: typo Donwload 2023-07-21 08:21:59 +08:00
dependabot[bot]
78b8af7de6
Build(deps-dev): Bump word-wrap from 1.2.3 to 1.2.4
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-19 09:00:47 +00:00
unitwk
e6c8cad1d1
Fix: Commit message 2023-07-04 20:09:43 +08:00
unitwk
94cb5ad0e4
Merge pull request #921 from nz-lin/master
修复: WS连接时使用 data/RemoteServiceConfig 中的 connectOpts
2023-07-02 11:03:17 +08:00
nz-lin
fd12c9a5dd 修复: WS连接时使用 data/RemoteServiceConfig 中的 connectOpts 2023-07-02 05:27:47 +08:00
unitwk
577dd0fca4
Update README.md 2023-06-05 21:53:11 +08:00
unitwk
d83818c904
Update README_CN.md 2023-06-05 21:50:54 +08:00
unitwk
6fe996a834
Update README.md 2023-06-05 21:33:44 +08:00
unitwk
2af25b808b Feat: update web version 2023-05-29 23:06:13 +08:00
unitwk
cbafe1e284 Feat: change daemonVersion -> 3.4.0 2023-05-20 12:10:17 +08:00
unitwk
ac903b5df7 Feat: add file name search 2023-05-19 18:04:51 +08:00
unitwk
b8050b62f0 Feat: socket.io add rejectUnauthorized=false 2023-05-18 15:28:53 +08:00
unitwk
9b982b2b6f
Update README_CN.md 2023-04-23 14:55:25 +08:00
unitwk
db98312ff4
Merge pull request #869 from Bluemangoo/main-776
Fix: remote time rendered using remote time zone (#776)
2023-04-09 11:42:31 +08:00
bluemangoo
77c852d95e
Fix: remote time rendered using remote time zone (#776) 2023-04-09 08:30:14 +08:00
unitwk
e7e68d328e
Merge pull request #854 from Bluemangoo/main-829
https://github.com/MCSManager/MCSManager/issues/829
2023-03-27 11:01:58 +08:00
bluemangoo
415d0961be
Feat: enable size setting when requesting api "/api/protected_instance/outputlog" (Issue #829) 2023-03-25 20:42:21 +08:00
unitwk
20bb46c214
Merge pull request #841 from ztsinsun/add
Update README.md
2023-03-13 17:35:39 +08:00
unitwk
d1a1699b97
Merge pull request #840 from Bluemangoo/static-cache
cache static files
2023-03-13 10:38:48 +08:00
Z_Tsin
356e124a01
Update README.md 2023-03-11 20:49:36 +08:00
Bluemangoo
49cb682d48
Feat: cache static files 2023-03-11 20:06:17 +08:00
unitwk
160a4e293b
Update README.md 2023-02-28 10:47:08 +08:00
unitwk
ef26b4a864
Update README_CN.md 2023-02-28 10:45:48 +08:00
unitwk
1bb15a231f
Update README.md 2023-02-28 10:44:42 +08:00
443 changed files with 106100 additions and 5641 deletions

1
.dockerignore Symbolic link
View File

@ -0,0 +1 @@
.gitignore

View File

@ -1,14 +0,0 @@
// Copyright (C) 2022 MCSManager <mcsmanager-dev@outlook.com>
module.exports = {
env: {
browser: true,
commonjs: true,
es2021: true
},
extends: "eslint:recommended",
parserOptions: {
ecmaVersion: 12
},
rules: {}
};

View File

@ -1,16 +0,0 @@
---
name: "[Bug report]"
about: Bug report
title: ''
labels: BUG
assignees: ''
---
**MCSManager Version**
**System Info/Version**
**Node Version**
**Step**

View File

@ -1,10 +0,0 @@
---
name: "[Feature request] "
about: Feature request
title: ''
labels: Feature Request
assignees: ''
---

View File

@ -1,10 +0,0 @@
---
name: "[Question]"
about: Create a question
title: ''
labels: ''
assignees: ''
---

48
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@ -0,0 +1,48 @@
name: Bug Report
description: Create a report to help us improve
title: "[Bug Report] "
labels: "Bug Report"
body:
- type: input
id: Platform
attributes:
label: Platform
description: Please enter the platform on which you encountered the bug.
placeholder: e.g. Windows 11, Ubuntu 14.04
validations:
required: true
- type: input
id: panel-version
attributes:
label: Panel Version
description: MCSManager Panel Version
placeholder: e.g. 10.1.0
validations:
required: true
- type: input
id: daemon-version
attributes:
label: Daemon Version (Optional)
description: MCSManager Daemon Version
placeholder: e.g. 4.3.0
validations:
required: false
- type: input
id: recurrence-probability
attributes:
label: Recurrence Probability
description: Recurrence Probability
placeholder: 1%~100%
validations:
required: true
- type: textarea
id: bug-description
attributes:
label: Bug Description
description: Please describe the problem you met in as much detail as possible. Besides, please describe how to trigger this problem again.
placeholder: |
1. Click a button named ...
2. ...
3. ...
validations:
required: true

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: English | Discord Channel
url: https://discord.gg/BNpYMVX7Cd
about: The official Discord channel of MCSManager!
- name: 中文用户 | QQ Group
url: http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=6ryJRaHMaAM9aSeSdRWn6qm9gQ3lI8vu&authKey=BMZ5gA9Rqw%2B5714yAW1ZxiWnFbkk2KRKgBF%2BMiIaOw0VVsSR7tsP10cFwhmDdlgU&noverify=0&group_code=198646856
about: The official QQ Group of MCSManager!
- name: 中文用户 | Telegram Group
url: https://t.me/MCSManager_dev
about: The official Telegram Group of MCSManager!

22
.github/ISSUE_TEMPLATE/feature.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Feature Request
description: A new feature for MCSManager
title: "[Feature] "
labels: "Feature Request"
body:
- type: markdown
attributes:
value: Please make sure that no duplicated issues has already been delivered.
- type: textarea
id: description
attributes:
label: Description
description: Please describe in detail the new functionality you would like to add.
validations:
required: true
- type: textarea
id: reason
attributes:
label: Reason
description: Please describe why you want to add the feature into MCSManager.
validations:
required: true

1
.github/github.txt vendored
View File

@ -0,0 +1 @@

BIN
.github/panel-custom-layout.gif vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 MiB

BIN
.github/panel-image.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

BIN
.github/panel-instances.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 740 KiB

View File

@ -13,12 +13,12 @@ name: "CodeQL"
on:
push:
branches: [ "master" ]
branches: ["next"]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
branches: ["next"]
schedule:
- cron: '34 21 * * 6'
- cron: "37 18 * * 2"
jobs:
analyze:
@ -32,41 +32,40 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
language: ["javascript", "typescript"]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

@ -1,20 +0,0 @@
# Dependency Review Action
#
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
#
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: 'Dependency Review'
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v3
- name: 'Dependency Review'
uses: actions/dependency-review-action@v2

102
.github/workflows/docker.yml vendored Normal file
View File

@ -0,0 +1,102 @@
name: Release Docker Build
on:
release:
types: [published]
jobs:
build-web:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Docker meta web
id: meta_web
uses: docker/metadata-action@v5
with:
images: |
name=ghcr.io/${{ github.repository }}-web
name=githubyumao/mcsmanager-web,enable=${{ github.repository == 'MCSManager/MCSManager' }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub
if: ${{ github.repository == 'MCSManager/MCSManager' }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Build and Push Web
uses: docker/build-push-action@v6
with:
file: dockerfile/web.dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta_web.outputs.tags }}
labels: ${{ steps.meta_web.outputs.labels }}
build-args: |
BUILDPLATFORM=linux/amd64
build-daemon:
runs-on: ubuntu-latest
strategy:
matrix:
java_version: [8, 11, 17, 21]
steps:
- uses: actions/checkout@v4
- name: Docker meta daemon
id: meta_daemon
uses: docker/metadata-action@v5
with:
images: |
name=ghcr.io/${{ github.repository }}-daemon,enable=${{ matrix.java_version == 21 }}
name=githubyumao/mcsmanager-daemon,enable=${{ github.repository == 'MCSManager/MCSManager' && matrix.java_version == 21 }}
name=ghcr.io/${{ github.repository }}-daemon-jdk${{ matrix.java_version }}
name=githubyumao/mcsmanager-daemon-jdk${{ matrix.java_version }},enable=${{ github.repository == 'MCSManager/MCSManager' }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to ghcr.io
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub
if: ${{ github.repository == 'MCSManager/MCSManager' }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Build and Push Daemon
uses: docker/build-push-action@v6
with:
file: dockerfile/daemon.dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta_daemon.outputs.tags }}
labels: ${{ steps.meta_daemon.outputs.labels }}
build-args: |
BUILDPLATFORM=linux/amd64
JAVA_RUNTIME=${{ matrix.java_version }}

View File

@ -1,30 +0,0 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm install
- run: npm run dev

57
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,57 @@
name: Release Build
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Install dependencies
run: |
chmod a+x ./install-dependents.sh
chmod a+x ./build.sh
./install-dependents.sh
./build.sh
- name: Add binaries to production files
run: wget --input-file=lib-urls.txt --directory-prefix=production-code/daemon/lib/
- name: Create linux and windows build
run: |
cp -r production-code dist_linux
mv production-code dist_windows
- name: Copy startup scripts
run: |
cp prod-scripts/linux/* dist_linux/
cp prod-scripts/windows/* dist_windows/
- name: Copy node runtime to windows build
run: |
wget https://nodejs.org/download/release/latest-v20.x/win-x64/node.exe -O dist_windows/daemon/node_app.exe
cp dist_windows/daemon/node_app.exe dist_windows/web/node_app.exe
- name: Create archive
run: |
mv dist_linux/ mcsmanager/
tar czf mcsmanager_linux_release.tar.gz mcsmanager/
rm -rf mcsmanager/
mv dist_windows/ mcsmanager/
zip -r mcsmanager_windows_release.zip mcsmanager/
- name: Upload assets to release
uses: softprops/action-gh-release@v2
with:
files: |
mcsmanager_windows_release.zip
mcsmanager_linux_release.tar.gz

31
.github/workflows/webpack.yml vendored Executable file
View File

@ -0,0 +1,31 @@
name: Build MCSManager
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x, 20.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Run Build Script
run: |
chmod a+x ./install-dependents.sh
chmod a+x ./build.sh
./install-dependents.sh
./build.sh

19
.gitignore vendored
View File

@ -5,20 +5,17 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
test.txt
*.bat
src/public
panel/public/
*.code-workspace
vscode/
.vscode/
Daemon/
data/
dist/
out/
public/
lib/
production/
.DS_Store
production-code/
test.js
.idea/
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
@ -28,6 +25,7 @@ pids
*.pid
*.seed
*.pid.lock
mcsmanager_packages.json
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
@ -121,4 +119,7 @@ workspace.code-workspace
src/public/1.png
# IntelliJ Idea project files
/.idea/*
/.idea/*
*/.idea/*
.turbo

1
.npmrc Normal file
View File

@ -0,0 +1 @@
registry=https://registry.npmjs.org

19
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,19 @@
// Please do not commit changes to this file.
// You need to install the "i18n ally" VSCode plugin.
{
// Change this to your language, available options: "languages/*.json"
// "i18n-ally.displayLanguage": "en_US"
"i18n-ally.sourceLanguage": "en",
"i18n-ally.extract.keyMaxLength": 10000,
"cSpell.words": ["BUKKIT", "BUNGEECORD", "MINECRAFT"],
"i18n-ally.localesPaths": [
"languages",
"frontend/src/lang",
"daemon/src/i18n",
"panel/src/app/i18n"
],
"i18n-ally.keystyle": "flat",
"i18n-ally.enabledFrameworks": ["vue"],
"editor.wordSeparators": "`~!@#$%^&*()=+[{]}\\|;:'\",.<>/?"
}

128
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
support@mcsmanager.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

49
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,49 @@
## English 🌎
### Purpose
To prevent uncontrolled growth of features and wasted effort after submitting PRs that are not merged, these notices are hereby written.
### Submitting New Features
If you wish to submit a new feature via a Pull Request, please first open an issue to inform the developer @unitwk. After discussion, we will decide together whether the feature should be developed.
We will consider whether to merge this feature into the master branch from three perspectives: `scope of code impact`, `practicality of the feature`, and `estimated number of applicable users`.
Otherwise, unrestrained addition of features will inevitably lead to the continuous bloating of software functionality, which will sooner or later result in very serious security vulnerabilities.
### Iterating Old Features
Fixing or upgrading an existing feature, **without exceeding the responsibilities of the old feature**, **does not require opening an issue for discussion**. You can directly submit a Pull Request, and after testing and Code Review, it will be merged.
**Code in open-source projects often exists for several years or even decades. Due to differences in developer habits, implementation approaches, and code styles, we need some rules and constraints to ensure the long-term health of the code. Thank you for your understanding.**
### How to Contribute Code?
Please refer to the `Development` section in the README.md file.
<br />
## 中文 🌏
### 目的
为了防止功能无节制增长和提交 PR 之后未得到合并浪费工作精力,特此写下这些须知通告。
### 提交新功能
如果你想 `Pull Request` 一个新功能,请先开启一个 `issue` 告知开发者 @unitwk ,我们一起经过讨论之后,再决定这个功能是否应该开发。
我们会从`代码影响范围``功能实用性``估算的适用群体人数` 三个角度来考虑这个功能是否应该合并到 master 分支。
否则,无节制的新增功能必将导致软件功能不断臃肿,从而迟早会有一天会出现非常严重的安全漏洞。
### 迭代旧功能
修复或升级某个现有的功能,在**不超出旧功能的职责**情况下,**无需开 `issue` 进行讨论**,你可以直接提交 `Pull Request`,在经过测试和 `Code Review`后,都会给予合并。
**开源项目的代码通常会存在几年甚至十年以上,由于每个开发者习惯不同,实现思路不同,代码风格不同,所以我们需要有一定的规则约束来让代码长期健康的活下去,谢谢你的理解。**
### 如何贡献代码?
请阅读 README.MD 文件的 `Development` 段落。

322
LICENSE Executable file → Normal file
View File

@ -2,190 +2,200 @@
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
Copyright 2022 unitwk
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Copyright 2025 MCSManager
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

279
README.md Executable file → Normal file
View File

@ -1,243 +1,224 @@
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
<div align="center">
<a href="https://mcsmanager.com/" target="_blank">
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
</a>
<br />
<br />
<h1 id="mcsmanager">
<a href="https://mcsmanager.com/" target="_blank">MCSManager Panel</a>
</h1>
[![--](https://img.shields.io/badge/Support-Windows/Linux-green.svg)](https://github.com/MCSManager)
[![Status](https://img.shields.io/badge/npm-v6.14.15-blue.svg)](https://www.npmjs.com/)
[![Status](https://img.shields.io/badge/node-v14.17.6-blue.svg)](https://nodejs.org/en/download/)
[![Status](https://img.shields.io/badge/npm-v8.9.14-blue.svg)](https://www.npmjs.com/)
[![Status](https://img.shields.io/badge/node-v16.20.2-blue.svg)](https://nodejs.org/en/download/)
[![Status](https://img.shields.io/badge/License-Apache%202.0-red.svg)](https://github.com/MCSManager)
[Official Website](http://mcsmanager.com/) | [Web Project](https://github.com/MCSManager/MCSManager) | [UI Project](https://github.com/MCSManager/UI) | [Daemon Project](https://github.com/MCSManager/Daemon)
[Official Website](http://mcsmanager.com/) | [Docs](https://docs.mcsmanager.com/) | [Discord](https://discord.gg/BNpYMVX7Cd)
[简体中文](README_ZH.md) | [繁體中文](README_TW.md) | [Deutsch](README_DE.md) | [Português BR](README_PTBR.md) |
[日本語](README_JP.md) | [Spanish](README_ES.md)
[English](readme.md) | [简体中文](README_CN.md)
</div>
<br />
## Introduction
## What is MCSManager?
MCSManager Panelabbr: MCSM Panelis a multilingual, lightweight, out-of-the-box, and multi-instance Minecraft server control panel with Docker support.
**MCSManager Panel** (MCSM) is a **modern, secure, and distributed control panel** designed for managing Minecraft and Steam game servers.
MCSManager panel can help you manage multiple physical servers in one place, and create game servers at any host dynamically. It also provides a secure and reliable user permission system for a seamless multi-user experience.
MCSManager has already gained a certain level of popularity within the community, specifically because of Minecraft. MCSManager excels in offering a centralized management solution for multiple server instances and provides a secure and reliable multi-user permission system. In addition, we are committed to support server administrators, not only for Minecraft but also for Terraria and various Steam games. Our goal is to foster a thriving and supportive community for game server management.
![Screenshot.png](https://mcsmanager.com/main.png)
![Screenshot.png](https://mcsmanager.com/main2.png)
MCSManager **supports English, French, German, Italian, Japanese, Portuguese, Simplified Chinese, and Traditional Chinese**, with plans to add support for more languages in the future!
**Terminal**
![failed_to_load_screenshot.png](/.github/panel-image.png)
**Instance List**
![failed_to_load_screenshot.png](/.github/panel-instances.png)
**Custom Layout**
![failed_to_load_screenshot.png](/.github/panel-custom-layout.gif)
## Features
1. One-click deployment of `Minecraft` Java/Bedrock Server
2. Compatible with most `Steam` game servers. (e.g. `Palworld`, `Squad`, `Project Zomboid`, `Terraria`, etc.)
3. Customizable UI, create your own layout
4. Supports all images on `Docker Hub`, supports multiple users and supports commercial services!
5. Manage multiple servers with a single web interface
6. The technology stack is simple, and you only need to be good at Typescript to complete the entire MCSManager development.
7. And More!
<br />
## Runtime Environment
MCSManager panel can run on both Windows and Linux platforms without a database or complicated system configuration. As a lightweight control panel, you only need Node.js to run it.
MCSM supports both `Windows` and `Linux`. The only requirement is `Node.js` and some libraries **for decompression**.
Required Node.js version: **14.17.6** or above.
Requires [Node.js 16.20.2](https://nodejs.org/en) or above.
<br />
## Install
## Installation
### Windows
For the Windows systems, the MCSM panel has been **compiled into a click-to-run version**.
For Windows, we provide packaged executable files:
Download it from the official site: [https://mcsmanager.com/](https://mcsmanager.com/)
Go to: [https://mcsmanager.com/](https://mcsmanager.com/)
<br />
### Linux
**Quick Install with one command**
**One-Command Deployment**
> The script needs to register system services and requires root permissions because of that.
```bash
wget -qO- https://raw.githubusercontent.com/mcsmanager/Script/master/setup_en.sh | bash
sudo su -c "wget -qO- https://script.mcsmanager.com/setup.sh | bash"
```
- The script is designed for Ubuntu/Centos/Debian/Archlinux of AMD64 architecture only.
- Use `systemctl start mcsm-{web,daemon}` to start service after installtion.
- Directory for panel components and runtime: `/opt/mcsmanager/`
**Usage**
```bash
systemctl start mcsm-{web,daemon}
systemctl stop mcsm-{web,daemon}
```
- Only supports Ubuntu/Centos/Debian/Archlinux.
- Installation directory: `/opt/mcsmanager/`.
<br />
**Linux Manual Installation**
- If the installation script does not work, you can try the following steps to install manually.
- If the installation script fails to execute correctly, you can try to install it manually.
```bash
# switch to the installation directory. Please create it in advance with 'mkdir /opt/' if not exist.
# Create /opt directory if not already
mkdir /opt
# Switch to /opt
cd /opt/
# Download runtime environment (Node.js). Ignore this step if you have Node.js 14+ installed already.
wget https://nodejs.org/dist/v14.17.6/node-v14.17.6-linux-x64.tar.gz
# Decompress archive
tar -zxvf node-v14.17.6-linux-x64.tar.gz
# Add program to system PATH
ln -s /opt/node-v14.17.6-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v14.17.6-linux-x64/bin/npm /usr/bin/npm
# Download Node.js 20.11. If you already have Node.js 16+ installed, ignore this step.
wget https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz
# Decompress Node.js source
tar -xvf node-v20.11.0-linux-x64.tar.xz
# Add Node.js to system PATH
ln -s /opt/node-v20.11.0-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v20.11.0-linux-x64/bin/npm /usr/bin/npm
# Prepare installation directory
# Prepare MCSM's installation directory
mkdir /opt/mcsmanager/
cd /opt/mcsmanager/
# Download the web project
git clone https://github.com/MCSManager/MCSManager-Web-Production.git web
cd web
# Download MCSManager
wget https://github.com/MCSManager/MCSManager/releases/latest/download/mcsmanager_linux_release.tar.gz
tar -zxf mcsmanager_linux_release.tar.gz
# Install dependencies
npm install --production
cd /opt/mcsmanager/
./install.sh
# Download the Daemon
git clone https://github.com/MCSManager/MCSManager-Daemon-Production.git daemon
cd daemon
# Install dependencies
npm install --production
# Please open two terminals or screens.
# Please open two terminals or Screen
# Start the daemon first
cd /opt/mcsmanager/daemon
# Start the daemon
node app.js
# Start the daemon first.
./start-daemon.sh
# Start the web project (in the second terminal/screen)
cd /opt/mcsmanager/web
# start the application
node app.js
# Start the web interface at the second terminal or screen.
./start-web.sh
# Access http://localhost:23333/ for web interface
# In general, the web application will scan and connect to the local daemon automatically.
# For web access, go to http://localhost:23333/
# In general, the web interface will automatically scan and add the local daemon.
```
- Note, the above steps do not register the panel components to system service. You have to use 'screen' to manage it or register the system service manually.
This installation approach does not automatically set up MCSManager as a system service. Therefore, it is necessary to use `screen` for management. For those interested in managing MCSManager through a system service, please refer to our wiki/documentation.
<br />
## Development
## Data Directories
This section is specifically designed for developers. General users may disregard this portion without concern.
Web Config & Data: `/opt/mcsmanager/web/data/`
### Plugins
Daemon Config & Data `/opt/mcsmanager/daemon/data/`
We use "VS Code" to develop MCSManager. You may need to install these plugins:
<br />
- i18n display support (I18n Ally)
- Code formatter (Prettier)
- Vue - Offcial
- ESLint
## Update
Reference: https://github.com/MCSManager/MCSManager/wiki/Update-MCSManager
> Note, backup of `data` directory before each update is highly recommended.
<br />
## Projects
This software requires all three projects to run. The code you use for installation is the result of compilation and integration.
[**Web Backend**](https://github.com/MCSManager/MCSManager)
- Role: Control Center
- Responsible for: Backend APIs, user data management, and communication & authentication with daemons.
[**Frontend/UI**](https://github.com/MCSManager/UI)
- Role: The user interfaces for the backend.
- Responsible for: Displaying statistics via the web interface, sending requests, and communicating with daemons. The final product of this project is pure static files.
[**Daemon**](https://github.com/MCSManager/Daemon)
- Role: Slave/controlled remote node
- Responsible for: Controlling all instances on localhost and managing the actual instance process. It is capable to communicate with all objects.
<br />
## Build the Development Environment
This is intended for developers. If you are not a developer, you can safely ignore these.
You can continue to develop or preview all the projects once they are running under the development environment. Please make sure to be in compliance with the license.
**Web Project**
### MacOS
```bash
git clone https://github.com/MCSManager/MCSManager.git
cd MCSManager
npm install
npm run start
# By default, use ts-node to run Typescript code directly
# By default, run on port 23333.
./install-dependents.sh
./npm-dev-macos.sh
```
**UI Project**
### Windows
```bash
git clone https://github.com/MCSManager/UI.git
cd UI
npm install
npm run serve
# Preview the interface at http://localhost:8080/
# All the requests will be redirected to port 23333.
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.bat
./npm-dev-windows.bat
```
**Daemon Project**
### Dependency Files
You'll need to go to the [PTY](https://github.com/MCSManager/PTY) and [Zip-Tools](https://github.com/MCSManager/Zip-Tools) projects to download the corresponding binary files and place them in the `daemon/lib` directory to ensure the proper functioning of the `Emulation Terminal` and `File Decompression`.
### Build Production Version
```bash
git clone https://github.com/MCSManager/Daemon.git
cd Daemon
npm install
npm run start
# After running, please connect the daemon to the control panel via the web interface.
# By default, run on port 24444
./build.bat # Windows
./build.sh # MacOS
```
Output Directory: "production-code"
<br />
## Code Contributing
If you experience any problems while using MCSManager, you are welcome to [submit an Issue](https://github.com/MCSManager/MCSManager/issues/new/choose). Alternatively, you can fork the project and contribute directly by submitting a Pull Request.
Please ensure that any submitted code adheres to our existing coding style. For more details, refer to the guidelines provided in [this issue](https://github.com/MCSManager/MCSManager/issues/544).
<br />
## Browser Compatibility
- Support mainstream modern browsers like `Chrome` `Firefox` `Safari` `Opera`.
- `IE` support has been dropped.
- Supported on modern browsers including `Chrome`, `Firefox`, and `Safari`.
- Support for `IE` has been discontinued.
<br />
## i18n
## BUG Reporting
The MCSManager internationalization was done by [Lazy](https://github.com/LazyCreeper), [KevinLu2000](https://github.com/KevinLu2000), [zijiren233](https://github.com/zijiren233) and [Unitwk](https://github.com/unitwk).
**Open Issue:** [Click here](https://github.com/MCSManager/MCSManager/issues/new/choose)
**Security Vulnerability Report:** [SECURITY.md](SECURITY.md)
<br />
## Panel Permission
## Internationalization
The control panel will check the user list while running. If there is no user available, a default administrator user will be created.
Thanks to these contributors for providing a substantial amount of translation:
If you forget your only administrator account, you can back up all the current user data, regenerate a new admin account, and overwrite the previous one.
> User Data: /opt/mcsmanager/web/data/Users/*.json
<br />
## Contribution
If you encounter any issue while using, you can [submit an Issue](https://github.com/MCSManager/MCSManager/issues/new/choose) or submit Pull Request after you fix it in a fork.
The code needs to be in its existing format, and no extra codes should be formatted. For details: [click here](https://github.com/MCSManager/MCSManager/issues/544)。
<br />
## Report bug
Feedback on any problem encountered is welcomed and will be responded to in a timely manner.
If you find a serious security vulnerability, you can email mcsmanager-dev@outlook.com for a private submission.
After the security issue has been resolved, your name will be listed as the bug-finder.
- [KevinLu2000](https://github.com/KevinLu2000)
- [Unitwk](https://github.com/unitwk)
- [JianyueLab](https://github.com/JianyueLab)
- [IceBrick](https://github.com/IceBrick01)
<br />
## License
Copyright 2022 [MCSManager Dev](https://github.com/mcsmanager), Apache-2.0 license.
**Additional Requirements:**
You must keep all copyright information and place "Powered by MCSManager" in a conspicuous position.
The source code of MCSManager is licensed under the [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) License.
Copyright ©2025 MCSManager.

View File

@ -1,255 +0,0 @@
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
<br />
[![Status](https://img.shields.io/badge/npm-v6.14.15-blue.svg)](https://www.npmjs.com/)
[![Status](https://img.shields.io/badge/node-v14.17.6-blue.svg)](https://nodejs.org/en/download/)
[![Status](https://img.shields.io/badge/License-Apache%202.0-red.svg)](https://github.com/MCSManager)
[官方网站](http://mcsmanager.com/) | [使用文档](https://docs.mcsmanager.com/) | [团队主页](https://github.com/MCSManager) | [面板端项目](https://github.com/MCSManager/MCSManager) | [网页前端项目](https://github.com/MCSManager/UI) | [守护进程项目](https://github.com/MCSManager/Daemon)
中文 QQ 群https://jq.qq.com/?_wv=1027&k=Pgl9ScGw
中文 TG 群https://t.me/MCSManager_dev
爱发电赞助https://afdian.net/a/mcsmanager
<br />
## 这是什么?
MCSManager 面板简称MCSM 面板)是一款开源,分布式,轻量级,快速部署,支持大部分游戏服务端和控制台程序的管理面板
<br />
## 软件特性
软件在 Minecraft 和其他游戏社区内中已有一定的流行程度,它可以帮助你集中管理多个物理服务器,动态在任何主机上创建游戏服务端,并且提供安全可靠的多用户权限系统,可以很轻松的帮助你管理多个服务器,一直在为 MinecraftTerrariaSteam 游戏服务器管理员,运维人员和个人开发者提供健康的软件支持。
![截图.png](https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/MCSM9.png)
![Screenshot.png](https://mcsmanager.com/main2.png)
<img width="1322" alt="QQ20221207-174328@2x" src="https://user-images.githubusercontent.com/18360009/206144481-7f57b40d-f71b-4d7e-a617-846da69ca1a3.png">
<br />
## 运行环境
控制面板可运行在 Windows 与 Linux 平台,无需数据库与任何系统配置,只需安装 node 环境即可快速运行,属于轻量级的 Minecraft 服务端控制面板。
必须 `Node 14.17.0` 以上,无需数据库和更改任何系统配置,开箱即可运行。
<br />
## 配置/数据文件
配置文件: `data/SystemConfig/config.json`
用户数据文件:`data/User/*.json`
远程守护进程配置:`data/RemoteServiceConfig/*.json`
<br />
## 软件文档
地址:[https://docs.mcsmanager.com/](https://docs.mcsmanager.com/)
<br />
## 安装
### Windows
对于 Windows 系统,**已整合成直接运行版本,下载即可运行**(使用管理员权限运行):
前往:[https://mcsmanager.com/](https://mcsmanager.com/)
<br />
### Linux
**一行命令快速安装**
```bash
// 国内用户专用 gitee 加速源
wget -qO- https://gitee.com/mcsmanager/script/raw/master/setup.sh | bash
// 或原始源(科学上网)
wget -qO- https://raw.githubusercontent.com/mcsmanager/Script/master/setup.sh | bash
```
- 脚本仅适用于 AMD64 架构 Ubuntu/Centos/Debian/Archlinux。
- 执行完成后,使用 `systemctl start mcsm-{web,daemon}` 即可启动面板服务。
- 面板代码与运行环境自动安装在 `/opt/mcsmanager/` 目录下。
<br />
**Linux 手动安装**
- 若一键安装不起作用,则可以尝试此步骤手动安装。
```bash
# 切换到安装目录,没有此目录请执行 mkdir /opt/
cd /opt/
# 下载运行环境(已有 Node 14+ 可忽略)
wget https://npmmirror.com/mirrors/node/v14.17.6/node-v14.17.6-linux-x64.tar.gz
# 解压文件
tar -zxvf node-v14.17.6-linux-x64.tar.gz
# 链接程序到环境变量中
ln -s /opt/node-v14.17.6-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v14.17.6-linux-x64/bin/npm /usr/bin/npm
# 准备安装目录
mkdir /opt/mcsmanager/
cd /opt/mcsmanager/
# 下载面板端Web程序
git clone https://github.com/MCSManager/MCSManager-Web-Production.git web
cd web
# 安装依赖库
npm install --production --registry=https://registry.npmmirror.com/
cd /opt/mcsmanager/
# 下载守护进程Daemon程序
git clone https://github.com/MCSManager/MCSManager-Daemon-Production.git daemon
cd daemon
# 安装依赖库
npm install --production --registry=https://registry.npmmirror.com/
# 打开两个终端或两个 Screen 软件的终端窗口
# 先启动守护进程
cd /opt/mcsmanager/daemon
# 启动
node app.js
# 然后启动面板端进程
cd /opt/mcsmanager/web
# 启动
node app.js
# 访问 http://localhost:23333/ 即可进入面板。
# 默认情况下,面板端会自动扫描 daemon 文件夹并且自动连接到守护进程。
```
- 注意这种安装方式不会自动注册面板到系统服务Service所以必须使用 `screen` 软件来管理。
<br />
## 更新版本
参考: https://github.com/MCSManager/MCSManager/wiki/Update-MCSManager
> 如果你不是特别需要新版本的功能,或者不是为了修复安全隐患,那就不建议更新。
<br />
## 项目体系
整个软件运行需要三个项目的互相配合才可运行,您普通安装的代码是编译再整合后的产物。
[**控制面板端**](https://github.com/MCSManager/MCSManager)
- 角色:控制中心
- 责任:负责提供网页前端的后端接口,提供 API 接口,用户数据管理和对守护进程进行通信和授权。
[**网页前端**](https://github.com/MCSManager/UI)
- 角色:控制中心的用户交互界面
- 责任:以网页形式展示数据,发送请求,并且拥有与守护进程通信的能力,此项目最终产物是纯静态文件。
[**守护进程**](https://github.com/MCSManager/Daemon)
- 角色:被控端
- 责任:控制本地主机的所有实例,真实进程的实际管理者,拥有与任何对象的通信能力。
<br />
## 搭建开发环境
此段落面向开发人员,普通用户无需关注也无需执行。
所有项目全部以开发环境运行后,便可以进行开发与预览,请务必遵循开源协议。
**控制面板端MCSManager**
```bash
git clone https://github.com/MCSManager/MCSManager.git
cd MCSManager
npm install
npm run start
# 默认将采用 ts-node 直接执行 Typescript 代码
# 默认运行在 23333 端口
```
**网页前端UI**
```bash
git clone https://github.com/MCSManager/UI.git
cd UI
npm install
npm run serve
# 访问 http://localhost:8080/ 即可预览界面
# 所有 API 请求将自动转发到 23333 端口
```
**守护进程Daemon**
```bash
git clone https://github.com/MCSManager/Daemon.git
cd Daemon
npm install
npm run start
# 运行后请在控制面板端连接本守护进程
# 默认运行在 24444 端口
```
<br />
## 浏览器兼容性
- 支持 `Chrome` `Firefox` `Safari` `Opera` 等现代主流浏览器。
- 已放弃支持 `IE` 浏览器。
<br />
## 国际化
MCSManager 已支持中文,英文两种语言,已经实现国际化全面覆盖。
软件国际化由 [Lazy](https://github.com/LazyCreeper)[KevinLu2000](https://github.com/KevinLu2000)[zijiren233](https://github.com/zijiren233) 和 [Unitwk](https://github.com/unitwk) 共同完成
<br />
## 贡献
如果你在使用过程中发现任何问题,可以 [提交 Issue](https://github.com/MCSManager/MCSManager/issues/new/choose) 或自行 Fork 修改后提交 Pull Request。
代码需要保持现有格式,不得格式化多余代码,具体可[参考这里](https://github.com/MCSManager/MCSManager/issues/544)。
<br />
## 问题报告
欢迎发现的任何问题进行反馈,必当及时修复。
若发现严重安全漏洞又不便公开发布,请发送邮件至: mcsmanager-dev@outlook.com。
安全问题修复后将在代码中附加漏洞发现者姓名。
<br />
## 源代码协议
遵循 Apache-2.0 协议。
**我们对源代码有额外的限制你必须保留所有版权文字带Copyright并在明显位置附上 Powered by MCSManager。**
版权所有 2022 MCSManager 开发团队。

224
README_DE.md Normal file
View File

@ -0,0 +1,224 @@
<div align="center">
<a href="https://mcsmanager.com/" target="_blank">
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
</a>
<br />
<h1 id="mcsmanager">
<a href="https://mcsmanager.com/" target="_blank">MCSManager Panel</a>
</h1>
[![--](https://img.shields.io/badge/Support-Windows/Linux-green.svg)](https://github.com/MCSManager)
[![Status](https://img.shields.io/badge/npm-v8.9.14-blue.svg)](https://www.npmjs.com/)
[![Status](https://img.shields.io/badge/node-v16.20.2-blue.svg)](https://nodejs.org/en/download/)
[![Status](https://img.shields.io/badge/License-Apache%202.0-red.svg)](https://github.com/MCSManager)
[Offizielle Website](http://mcsmanager.com/) | [Dokumentation](https://docs.mcsmanager.com/) | [Discord](https://discord.gg/BNpYMVX7Cd)
[Englisch](README.md) | [简体中文](README_ZH.md) | [繁體中文](README_TW.md) | [Português BR](README_PTBR.md) |
[日本語](README_JP.md) | [Spanisch](README_ES.md)
</div>
<br />
## Was ist MCSManager?
**MCSManager Panel** (MCSM) ist ein **modernes, sicheres und verbreitetes Verwaltungspanel**, designt für die Verwaltung von Minecraft und Steam Spielserver.
MCSManager hat bereits eine gewisse Popularität in der Community erlangt, insbesondere durch Minecraft. MCSManager zeichnet sich durch eine zentralisierte Verwaltungslösung für mehrere Serverinstanzen aus und bietet ein sicheres und zuverlässiges Berechtigungssystem für mehrere Benutzer. Darüber hinaus engagieren wir uns für die Unterstützung von Serveradministratoren, nicht nur für Minecraft, sondern auch für Terraria und verschiedene Steam Spiele. Unser Ziel ist es, eine florierende und unterstützende Community für die Verwaltung von Spielservern zu fördern.
MCSManager **unterstützt Englisch, Französisch, Deutsch, Italienisch, Japanisch, Portugiesisch, Chinesisch (Vereinfacht) und Chinesisch (Traditionell)**, mit Plänen mehr Sprachen in der Zukunft zu unterstützen!
**Terminal**
![failed_to_load_screenshot.png](/.github/panel-image.png)
**Instanzliste**
![failed_to_load_screenshot.png](/.github/panel-instances.png)
**Benutzerdefiniertes Layout**
![failed_to_load_screenshot.png](/.github/panel-custom-layout.gif)
## Funktionen
1. Ein-Klick-Bereitstellung von `Minecraft` Java/Bedrock Servers
2. Kompatibel mit den meisten `Steam` Spielservern. (z.B. `Palworld`, `Squad`, `Project Zomboid`, `Terraria`, etc.)
3. Anpassbare Benutzeroberfläche, erstellen Sie Ihr eigenes Layout
4. Unterstützt alle Images auf `Docker Hub`, unterstützt mehrere Benutzer und unterstützt kommerzielle Dienste!
5. Verwalten Sie mehrere Server mit einer einzigen Weboberfläche
6. Der Technologie-Stack ist einfach, und Sie müssen nur gut in Typescript sein, um die gesamte MCSManager-Entwicklung abzuschließen.
7. Und mehr!
<br />
## Laufzeitumgebung
MCSM unterstützt `Windows` und `Linux`. Die einzige Anforderung ist `Node.js` und ein Paar andere Bibliotheken **für die Dekomprimierung**.
Benötigt [Node.js 16.20.2](https://nodejs.org/en) oder höher.
<br />
## Installation
### Windows
Für Windows, stellen wir gepackte ausführbare Dateien zur Verfügung:
Gehe zu: [https://mcsmanager.com/](https://mcsmanager.com/)
<br />
### Linux
**Bereitstellung mit einem Befehl**
> Das Skript muss Systemdienste registrieren und benötigt daher Root-Berechtigungen.
```bash
sudo su -c "wget -qO- https://script.mcsmanager.com/setup.sh | bash"
```
**Verwendung**
```bash
systemctl start mcsm-{web,daemon}
systemctl stop mcsm-{web,daemon}
```
- Unterstützt nur Ubuntu/Centos/Debian/Archlinux.
- Installationsort: `/opt/mcsmanager/`.
<br />
**Linux - Manuelle Installation**
- Wenn das Installationsskript nicht ordnungsgemäß ausgeführt wird, können Sie versuchen, es manuell zu installieren.
```bash
# Erstellen des /opt Verzeichnisses, wenn es nicht bereits existiert
mkdir /opt
# Wechseln zu /opt/
cd /opt/
# Node.js 20.11 herunterladen. Wenn Sie bereits Node.js 16+ installiert haben, können sie diesen Schritt ignorieren.
wget https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz
# Node.js entpacken
tar -xvf node-v20.11.0-linux-x64.tar.xz
# Node.js zum System PATH hinzufügen
ln -s /opt/node-v20.11.0-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v20.11.0-linux-x64/bin/npm /usr/bin/npm
# MCSM's Installationsort vorbereiten
mkdir /opt/mcsmanager/
cd /opt/mcsmanager/
# MCSManager herunterladen
wget https://github.com/MCSManager/MCSManager/releases/latest/download/mcsmanager_linux_release.tar.gz
tar -zxf mcsmanager_linux_release.tar.gz
# Abhängigkeiten installieren
./install.sh
# Bitte öffnen Sie zwei Terminals oder Screens.
# Starten Sie den Daemon zuerst.
./start-daemon.sh
# Starten Sie anschließend das Web-Interface im zweiten Terminal oder Screen.
./start-web.sh
# Gehen Sie für den Webzugriff zu http://localhost:23333/
# Im Allgemeinen scannt das Webinterface automatisch den lokalen Daemon und fügt ihn hinzu.
```
Bei diesem Installationsansatz wird MCSManager nicht automatisch als Systemdienst eingerichtet. Daher ist es notwendig, "Screen" für die Verwaltung zu verwenden. Wenn Sie daran interessiert sind, MCSManager über einen Systemdienst zu verwalten, lesen Sie bitte unser Wiki/unsere Dokumentation.
<br />
## Entwicklung
Dieser Abschnitt wurde speziell für Entwickler entwickelt. Allgemeine Benutzer können diesen Teil ohne Bedenken ignorieren.
### Plugins
Wir verwenden "VS Code", um MCSManager zu entwickeln. Möglicherweise müssen Sie diese Plugins installieren:
- i18n display support (I18n Ally)
- Code formatter (Prettier)
- Vue - Offcial
- ESLint
### MacOS
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.sh
./npm-dev-macos.sh
```
### Windows
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.bat
./npm-dev-windows.bat
```
### Abhängigkeiten
Sie müssen zu den Projekten [PTY](https://github.com/MCSManager/PTY) und [Zip-Tools](https://github.com/MCSManager/Zip-Tools) gehen, um die entsprechenden Binärdateien herunterzuladen und sie im Verzeichnis 'daemon/lib' abzulegen, um das ordnungsgemäße Funktionieren des `Emulation Terminals` und der `File Decompression` sicherzustellen.
### Produktionsversion erstellen
```bash
./build.bat # Windows
./build.sh # MacOS
```
Ausgabe-Verzeichnis: "production-code"
<br />
## Code beitragen
Sollten Sie Probleme bei der Nutzung von MCSManager haben, können Sie gerne [ein Issue](https://github.com/MCSManager/MCSManager/issues/new/choose) einreichen. Alternativ können Sie das Projekt forken und direkt beitragen, indem Sie einen Pull Request einreichen.
Bitte stellen Sie sicher, dass der eingereichte Code unserem bestehenden Codierungsstil entspricht. Weitere Informationen finden Sie in den Richtlinien in [diesem Issue](https://github.com/MCSManager/MCSManager/issues/544).
<br />
## Browser Kompatibilität
- Wird in modernen Browsern wie `Chrome`, `Firefox` und `Safari` unterstützt.
- Die Unterstützung für `IE` wurde eingestellt.
<br />
## BUG Reporting
**Issue erstellen:** [Hier drücken](https://github.com/MCSManager/MCSManager/issues/new/choose)
**Bericht über Sicherheitslücken:** [SECURITY.md](SECURITY.md)
<br />
## Internationalisierung
Vielen Dank an diese Mitwirkenden für die Bereitstellung einer beträchtlichen Menge an Übersetzungen:
- [KevinLu2000](https://github.com/KevinLu2000)
- [Unitwk](https://github.com/unitwk)
- [JianyueLab](https://github.com/JianyueLab)
- [IceBrick](https://github.com/IceBrick01)
<br />
## Lizens
Der Quellcode von MCSManager ist unter der [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) Lizenz lizenziert.
Copyright ©2025 MCSManager.

199
README_ES.md Normal file
View File

@ -0,0 +1,199 @@
<div align="center">
<a href="https://mcsmanager.com/" target="_blank">
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
</a>
<br />
<h1 id="mcsmanager">
<a href="https://mcsmanager.com/" target="_blank">Panel de MCSManager</a>
</h1>
[![--](https://img.shields.io/badge/Support-Windows/Linux-green.svg)](https://github.com/MCSManager)
[![Estado](https://img.shields.io/badge/npm-v8.9.14-blue.svg)](https://www.npmjs.com/)
[![Estado](https://img.shields.io/badge/node-v16.20.2-blue.svg)](https://nodejs.org/en/download/)
[![Licencia](https://img.shields.io/badge/License-Apache%202.0-red.svg)](https://github.com/MCSManager)
[Sitio Oficial](http://mcsmanager.com/) | [Documentación](https://docs.mcsmanager.com/) | [Discord](https://discord.gg/BNpYMVX7Cd)
[Inglés](README.md) | [简体中文](README_ZH.md) | [繁體中文](README_TW.md) | [Deutsch](README_DE.md) | [Português BR](README_PTBR.md) | [日本語](README_JP.md)
</div>
<br />
## ¿Qué es MCSManager?
**Panel de MCSManager** (MCSM) es un **panel de control moderno, seguro y distribuido** diseñado para gestionar servidores de juego de Minecraft y Steam.
MCSManager ha ganado popularidad en la comunidad, especialmente en Minecraft. MCSManager ofrece una solución centralizada para gestionar múltiples instancias de servidor y proporciona un sistema de permisos multiusuario seguro y confiable. Nos comprometemos a apoyar a los administradores de servidores no solo para Minecraft, sino también para Terraria y varios juegos de Steam. Nuestro objetivo es fomentar una comunidad próspera y de apoyo en la gestión de servidores de juego.
MCSManager **admite inglés, francés, alemán, italiano, japonés, portugués, chino simplificado y chino tradicional**, ¡y planea agregar más idiomas en el futuro!
![failed_to_load_screenshot.png](/.github/panel-image.png)
![failed_to_load_screenshot.png](/.github/panel-instances.png)
## Características
1. Implementación con un clic de servidor `Minecraft` Java/Bedrock.
2. Compatible con la mayoría de servidores de juegos de `Steam` (p. ej., `Palworld`, `Squad`, `Project Zomboid`, `Terraria`, etc.).
3. Interfaz personalizable; crea tu propio diseño.
4. Soporte para virtualización con `Docker`, multiusuario y servicios comerciales.
5. Gestiona múltiples servidores desde una sola interfaz web.
6. ¡Y más!
<br />
## Entorno de Ejecución
MCSM es compatible con `Windows` y `Linux`. El único requisito es `Node.js` y algunas librerías **para descompresión**.
Requiere [Node.js 16.20.2](https://nodejs.org/en) o superior.
<br />
## Instalación
### Windows
Para Windows, ofrecemos archivos ejecutables empaquetados:
Ir a: [https://mcsmanager.com/](https://mcsmanager.com/)
<br />
### Linux
**Despliegue con un solo comando**
> El script necesita registrar servicios del sistema, requiere permisos de root.
```bash
sudo su -c "wget -qO- https://script.mcsmanager.com/setup.sh | bash"
```
**Uso**
```bash
systemctl start mcsm-{web,daemon}
systemctl stop mcsm-{web,daemon}
```
- Solo compatible con Ubuntu/Centos/Debian/Archlinux.
- Directorio de instalación: `/opt/mcsmanager/`.
<br />
**Instalación Manual en Linux**
- Si el script de instalación falla, puedes intentar instalarlo manualmente.
```bash
# Crear directorio /opt si no existe
mkdir /opt
# Cambiar a /opt
cd /opt/
# Descargar Node.js 20.11. Si ya tienes Node.js 16+ instalado, omite este paso.
wget https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz
# Descomprimir Node.js
tar -xvf node-v20.11.0-linux-x64.tar.xz
# Agregar Node.js al PATH del sistema
ln -s /opt/node-v20.11.0-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v20.11.0-linux-x64/bin/npm /usr/bin/npm
# Preparar el directorio de instalación de MCSM
mkdir /opt/mcsmanager/
cd /opt/mcsmanager/
# Descargar MCSManager
wget https://github.com/MCSManager/MCSManager/releases/latest/download/mcsmanager_linux_release.tar.gz
tar -zxf mcsmanager_linux_release.tar.gz
# Instalar dependencias
./install.sh
# Abrir dos terminales o pantallas.
# Iniciar el daemon primero.
./start-daemon.sh
# Iniciar la interfaz web en la segunda terminal o pantalla.
./start-web.sh
# Para acceder a la web, ir a http://localhost:23333/
# En general, la interfaz web escaneará y añadirá automáticamente el daemon local.
```
Este método de instalación no configura automáticamente MCSManager como un servicio del sistema. Por lo tanto, es necesario usar `screen` para la administración. Para quienes quieran administrar MCSManager a través de un servicio del sistema, por favor consulta nuestra wiki/documentación.
<br />
## Compatibilidad del Navegador
- Compatible con navegadores modernos como `Chrome`, `Firefox` y `Safari`.
- El soporte para `IE` ha sido discontinuado.
<br />
## Desarrollo
Esta sección está dirigida específicamente a desarrolladores. Los usuarios generales pueden ignorarla sin problema.
### MacOS
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.sh
./npm-dev-macos.sh
```
### Windows
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.bat
./npm-dev-windows.bat
```
### Construir Versión de Producción
```bash
./build.bat # Windows
./build.sh # MacOS
```
Luego, deberás ir a los proyectos [PTY](https://github.com/MCSManager/PTY) y [Zip-Tools](https://github.com/MCSManager/Zip-Tools) para descargar los archivos binarios correspondientes y colocarlos en el directorio `daemon/lib` para asegurar el funcionamiento adecuado del `Terminal de Emulación` y la `Descompresión de Archivos`.
<br />
## Contribución de Código
Si experimentas problemas al usar MCSManager, puedes [enviar un Issue](https://github.com/MCSManager/MCSManager/issues/new/choose). Alternativamente, puedes hacer un fork del proyecto y contribuir directamente enviando un Pull Request.
Asegúrate de que el código enviado siga nuestro estilo de codificación existente. Para más detalles, consulta las pautas en [este issue](https://github.com/MCSManager/MCSManager/issues/544).
<br />
## Reporte de Errores
**Abrir Issue:** [Haz clic aquí](https://github.com/MCSManager/MCSManager/issues/new/choose)
**Reporte de Vulnerabilidades de Seguridad:** [SECURITY.md](SECURITY.md) (en ingles)
<br />
## Internacionalización
Gracias a estos colaboradores por proporcionar una gran cantidad de traducciones:
- [KevinLu2000](https://github.com/KevinLu2000)
- [Unitwk](https://github.com/unitwk)
- [JianyueLab](https://github.com/JianyueLab)
- [IceBrick](https://github.com/IceBrick01)
<br />
## Licencia
El código fuente de MCSManager está licenciado bajo la [Licencia Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0).
Copyright ©2025 MCSManager.

205
README_JP.md Normal file
View File

@ -0,0 +1,205 @@
<div align="center">
<a href="https://mcsmanager.com/" target="_blank">
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
</a>
<br />
<h1 id="mcsmanager">
<a href="https://mcsmanager.com/" target="_blank">MCSManager パネル</a>
</h1>
[![--](https://img.shields.io/badge/Support-Windows/Linux-green.svg)](https://github.com/MCSManager)
[![Status](https://img.shields.io/badge/npm-v8.9.14-blue.svg)](https://www.npmjs.com/)
[![Status](https://img.shields.io/badge/node-v16.20.2-blue.svg)](https://nodejs.org/en/download/)
[![Status](https://img.shields.io/badge/License-Apache%202.0-red.svg)](https://github.com/MCSManager)
[HP](http://mcsmanager.com/) | [ドキュメント](https://docs.mcsmanager.com/) | [Discord](https://discord.gg/BNpYMVX7Cd)
[English](README.md) | [简体中文](README_ZH.md) | [繁體中文](README_TW.md) | [Deutsch](README_DE.md) | [Português BR](README_PTBR.md) | [Spanish](README_ES.md)
</div>
<br />
## MCSManagerとは
**MCSManager パネル**は、マイクラフトMinecraftやsteamのゲームサーバーを管理するために開発されました。このパネルは、モダンで安全な分散型コントロールパネルです。
MCSManagerは、マイクラフトと中心としてコミュニティ内で既に一定の人気を得ています。このパネルは、複数のサーバーインスタンスの集中管理ソリューションを提供し、安全で信頼できるマルチユーザー許可システムも提供します。まだ、マイクラフトだけでなく、Terrariaや色々なSteamゲームサーバーの管理者をサポートします。私たちの目標は、ゲームサーバー管理のために別なコミュニティを育成します。
今まで、MCSManagerは英語、フランス語、ドイツ語、イタリア語、日本語、簡体中国語、繫体中国語をサポートしており、将来は多くの言語のサポートを追加する予定です。
![failed_to_load_screenshot.png](/.github/panel-image.png)
![failed_to_load_screenshot.png](/.github/panel-instances.png)
## 特徴
1. シンプルなマイクラフトサーバーをデプロイメントができます。
2. 他のゲームサーバーもコンパチブルです。(例:`Palworld`, `Squad`, `Project Zomboid`, `Terraria`)
3. 個人的なUIをカスタマイズすることができます。
4. `Docker`デプロイすると商用利用ができます。
5. 一つウェブでマルチサーバー管理することができます。
6. もっと
<br />
## ランタイム環境
MCSMパネルは`Windows``Linux`システムをサポートして、`Node.js`が必要です。
`Node.js`は16.20.2以上が必要です。
<br />
## インスタレーション
### Windows
[MCSM HP](https://mcsmanager.com)でファイルパックをダウンロードしって、`.exe`ファイルを実行するです。
<br />
### Linux
**シンプルデプロイ**
> スクリプトは自動的にシステムサービスを登録して、実行するときはルートパーミッションが必要です。
```bash
sudo su -c "wget -qO- https://script.mcsmanager.com/setup.sh | bash"
```
**コマンド**
```bash
systemctl start mcsm-{web,daemon}
systemctl stop mcsm-{web,daemon}
```
- Ubuntu/Centos/Debian/Archlinuxしかサポートしてないです。
- インストールパス: `/opt/mcsmanager/`.
<br />
**Linux マニュアルのインストール**
- スクリプト実行するときでエロがあったら、マニュアルでインストールもできます。
```bash
# /opt パスなかったら、パスを作成します
mkdir /opt
# /opt パスを開けます
cd /opt/
# Node.js 20.11 ダウンロードします。Node.js 16+ あったら、しなくていいです。
wget https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz
# Node.jsソースの解凍
tar -xvf node-v20.11.0-linux-x64.tar.xz
# Node.jsをシステムパス追加します
ln -s /opt/node-v20.11.0-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v20.11.0-linux-x64/bin/npm /usr/bin/npm
# MCSMのインストールパスを準備します
mkdir /opt/mcsmanager/
cd /opt/mcsmanager/
# MCSMダウンロードします
wget https://github.com/MCSManager/MCSManager/releases/latest/download/mcsmanager_linux_release.tar.gz
tar -zxf mcsmanager_linux_release.tar.gz
# 必要なアプリを自動的にインストールします
./install.sh
# 二つターミナル用意してください
# まず、daemon実行します。
./start-daemon.sh
# daemon実行したら、二つ目のターミナルでウェブを実行します。
./start-web.sh
# ウェブのアドレスは http://localhost:23333/
# ウェブは自動的に同じデバイスインストールしたdaemonを検測して、追加します。
```
マニュアルインストールは、自動的にシステムサービス追加しません。そして、自分でシステムサービス追加するか`screen`しないといけないです。システム追加する方法は、グーグルやウィキペディアで調べてください。
<br />
## ブラウザの互換性
- Supported on modern browsers including `Chrome`, `Firefox`, and `Safari`.
- `Chrome``Firefox``Safari`がサポートしています。
- Support for `IE` has been discontinued.
- 現在は、`IE`のサポートしていません。
<br />
## 開発
以下の情報は、開発者関係のみです。普通のユーザーとは関係ないです。
### MacOS
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.sh
./npm-dev-macos.sh
```
### Windows
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.bat
./npm-dev-windows.bat
```
### Build Production Version
```bash
./build.bat # Windows
./build.sh # MacOS
```
そのあとは、[PTY](https://github.com/MCSManager/PTY)と[Zip-Tools](https://github.com/MCSManager/Zip-Tools) ダウンロードして、解凍して、対応の`daemon/lib`パスへ移動してください。
<br />
## コード貢献
問題と意見あったら、GitHubのissueへ提出してください。プロジェクトforkしたら、そして、Pull Requestへcommit出して貢献することができます。
もし、貢献するは、コードのスタイルが現在と似てっる感じしてください。詳細は、[ガイドライン](https://github.com/MCSManager/MCSManager/issues/544)見てください。
<br />
## BUG レポート
**IssueとBUG:** [押してください](https://github.com/MCSManager/MCSManager/issues/new/choose)
**安全関係のレポート:** [SECURITY.md](SECURITY.md)
<br />
## 国際化
以下の人は、多量の翻訳してありがどうございます:
- [KevinLu2000](https://github.com/KevinLu2000)
- [Unitwk](https://github.com/unitwk)
- [JianyueLab](https://github.com/JianyueLab)
- [IceBrick](https://github.com/IceBrick01)
<br />
## ライセンス
ソースコードは、 [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)ライセンス使っています。
Copyright ©2025 MCSManager.

204
README_PTBR.md Normal file
View File

@ -0,0 +1,204 @@
<div align="center">
<a href="https://mcsmanager.com/" target="_blank">
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
</a>
<br />
<h1 id="mcsmanager">
<a href="https://mcsmanager.com/" target="_blank">Painel MCSManager</a>
</h1>
[![--](https://img.shields.io/badge/Support-Windows/Linux-green.svg)](https://github.com/MCSManager)
[![Status](https://img.shields.io/badge/npm-v8.9.14-blue.svg)](https://www.npmjs.com/)
[![Status](https://img.shields.io/badge/node-v16.20.2-blue.svg)](https://nodejs.org/en/download/)
[![Status](https://img.shields.io/badge/License-Apache%202.0-red.svg)](https://github.com/MCSManager)
[Website Oficial](http://mcsmanager.com/) | [Documentação](https://docs.mcsmanager.com/) | [Discord](https://discord.gg/BNpYMVX7Cd)
[English](README.md) | [简体中文](README_ZH.md) | [繁體中文](README_TW.md) | [Deutsch](README_DE.md) |
[日本語](README_JP.md) | [Spanish](README_ES.md)
</div>
<br />
## O que é o MCSManager?
O **Painel MCSManager** (MCSM) é um **painel de controle moderno, seguro e distribuído** projetado para gerenciar servidores de jogos Minecraft e Steam.
O MCSManager já conquistou um certo nível de popularidade dentro da comunidade, especificamente a de Minecraft. O MCSManager se destaca por oferecer uma solução de gerenciamento centralizado para várias instâncias de servidores e proporciona um sistema de permissões multiusuário seguro e confiável. Além disso, estamos comprometidos em apoiar os administradores de servidores não apenas para Minecraft, mas também para Terraria e diversos jogos da Steam. Nosso objetivo é fomentar uma comunidade próspera e colaborativa para o gerenciamento de servidores de jogos.
O MCSManager **suporta Alemão, Chinês Simplificado, Chinês Tradicional, Inglês, Francês, Italiano, Japonês e Português**, com planos de adicionar suporte para mais idiomas no futuro!
![failed_to_load_screenshot.png](/.github/panel-image.png)
![failed_to_load_screenshot.png](/.github/panel-instances.png)
## Features
1. Implantação com um clique do servidor `Minecraft` Java/Bedrock
2. Compatível com a maioria dos servidores de jogos da `Steam` (ex.: `Palworld`, `Squad`, `Project Zomboid`, `Terraria`, etc.)
3. Interface personalizável, crie seu próprio layout
4. Suporte à virtualização `Docker`, multiusuário e serviços comerciais
5. Gerencie múltiplos servidores com uma única interface web
6. E mais...
<br />
## Ambiente de Execução
O MCSM suporta tanto `Windows` quanto `Linux`. O único requisito é `Node.js` e algumas bibliotecas **para descompressão**.
Requer [Node.js 16.20.2](https://nodejs.org/en) ou superior.
<br />
## Instalação
### Windows
Para Windows, fornecemos arquivos executáveis empacotados:
Acesse: [https://mcsmanager.com/](https://mcsmanager.com/)
<br />
### Linux
**Implantação com um Comando**
> O script precisa registrar serviços do sistema, portanto, requer permissões de root.
```bash
sudo su -c "wget -qO- https://script.mcsmanager.com/setup.sh | bash"
```
**Uso**
```bash
systemctl start mcsm-{web,daemon}
systemctl stop mcsm-{web,daemon}
```
- Suporta apenas Ubuntu/Centos/Debian/Archlinux.
- Diretório de instalação: `/opt/mcsmanager/`.
<br />
**Instalação Manual no Linux**
- Se o script de instalação falhou ao ser executado corretamente, você pode tentar instalar manualmente.
```bash
# Criar o diretório /opt se ainda não existir
mkdir /opt
# Mudar para o diretório /opt
cd /opt/
# Baixar o Node.js 20.11. Se você já tiver o Node.js 16+ instalado, ignore este passo.
wget https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz
# Descompactar o código-fonte do Node.js
tar -xvf node-v20.11.0-linux-x64.tar.xz
# Adicionar o Node.js ao PATH do sistema
ln -s /opt/node-v20.11.0-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v20.11.0-linux-x64/bin/npm /usr/bin/npm
# Preparar o diretório de instalação do MCSM
mkdir /opt/mcsmanager/
cd /opt/mcsmanager/
# Baixar o MCSManager
wget https://github.com/MCSManager/MCSManager/releases/latest/download/mcsmanager_linux_release.tar.gz
tar -zxf mcsmanager_linux_release.tar.gz
# Instalar dependências
./install.sh
# Por favor, abra dois terminais ou telas separadas.
# Inicie o daemon primeiro.
./start-daemon.sh
# Inicie a interface web no segundo terminal ou tela.
./start-web.sh
# Para acessar a web, vá para http://localhost:23333/
# Geralmente, a interface web irá escanear e adicionar automaticamente o daemon local.
```
Este método de instalação não configura automaticamente o MCSManager como um serviço do sistema. Portanto, é necessário usar `screen` para gerenciamento. Para aqueles interessados em gerenciar o MCSManager por meio de um serviço do sistema, consulte nossa wiki/documentação.
<br />
## Compatibilidade com Navegadores
- Suportado em navegadores modernos, incluindo `Chrome`, `Firefox` e `Safari`.
- O suporte ao `IE` foi descontinuado.
<br />
## Desenvolvimento
Esta seção é especificamente projetada para desenvolvedores. Usuários comuns podem ignorar esta parte sem preocupações.
### MacOS
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.sh
./npm-dev-macos.sh
```
### Windows
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.bat
./npm-dev-windows.bat
```
### Build Production Version
```bash
./build.bat # Windows
./build.sh # MacOS
```
Em seguida, você precisará acessar os projetos [PTY](https://github.com/MCSManager/PTY) e [Zip-Tools](https://github.com/MCSManager/Zip-Tools) para baixar os arquivos binários correspondentes e colocá-los no diretório `daemon/lib` para garantir o funcionamento adequado do `Terminal de Emulação` e `Descompressão de Arquivos`.
<br />
## Contribuição de Código
Se você encontrar algum problema ao usar o MCSManager, sinta-se à vontade para [enviar um Issue](https://github.com/MCSManager/MCSManager/issues/new/choose). Alternativamente, você pode fazer um fork do projeto e contribuir diretamente enviando um Pull Request.
Por favor, certifique-se de que qualquer código enviado siga o estilo de codificação existente. Para mais detalhes, consulte as diretrizes fornecidas [neste issue](https://github.com/MCSManager/MCSManager/issues/544).
<br />
## Relatório de BUGs
**Criar Issue:** [Clique aqui](https://github.com/MCSManager/MCSManager/issues/new/choose)
**Relatório de Vulnerabilidade de Segurança:** [SECURITY.md](SECURITY.md)
<br />
## Internacionalização
Agradecemos aos seguintes colaboradores por fornecerem uma quantidade substancial de tradução:
- [KevinLu2000](https://github.com/KevinLu2000)
- [Unitwk](https://github.com/unitwk)
- [JianyueLab](https://github.com/JianyueLab)
- [IceBrick](https://github.com/IceBrick01)
<br />
## Licença
O código-fonte do MCSManager é licenciado sob a Licença [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0).
Copyright ©2025 MCSManager.

218
README_TW.md Normal file
View File

@ -0,0 +1,218 @@
<div align="center">
<a href="https://mcsmanager.com/" target="_blank">
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
</a>
<br />
<h1 id="mcsmanager">
<a href="https://mcsmanager.com/" target="_blank">MCSManager Panel</a>
</h1>
[![--](https://img.shields.io/badge/Support-Windows/Linux-green.svg)](https://github.com/MCSManager)
[![Status](https://img.shields.io/badge/npm-v8.9.14-blue.svg)](https://www.npmjs.com/)
[![Status](https://img.shields.io/badge/node-v16.20.2-blue.svg)](https://nodejs.org/en/download/)
[![Status](https://img.shields.io/badge/License-Apache%202.0-red.svg)](https://github.com/MCSManager)
[官方網站](http://mcsmanager.com/) | [教學說明](https://docs.mcsmanager.com/#/zh-cn/) | [TG 群組](https://t.me/MCSManager_dev) | [成為贊助者](https://afdian.net/a/mcsmanager)
[English](README.md) | [简体中文](README_ZH.md) | [Deutsch](README_DE.md) | [Português BR](README_PTBR.md) |
[日本語](README_JP.md) | [Spanish](README_ES.md)
</div>
<br />
## 這是什麼?
**MCSManager 面板**簡稱MCSM 面板)是一款免費,開源,分散式,輕量級,快速部署,支援 Minecraft 和 Steam 遊戲伺服器的 Web 管理面板。
此軟體在 `Minecraft` 和其他遊戲社群內中已有一定的流行程度,它可以幫助你集中管理多個實體伺服器,實現在任何主機上建立遊戲伺服器,並且提供安全可靠的多使用者權限系統,可以很輕鬆的幫助你管理多個伺服器,一直在為 `Minecraft``Terraria``Steam` 遊戲伺服器的管理員,維護人員和個人開發者提供健康的軟體支援。
![截圖載入失敗,請科學上網.png](/.github/panel-image.png)
![截圖載入失敗,請科學上網.png](/.github/panel-instances.png)
<br />
## 功能特性
1. 支援快速開服! 輕鬆部署 `Minecraft` Java 版/基岩版遊戲伺服器。
2. 相容於大部分 `Steam` 遊戲伺服器,例如 `幻獸帕魯``Squad``Project Zomboid``Terraria` 等。
3. 網頁支援拖拉式的小卡片佈局,打造自己喜歡的介面佈局。
4. 支援 `Docker` 虛擬化,支援多使用者,支援商業出租行為。
5. 支援所有 `Docker` 映像,輕鬆打造預設!
6. 支援分散式,一個網頁即可同時管理數台機器。
7. 更多...
<br />
## 執行環境
控制面板可執行在 `Windows``Linux` 平台,無需安裝資料庫,只需安裝 `Node.js` 環境和幾個**用於解壓縮**的指令。
必須使用 [Node.js 16.20.2](https://nodejs.org/en) 以上,建議使用最新版本 LTS 版本。
<br />
## 安裝
### Windows
對於 Windows 系統,**已整合成快速啟動版本,下載即可執行**:
前往:[https://mcsmanager.com/](https://mcsmanager.com/)
<br />
### Linux
**快速安裝**
```bash
sudo su -c "wget -qO- https://script.mcsmanager.com/setup.sh | bash"
```
**安裝後的使用方法**
```bash
systemctl start mcsm-{web,daemon} # 開啟面板
systemctl stop mcsm-{web,daemon} # 關閉面板
```
- 快速安裝指令只適用於 Ubuntu/Centos/Debian/Archlinux。
- 面板程式碼與執行環境自動安裝在 `/opt/mcsmanager/` 資料夾下。
<br />
**Linux 手動安裝**
- 若快速安裝無法使用,則可以嘗試此步驟手動安裝。
```bash
# 切換到安裝資料夾。 如果沒有這個資料夾,請先輸入 mkdir /opt/ 新增它。
cd /opt/
# 下載執行環境Node.js。 如果你已經安裝了 Node.js 16+,請忽略此步驟。
wget https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz
# 解壓縮檔案
tar -xvf node-v20.11.0-linux-x64.tar.xz
# 新增程式到系統環境變數
ln -s /opt/node-v20.11.0-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v20.11.0-linux-x64/bin/npm /usr/bin/npm
# 準備好安裝資料夾
mkdir /opt/mcsmanager/
cd /opt/mcsmanager/
# 下載 MCSManager
wget https://github.com/MCSManager/MCSManager/releases/latest/download/mcsmanager_linux_release.tar.gz
tar -zxf mcsmanager_linux_release.tar.gz
# 安裝函式庫
./install.sh
# 請開啟兩個終端機或 screen
# 先啟動節點程式
./start-daemon.sh
# 啟動網頁服務(在第二個終端機或 screen)
./start-web.sh
# 進入 http://localhost:23333/ 開始使用
# 一般來說,網頁服務會自動掃描並連接到本機節點。
```
這種安裝方式不會自動註冊系統服務(Service),所以必須使用 `screen` 軟體來管理,如果你希望由系統服務來接管 MCSManager請參考文件。
<br />
## 瀏覽器相容性
- 支援 `Chrome` `Firefox` `Safari` `Opera` 等現代主流瀏覽器。
- 已放棄支援 `IE` 瀏覽器。
<br />
## 建立開發環境
這是給開發人員使用的,一般使用者可直接跳過這個環節。
### MacOS
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.sh
./npm-dev-macos.sh
```
### Windows
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.bat
./npm-dev-windows.bat
```
### 編譯正式環境版本
```bash
./build.bat # Windows
./build.sh # MacOS
```
接下來你還需要前往 [PTY](https://github.com/MCSManager/PTY) 和 [Zip-Tools](https://github.com/MCSManager/Zip-Tools) 兩個專案下載對應的檔案,將他們存放到 `daemon/lib` 目錄下,以確保 `模擬終端機``解壓縮檔案` 正常運作。
<br />
## 貢獻程式碼
如果你在使用過程中發現任何問題,可以 [提交 Issue](https://github.com/MCSManager/MCSManager/issues/new/choose) 或自行 Fork 修改後提交 Pull Request。
程式碼需保持現有格式,不得刪除多餘程式碼,具體可[參考這裡](https://github.com/MCSManager/MCSManager/issues/544)。
<br />
## 回報 BUG
歡迎回報發現到的任何問題,將會快速修復。
若發現嚴重安全漏洞又不方便公開發布,請 E-mail 至: support@mcsmanager.com安全問題修復後將在程式碼中附加漏洞發現者姓名。
<br />
## 國際化
感謝下列成員提供的**大量**翻譯檔案:
- [KevinLu2000](https://github.com/KevinLu2000)
- [Unitwk](https://github.com/unitwk)
- [JianyueLab](https://github.com/JianyueLab)
- [IceBrick](https://github.com/IceBrick01)
<br />
## 原始碼協定
原始碼遵循 [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) 協定。
Copyright ©2025 MCSManager.

212
README_ZH.md Normal file
View File

@ -0,0 +1,212 @@
<div align="center">
<a href="https://mcsmanager.com/" target="_blank">
<img src="https://public-link.oss-cn-shenzhen.aliyuncs.com/mcsm_picture/logo.png" alt="MCSManagerLogo.png" width="510px" />
</a>
<br />
<h1 id="mcsmanager">
<a href="https://mcsmanager.com/" target="_blank">MCSManager Panel</a>
</h1>
[![--](https://img.shields.io/badge/Support-Windows/Linux-green.svg)](https://github.com/MCSManager)
[![Status](https://img.shields.io/badge/npm-v8.9.14-blue.svg)](https://www.npmjs.com/)
[![Status](https://img.shields.io/badge/node-v16.20.2-blue.svg)](https://nodejs.org/en/download/)
[![Status](https://img.shields.io/badge/License-Apache%202.0-red.svg)](https://github.com/MCSManager)
[官方网站](http://mcsmanager.com/) | [使用文档](https://docs.mcsmanager.com/#/zh-cn/) | [QQ 群](https://jq.qq.com/?_wv=1027&k=Pgl9ScGw) | [TG 群](https://t.me/MCSManager_dev) | [成为赞助者](https://afdian.net/a/mcsmanager)
[English](README.md) | [繁體中文](README_TW.md) | [Deutsch](README_DE.md) | [Português BR](README_PTBR.md) |
[日本語](README_JP.md) | [Spanish](README_ES.md)
</div>
<br />
## 这是什么?
**MCSManager 面板**简称MCSM 面板)是一款免费,开源,分布式,轻量级,快速部署,支持 Minecraft 和 Steam 游戏服务器的 Web 管理面板。
此软件在 `Minecraft` 和其他游戏社区内中已有一定的流行程度,它可以帮助你集中管理多个物理服务器,实现在任何主机上创建游戏服务器,并且提供安全可靠的多用户权限系统,可以很轻松的帮助你管理多个服务器,一直在为 `Minecraft``Terraria``Steam` 游戏服务器的管理员,运维人员和个人开发者提供健康的软件支持。
![截图加载失败,请科学上网.png](/.github/panel-image.png)
![截图加载失败,请科学上网.png](/.github/panel-instances.png)
<br />
## 功能特性
1. 支持一键开服!轻松部署 `Minecraft` Java 版/基岩版游戏服务器。
2. 兼容大部分 `Steam` 游戏服务器,列如 `幻兽帕鲁``战术小队``僵尸毁灭工程``泰拉瑞亚` 等。
3. 网页支持拖拽式的小卡片布局,打造自己喜欢的界面布局。
4. 支持 `Docker Hub` 上的所有镜像,支持多用户,支持商业服务。
5. 支持分布式,一个网页即可同时管理数台机器。
6. 技术栈简单,仅需擅长 Typescript 即可完成整个 MCSManager 开发!
7. 更多...
<br />
## 运行环境
控制面板可运行在 `Windows``Linux` 平台,无需安装数据库,只需安装 `Node.js` 环境和几个**用于解压缩**的命令。
必须使用 [Node.js 16.20.2](https://nodejs.org/en) 以上,推荐使用最新版本 LTS 版本。
<br />
## 安装
### Windows
对于 Windows 系统,**已整合成直接运行版本,下载即可运行**:
前往:[https://mcsmanager.com/](https://mcsmanager.com/)
<br />
### Linux
**一行命令快速安装**
```bash
sudo su -c "wget -qO- https://script.mcsmanager.com/setup_cn.sh | bash"
```
**安装后的使用方法**
```bash
systemctl start mcsm-{web,daemon} # 开启面板
systemctl stop mcsm-{web,daemon} # 关闭面板
```
- 脚本仅适用于 Ubuntu/Centos/Debian/Archlinux。
- 面板代码与运行环境自动安装在 `/opt/mcsmanager/` 目录下。
<br />
**Linux 手动安装**
- 若一键安装不起作用,则可以尝试此步骤手动安装。
```bash
# 切换到安装目录。如果不存在,请提前用'mkdir /opt/'创建它。
cd /opt/
# 下载运行时环境Node.js。如果你已经安装了Node.js 16+,请忽略此步骤。
wget https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz
# 解压档案
tar -xvf node-v20.11.0-linux-x64.tar.xz
# 添加程序到系统环境变量
ln -s /opt/node-v20.11.0-linux-x64/bin/node /usr/bin/node
ln -s /opt/node-v20.11.0-linux-x64/bin/npm /usr/bin/npm
# 准备好安装目录
mkdir /opt/mcsmanager/
cd /opt/mcsmanager/
# 下载MCSManager
wget https://github.com/MCSManager/MCSManager/releases/latest/download/mcsmanager_linux_release.tar.gz
tar -zxf mcsmanager_linux_release.tar.gz
# 安装依赖库
./install.sh
# 请打开两个终端或screen
# 先启动节点程序
./start-daemon.sh
# 启动网络服务(在第二个终端或screen)
./start-web.sh
# 为网络界面访问http://localhost:23333/
# 一般来说,网络应用会自动扫描并连接到本地守护进程。
```
这种安装方式不会自动注册面板到系统服务Service所以必须使用 `screen` 软件来管理,如果你希望由系统服务来接管 MCSManager请参考文档。
<br />
## 搭建开发环境
此段落面向开发人员,普通用户无需关注也无需执行。
### 必备插件
我们使用 “VS Code” 开发 MCSManager你可能需要安装这些插件
- i18n 文案显示支持I18n Ally
- 代码格式化Prettier
- Vue - Offcial
- ESLint
### MacOS
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.sh
./npm-dev-macos.sh
```
### Windows
```bash
git clone https://github.com/MCSManager/MCSManager.git
./install-dependents.bat
./npm-dev-windows.bat
```
### 依赖文件
接下来你还需要前往 [PTY](https://github.com/MCSManager/PTY) 和 [Zip-Tools](https://github.com/MCSManager/Zip-Tools) 两个项目下载对应的二进制文件,将他们存放到 `daemon/lib` 目录下,以确保 `仿真终端``文件解压缩` 的正常工作。
### 构建生产环境版本
```bash
./build.bat # Windows
./build.sh # MacOS
```
最终产物目录: "production-code"
<br />
## 贡献代码
如果你在使用过程中发现任何问题,可以 [提交 Issue](https://github.com/MCSManager/MCSManager/issues/new/choose) 或自行 Fork 修改后提交 Pull Request。
代码需要保持现有格式,不得格式化多余代码,具体可[参考这里](https://github.com/MCSManager/MCSManager/issues/544)。
<br />
## 浏览器兼容性
- 支持 `Chrome` `Firefox` `Safari` `Opera` 等现代主流浏览器。
- 已放弃支持 `IE` 浏览器。
<br />
## BUG 报告
欢迎发现的任何问题进行反馈,必当及时修复。
若发现严重安全漏洞又不便公开发布,请发送邮件至: support@mcsmanager.com安全问题修复后将在代码中附加漏洞发现者姓名。
<br />
## 国际化
感谢下列成员提供的**大量**翻译文件:
- [KevinLu2000](https://github.com/KevinLu2000)
- [Unitwk](https://github.com/unitwk)
- [JianyueLab](https://github.com/JianyueLab)
- [IceBrick](https://github.com/IceBrick01)
<br />
## 源代码协议
源代码遵循 [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) 协议。
Copyright ©2025 MCSManager.

11
SECURITY.md Normal file
View File

@ -0,0 +1,11 @@
## Security Vulnerability Reporting
If you discover a security vulnerability in MCSManager and believe it may harm other users, and you are willing to help us fix it but do not wish to disclose the details publicly.
**Please send detailed information to our email: support@mcsmanager.com.**
The email subject format should be: `[Security Vulnerability] <Title>`
Please provide detailed steps to reproduce the security vulnerability, its impact, and we will reply and express our gratitude upon receiving your email.
We will acknowledge your contribution by adding your name to the `readme.md` and `code`!

21
app.js
View File

@ -1,21 +0,0 @@
// Copyright (C) 2022 MCSManager <mcsmanager-dev@outlook.com>
console.log(`______ _______________________ ___
___ |/ /_ ____/_ ___/__ |/ /_____ _____________ _______ _____________
__ /|_/ /_ / _____ \\__ /|_/ /_ __ /_ __ \\ __ /_ __ / _ \\_ ___/
_ / / / / /___ ____/ /_ / / / / /_/ /_ / / / /_/ /_ /_/ // __/ /
/_/ /_/ \\____/ /____/ /_/ /_/ \\__,_/ /_/ /_/\\__,_/ _\\__, / \\___//_/
/____/
+ https://github.com/MCSManager
`);
console.log(`The installation and startup method you are using is no longer supported,
you may be reading an older version of the MCSManager tutorial or documentation.
Please go to https://mcsmanager.com/ official website for the latest installation method.
The program has automatically exited.
`);
console.log(`您使用的安装和启动方式已经不再支持,您可能正在阅读旧版本的 MCSManager 教程或文档。
请前往 https://mcsmanager.com/ 官方网站了解最新安装方式。
程序已自动退出
`);

58
build.bat Executable file
View File

@ -0,0 +1,58 @@
call npm run preview-build
rd /s /q "production-code"
rd /s /q ".\daemon\dist"
rd /s /q ".\daemon\production"
rd /s /q ".\panel\dist"
rd /s /q ".\panel\production"
echo "Build daemon..."
cd daemon
call npm run build
echo "Build panel..."
cd ../panel
call npm run build
echo "Build frontend..."
cd ../frontend
call npm run build
echo "Collecting files..."
cd ..
mkdir "production-code"
mkdir "production-code\daemon"
mkdir "production-code\web"
mkdir "production-code\web\public"
copy ".\daemon\production\app.js" ".\production-code\daemon\app.js"
copy ".\daemon\production\app.js.map" ".\production-code\daemon\app.js.map"
copy ".\daemon\package.json" ".\production-code\daemon\package.json"
copy ".\daemon\package-lock.json" ".\production-code\daemon\package-lock.json"
copy ".\panel\production\app.js" ".\production-code\web\app.js"
copy ".\panel\production\app.js.map" ".\production-code\web\app.js.map"
copy ".\panel\package.json" ".\production-code\web\package.json"
copy ".\panel\package-lock.json" ".\production-code\web\package-lock.json"
xcopy ".\frontend\dist" ".\production-code\web\public" /E /I /H /Y
rd /s /q ".\panel\production"
rd /s /q ".\daemon\production"
rd /s /q ".\daemon\dist"
rd /s /q ".\panel\dist"
rd /s /q ".\frontend\dist"
cd "production-code\daemon"
call npm install --production
cd "../web"
call npm install --production
cd "../../"
echo "------------"
echo "Compilation completed!"
echo "Output Directory: ./production-code/"
echo "------------"
pause

57
build.sh Executable file
View File

@ -0,0 +1,57 @@
#!/bin/sh
set -e
BASE_PATH=$(pwd)
npm run preview-build
rm -rf production-code
rm -rf ./daemon/dist ./daemon/production
rm -rf ./panel/dist ./panel/production
echo "Build daemon..."
cd "${BASE_PATH}/daemon"
npm run build
echo "Build panel..."
cd "${BASE_PATH}/panel"
npm run build
echo "Build frontend..."
cd "${BASE_PATH}/frontend"
npm run build
echo "Collecting files..."
cd "${BASE_PATH}"
mkdir production-code
mkdir production-code/daemon
mkdir production-code/web
mkdir production-code/web/public
mv "${BASE_PATH}/daemon/production/app.js" "${BASE_PATH}/production-code/daemon"
mv "${BASE_PATH}/daemon/production/app.js.map" "${BASE_PATH}/production-code/daemon"
cp -f "${BASE_PATH}/daemon/package.json" "${BASE_PATH}/production-code/daemon/package.json"
cp -f "${BASE_PATH}/daemon/package-lock.json" "${BASE_PATH}/production-code/daemon/package-lock.json"
mv "${BASE_PATH}/panel/production/app.js" "${BASE_PATH}/production-code/web"
mv "${BASE_PATH}/panel/production/app.js.map" "${BASE_PATH}/production-code/web"
cp -f "${BASE_PATH}/panel/package.json" "${BASE_PATH}/production-code/web/package.json"
cp -f "${BASE_PATH}/panel/package-lock.json" "${BASE_PATH}/production-code/web/package-lock.json"
mv "${BASE_PATH}"/frontend/dist/* "${BASE_PATH}/production-code/web/public"
rm -rf "${BASE_PATH}/daemon/dist" "${BASE_PATH}/daemon/production"
rm -rf "${BASE_PATH}/panel/dist" "${BASE_PATH}/panel/production"
rm -rf "${BASE_PATH}/frontend/dist"
cd "${BASE_PATH}/production-code/daemon"
npm install --production --no-fund --no-audit
cd "${BASE_PATH}/production-code/web"
npm install --production --no-fund --no-audit
echo "------------"
echo "Compilation completed!"
echo "Output Directory: ./production-code/"
echo "------------"

223
common/global.d.ts vendored Normal file
View File

@ -0,0 +1,223 @@
/*
Please ensure that all NEW fields cannot be divided again,
and the old configuration will be ignored.
Do not write:
steamOptions: {
ip: boolean;
port: boolean;
};
Write:
steamIp: ""
steamPort: 8080
*/
export interface IGlobalInstanceConfig {
nickname: string;
startCommand: string;
stopCommand: string;
cwd: string;
ie: string;
oe: string;
createDatetime: number;
lastDatetime: number;
type: string;
tag: string[];
endTime: number;
fileCode: string;
processType: string;
updateCommand: string;
actionCommandList: any[];
crlf: number;
category: number;
// Steam RCON
enableRcon?: boolean;
rconPassword?: string;
rconPort?: number;
rconIp?: string;
// Old fields
terminalOption: {
haveColor: boolean;
pty: boolean;
};
eventTask: {
autoStart: boolean;
autoRestart: boolean;
ignore: boolean;
};
docker: IGlobalInstanceDockerConfig;
pingConfig: {
ip?: string;
port?: number;
type?: number;
};
extraServiceConfig: {
openFrpTunnelId?: string;
openFrpToken?: string;
};
}
export interface IGlobalInstanceDockerConfig {
containerName?: string;
image?: string;
memory?: number;
ports?: string[];
extraVolumes?: string[];
maxSpace?: number;
network?: number;
io?: number;
networkMode?: string;
networkAliases?: string[];
cpusetCpus?: string;
cpuUsage?: number;
workingDir?: string;
env?: string[];
changeWorkdir?: boolean;
}
export interface IPanelResponseProtocol {
data: any;
timestamp: number;
status: number;
}
export interface IPanelOverviewRemoteResponse {
version: string;
process?: {
cpu: number;
memory: number;
cwd: string;
};
instance?: {
running: number;
total: number;
};
system?: {
type: string;
hostname: string;
platform: string;
release: string;
uptime: number;
cwd: string;
loadavg: number[];
freemem: number;
cpuUsage: number;
memUsage: number;
totalmem: number;
processCpu: number;
processMem: number;
};
cpuMemChart?: {
cpu: number;
mem: number;
}[];
uuid: string;
ip: string;
port: number;
prefix: string;
available: boolean;
remarks: string;
}
export interface IPanelOverviewResponse {
version: string;
specifiedDaemonVersion: string;
process: {
cpu: number;
memory: number;
cwd: string;
};
record: {
logined: number;
illegalAccess: number;
banips: number;
loginFailed: number;
};
system: {
user: any;
time: number;
totalmem: number;
freemem: number;
type: string;
version: string;
node: string;
hostname: string;
loadavg: number[];
platform: string;
release: string;
uptime: number;
cpu: number;
};
chart: {
system: { cpu: number; mem: number }[];
request: { value: number; totalInstance: number; runningInstance: number }[];
};
remoteCount: {
available: number;
total: number;
};
remote: IPanelOverviewRemoteResponse[];
}
export interface IJsonData {
[key: string]: any;
}
export interface IMapData<T> {
[key: string]: T;
}
export interface IPageLayoutConfig {
page: string;
items: ILayoutCard[];
theme?: {
backgroundImage: string;
};
}
export interface ILayoutCardParams {
field: string;
label: string;
type: "string" | "number" | "boolean" | "instance";
}
export interface ILayoutCard {
id: string;
type: string;
title: string;
width: number;
height: string;
meta: IJsonData;
disableAdd?: boolean;
onlyPath?: string[];
params?: ILayoutCardParams[];
followId?: string;
description?: string;
allowedPages?: Array<string> | null;
line?: number;
disableDelete?: boolean;
}
export interface IQuickStartPackages {
language: string;
description: string;
title: string;
runtime: string;
size: string;
hardware: string;
remark: string;
targetLink?: string;
author: string;
setupInfo?: IJsonData;
}
export interface IQuickStartTemplate {
remark: string;
languages: {
label: string;
value: string;
}[];
packages: IQuickStartPackages[];
}

1598
common/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

28
common/package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "common",
"version": "1.0.0",
"description": "MCSManager Common layer",
"main": "dist/index.js",
"homepage": "https://mcsmanager.com/",
"author": "https://github.com/unitwk",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/MCSManager/MCSManager"
},
"scripts": {
"build": "tsc --project tsconfig.json"
},
"dependencies": {
"@types/fs-extra": "^11.0.4",
"@types/node": "^20.9.0",
"@types/os-utils": "^0.0.4",
"archiver": "^6.0.1",
"compressing": "^1.10.0",
"fs-extra": "^11.1.1",
"node-stream-zip": "^1.15.0",
"os-utils": "^0.0.14",
"socket.io": "^4.7.2",
"typescript": "^4.9.4"
}
}

5
common/src/array.ts Normal file
View File

@ -0,0 +1,5 @@
export function arrayUnique<T>(arr: T[], felidName?: string): T[] {
if (!felidName) return Array.from(new Set(arr));
const map = new Map();
return arr.filter((v: any) => !map.has(v[felidName]) && map.set(v[felidName], v));
}

View File

@ -1,5 +1,3 @@
// Copyright (C) 2022 MCSManager <mcsmanager-dev@outlook.com>
export default class GlobalVariable {
public static readonly map = new Map<string, any>();

30
common/src/index.ts Normal file
View File

@ -0,0 +1,30 @@
import StorageSubsystem from "./system_storage";
import GlobalVariable from "./global_variable";
import InstanceStreamListener from "./instance_stream";
import MCServerStatus from "./mcping";
export { ProcessWrapper, killProcess } from "./process_tools";
export { systemInfo } from "./system_info";
export {
QueryMapWrapper,
IDataSource,
MySqlSource,
LocalFileSource,
QueryWrapper
} from "./query_wrapper";
export {
configureEntityParams,
toText,
toBoolean,
toNumber,
isEmpty,
supposeValue
} from "./typecheck";
export { arrayUnique } from "./array";
export { removeTrail } from "./string_utils";
export { MCServerStatus, StorageSubsystem, GlobalVariable, InstanceStreamListener };

View File

@ -1,16 +1,15 @@
// Copyright (C) 2022 MCSManager <mcsmanager-dev@outlook.com>
import { Socket } from "socket.io";
// Application instance data stream forwarding adapter
export default class InstanceStreamListener {
// Instance uuid -> Socket[]
public readonly listenMap = new Map<string, Socket[]>();
public constructor() {}
public requestForward(socket: Socket, instanceUuid: string) {
if (this.listenMap.has(instanceUuid)) {
const sockets = this.listenMap.get(instanceUuid);
if (!sockets) return;
for (const iterator of sockets)
if (iterator.id === socket.id)
throw new Error(
@ -26,14 +25,14 @@ export default class InstanceStreamListener {
if (!this.listenMap.has(instanceUuid))
throw new Error(`The specified ${instanceUuid} does not exist in the listening table`);
const socketList = this.listenMap.get(instanceUuid);
socketList.forEach((v, index) => {
if (v.id === socket.id) socketList.splice(index, 1);
socketList?.forEach((v, index) => {
if (v.id === socket.id) socketList?.splice(index, 1);
});
}
public forward(instanceUuid: string, data: any) {
const sockets = this.listenMap.get(instanceUuid);
sockets.forEach((socket) => {
sockets?.forEach((socket) => {
if (socket && socket.connected) socket.emit("instance/stdout", data);
});
}
@ -41,13 +40,13 @@ export default class InstanceStreamListener {
public forwardViaCallback(instanceUuid: string, callback: (socket: Socket) => void) {
if (this.listenMap.has(instanceUuid)) {
const sockets = this.listenMap.get(instanceUuid);
sockets.forEach((socket) => {
sockets?.forEach((socket) => {
if (socket && socket.connected) callback(socket);
});
}
}
public hasListenInstance(instanceUuid: string) {
return this.listenMap.has(instanceUuid) && this.listenMap.get(instanceUuid).length > 0;
return this.listenMap.has(instanceUuid) && this.listenMap?.get(instanceUuid)!.length > 0;
}
}

131
common/src/mcping.ts Executable file
View File

@ -0,0 +1,131 @@
// Using SLT (Server List Ping) provided by Minecraft.
// https://wiki.vg/Server_List_Ping#Response
import net from "net";
export interface MinecraftPingResponse {
host: string;
port: number;
online: boolean;
version: string;
motd: string;
current_players: number;
max_players: number;
latency: number;
}
export default class PingMinecraftServer {
public port: number;
public host: string;
public status: MinecraftPingResponse;
public client?: net.Socket;
constructor(port: number, host: string) {
this.port = port;
this.host = host;
this.status = {
online: false,
host,
port,
version: "",
motd: "",
current_players: 0,
max_players: 0,
latency: 0
};
}
getStatus() {
return new Promise<MinecraftPingResponse>((resolve, reject) => {
var start_time = new Date().getTime();
this.client = net.connect(
{
host: this.host,
port: this.port,
timeout: 1000 * 15
},
() => {
this.status.latency = Math.round(new Date().getTime() - start_time);
// 0xFE packet identifier for a server list ping
// 0x01 server list ping's payload (always 1)
let data = Buffer.from([0xfe, 0x01]);
this?.client?.write(data);
}
);
// The client can also receive data from the server by reading from its socket.
this?.client?.on("data", (response: any) => {
// Check the readme for a simple explanation
var server_info = response.toString().split("\x00\x00");
this.status = {
online: true,
host: this.host,
port: this.port,
version: server_info[2].replace(/\u0000/g, ""),
motd: server_info[3].replace(/\u0000/g, ""),
current_players: server_info[4].replace(/\u0000/g, ""),
max_players: server_info[5].replace(/\u0000/g, ""),
latency: this.status.latency
};
// Request an end to the connection after the data has been received.
this?.client?.end();
resolve(this.status);
this.destroy();
});
this?.client?.on("end", () => {
resolve(this.status);
this.destroy();
});
this?.client?.on("error", (err: any) => {
reject(err);
this.destroy();
});
});
}
private destroy() {
this.client?.removeAllListeners();
}
async asyncStatus() {
let status = await this.getStatus();
return status;
}
}
// async function test() {
// try {
// var status = await new MCServStatus(25565, "localhost").asyncStatus();
// // console.log("status: ", status);
// } catch (error) {
// console.error("错误:", error);
// }
// const memoryUsage = process.memoryUsage();
// console.log(
// "RSS (Resident Set Size):",
// (memoryUsage.rss / 1024 / 1024).toFixed(2),
// "MB",
// "Heap Total:",
// (memoryUsage.heapTotal / 1024 / 1024).toFixed(2),
// "MB",
// "Heap Used:",
// (memoryUsage.heapUsed / 1024 / 1024).toFixed(2),
// "MB",
// "External:",
// (memoryUsage.external / 1024 / 1024).toFixed(2),
// "MB"
// );
// // console.log("Heap Total:", (memoryUsage.heapTotal / 1024 / 1024).toFixed(2), "MB");
// // console.log("External:", (memoryUsage.external / 1024 / 1024).toFixed(2), "MB");
// // console.log("Heap Used:", (memoryUsage.heapUsed / 1024 / 1024).toFixed(2), "MB");
// }
// for (let index = 0; index < 10000; index++) {
// test();
// // @ts-ignore
// // global.gc();
// }

140
common/src/process_tools.ts Executable file
View File

@ -0,0 +1,140 @@
import { ChildProcess, exec, execSync, SpawnOptionsWithoutStdio } from "child_process";
import os from "os";
import child_process from "child_process";
import path from "path";
import EventEmitter from "events";
import iconv from "iconv-lite";
export class StartError extends Error {}
export class ProcessWrapper extends EventEmitter {
public process?: ChildProcess;
public pid?: number;
public errMsg = {
timeoutErr: "task timeout!",
exitErr: "task error!",
startErr: "task start error!"
};
constructor(
public readonly file: string,
public readonly args: string[],
public readonly cwd: string,
public readonly timeout: number = 0,
public readonly code = "utf-8",
public readonly option: SpawnOptionsWithoutStdio = {}
) {
super();
}
public setErrMsg(errMsg: { timeoutErr: string; exitErr: string; startErr: string }) {
this.errMsg = errMsg;
}
public start(): Promise<boolean> {
return new Promise((resolve, reject) => {
let timeTask: NodeJS.Timeout;
const subProcess = child_process.spawn(this.file, this.args, {
stdio: "pipe",
windowsHide: true,
cwd: path.normalize(this.cwd),
...this.option
});
this.process = subProcess;
this.pid = subProcess.pid;
this.emit("start", subProcess.pid);
if (!subProcess || !subProcess.pid) return reject(new Error(this.errMsg.startErr));
subProcess.stdout.on("data", (text) => this.emit("data", iconv.decode(text, this.code)));
subProcess.stderr.on("data", (text) => this.emit("data", iconv.decode(text, this.code)));
subProcess.on("exit", (code) => {
try {
this.emit("exit", code);
this.destroy();
} catch (error: any) {}
if (timeTask) clearTimeout(timeTask);
if (code !== 0) return reject(new Error(this.errMsg.exitErr));
return resolve(true);
});
// timeout, terminate the task
if (this.timeout) {
timeTask = setTimeout(() => {
if (subProcess?.pid && !subProcess.exitCode && subProcess.exitCode !== 0) {
killProcess(subProcess.pid, subProcess);
reject(new Error(this.errMsg.timeoutErr));
} else {
reject(new Error(this.errMsg.exitErr));
}
}, 1000 * this.timeout);
}
});
}
public getPid() {
return this.process?.pid;
}
public write(data?: any) {
return this.process?.stdin?.write(iconv.encode(data, this.code));
}
public kill() {
if (this.process?.pid) killProcess(this.process?.pid, this.process);
}
public status() {
return !!this.process?.exitCode;
}
public exitCode() {
return this.process?.exitCode;
}
private async destroy() {
try {
for (const n of this.eventNames()) this.removeAllListeners(n);
if (this.process?.stdout)
for (const eventName of this.process.stdout.eventNames())
this.process.stdout.removeAllListeners(eventName);
if (this.process?.stderr)
for (const eventName of this.process.stderr.eventNames())
this.process.stderr.removeAllListeners(eventName);
if (this.process)
for (const eventName of this.process.eventNames())
this.process.removeAllListeners(eventName);
this.process?.stdout?.destroy();
this.process?.stderr?.destroy();
if (this.process?.exitCode === null) {
this.process.kill("SIGTERM");
this.process.kill("SIGKILL");
}
} catch (error: any) {
console.log("[ProcessWrapper destroy() Error]", error);
} finally {
this.process = undefined;
}
}
}
export function killProcess(
pid: string | number,
process: { kill(signal?: any): any },
signal?: any
) {
try {
if (os.platform() === "win32") {
execSync(`taskkill /PID ${pid} /T /F`);
return true;
}
if (os.platform() === "linux") {
execSync(`kill -s 9 ${pid}`);
return true;
}
} catch (err) {
return signal ? process.kill(signal) : process.kill("SIGKILL");
}
return signal ? process.kill(signal) : process.kill("SIGKILL");
}

View File

@ -1,5 +1,3 @@
// Copyright (C) 2022 MCSManager <mcsmanager-dev@outlook.com>
interface IMap {
size: number;
forEach: (value: any, key?: any) => void;
@ -54,11 +52,22 @@ export interface IDataSource<T> {
// MYSQL data source
export class MySqlSource<T> implements IDataSource<T> {
selectPage: (condition: any, page: number, pageSize: number) => Page<T>;
select: (condition: any) => any[];
update: (condition: any, data: any) => void;
delete: (condition: any) => void;
insert: (data: any) => void;
constructor(public data: any) {}
selectPage(condition: any, page: number, pageSize: number) {
return {
page,
pageSize,
maxPage: 0,
total: 0,
data: []
};
}
select(condition: any) {
return [];
}
update(condition: any, data: any) {}
delete(condition: any) {}
insert(data: any) {}
}
// local file data source (embedded microdatabase)
@ -101,7 +110,7 @@ export class LocalFileSource<T> implements IDataSource<T> {
}
select(condition: any): any[] {
return null;
return [];
}
update(condition: any, data: any) {}
delete(condition: any) {}

View File

@ -0,0 +1,7 @@
export function removeTrail(origin: string, trail: string) {
if (origin.endsWith(trail)) {
return origin.slice(0, origin.length - trail.length);
} else {
return origin;
}
}

View File

@ -1,5 +1,3 @@
// Copyright (C) 2022 MCSManager <mcsmanager-dev@outlook.com>
import os from "os";
import osUtils from "os-utils";
import fs from "fs";
@ -90,7 +88,7 @@ function setLinuxSystemInfo() {
info.totalmem = memTotal * 1024;
info.memUsage = (info.totalmem - info.freemem) / info.totalmem;
osUtils.cpuUsage((p) => (info.cpuUsage = p));
} catch (error) {
} catch (error: any) {
// If the reading is wrong, the default general reading method is automatically used
otherSystemInfo();
}

View File

@ -1,17 +1,9 @@
// Copyright (C) 2022 MCSManager <mcsmanager-dev@outlook.com>
import path from "path";
import fs from "fs-extra";
interface IClassz {
name: string;
}
class StorageSubsystem {
public static readonly STIRAGE_DATA_PATH = path.normalize(path.join(process.cwd(), "data"));
public static readonly STIRAGE_INDEX_PATH = path.normalize(
path.join(process.cwd(), "data", "index")
);
export default class StorageSubsystem {
public static readonly DATA_PATH = path.normalize(path.join(process.cwd(), "data"));
public static readonly INDEX_PATH = path.normalize(path.join(process.cwd(), "data", "index"));
private checkFileName(name: string) {
const blackList = ["\\", "/", ".."];
@ -21,9 +13,36 @@ class StorageSubsystem {
return true;
}
public writeFile(name: string, data: string) {
const targetPath = path.normalize(path.join(StorageSubsystem.DATA_PATH, name));
fs.writeFileSync(targetPath, data, { encoding: "utf-8" });
}
public readFile(name: string) {
const targetPath = path.normalize(path.join(StorageSubsystem.DATA_PATH, name));
return fs.readFileSync(targetPath, { encoding: "utf-8" });
}
public readDir(dirName: string) {
const targetPath = path.normalize(path.join(StorageSubsystem.DATA_PATH, dirName));
if (!fs.existsSync(targetPath)) return [];
const files = fs.readdirSync(targetPath).map((v) => path.normalize(path.join(dirName, v)));
return files;
}
public deleteFile(name: string) {
const targetPath = path.normalize(path.join(StorageSubsystem.DATA_PATH, name));
fs.removeSync(targetPath);
}
public fileExists(name: string) {
const targetPath = path.normalize(path.join(StorageSubsystem.DATA_PATH, name));
return fs.existsSync(targetPath);
}
// Stored in local file based on class definition and identifier
public store(category: string, uuid: string, object: any) {
const dirPath = path.join(StorageSubsystem.STIRAGE_DATA_PATH, category);
const dirPath = path.join(StorageSubsystem.DATA_PATH, category);
if (!fs.existsSync(dirPath)) fs.mkdirsSync(dirPath);
if (!this.checkFileName(uuid))
throw new Error(`UUID ${uuid} does not conform to specification`);
@ -54,7 +73,7 @@ class StorageSubsystem {
* Instantiate an object based on the class definition and identifier
*/
public load(category: string, classz: any, uuid: string) {
const dirPath = path.join(StorageSubsystem.STIRAGE_DATA_PATH, category);
const dirPath = path.join(StorageSubsystem.DATA_PATH, category);
if (!fs.existsSync(dirPath)) fs.mkdirsSync(dirPath);
if (!this.checkFileName(uuid))
throw new Error(`UUID ${uuid} does not conform to specification`);
@ -74,7 +93,7 @@ class StorageSubsystem {
* Return all identifiers related to this class through the class definition
*/
public list(category: string) {
const dirPath = path.join(StorageSubsystem.STIRAGE_DATA_PATH, category);
const dirPath = path.join(StorageSubsystem.DATA_PATH, category);
if (!fs.existsSync(dirPath)) fs.mkdirsSync(dirPath);
const files = fs.readdirSync(dirPath);
const result = new Array<string>();
@ -88,10 +107,8 @@ class StorageSubsystem {
* Delete an identifier instance of the specified type through the class definition
*/
public delete(category: string, uuid: string) {
const filePath = path.join(StorageSubsystem.STIRAGE_DATA_PATH, category, `${uuid}.json`);
const filePath = path.join(StorageSubsystem.DATA_PATH, category, `${uuid}.json`);
if (!fs.existsSync(filePath)) return;
fs.removeSync(filePath);
}
}
export default new StorageSubsystem();

21
src/app/common/typecheck.ts → common/src/typecheck.ts Normal file → Executable file
View File

@ -1,5 +1,3 @@
// Copyright (C) 2022 MCSManager <mcsmanager-dev@outlook.com>
export function configureEntityParams(self: any, args: any, key: string, typeFn?: Function): any {
const selfDefaultValue = self[key] ?? null;
const v = args[key] != null ? args[key] : selfDefaultValue;
@ -35,15 +33,6 @@ export function configureEntityParams(self: any, args: any, key: string, typeFn?
return;
}
if (typeFn === Array) {
if (v == null) return (self[key] = null);
if (!(v instanceof Array))
throw new Error(
`ConfigureEntityParams Error: Expected type to be Array, but got ${typeof v}`
);
return;
}
if (typeFn) {
self[key] = typeFn(v);
} else {
@ -51,27 +40,27 @@ export function configureEntityParams(self: any, args: any, key: string, typeFn?
}
}
export function toText(v: any) {
export function toText(v: any): string | null {
if (isEmpty(v)) return null;
return String(v);
}
export function toNumber(v: any) {
export function toNumber(v: any): number | null {
if (isEmpty(v)) return null;
if (isNaN(Number(v))) return null;
return Number(v);
}
export function toBoolean(v: any) {
export function toBoolean(v: any): boolean | null {
if (isEmpty(v)) return null;
return Boolean(v);
}
export function isEmpty(v: any) {
export function isEmpty(v: any): boolean {
return v === null || v === undefined;
}
export function supposeValue(v: any, def: any = null) {
export function supposeValue<T>(v: any, def?: T) {
if (isEmpty(v)) return def;
return v;
}

25
common/tsconfig.json Executable file
View File

@ -0,0 +1,25 @@
{
"compilerOptions": {
"skipLibCheck": false,
"strictNullChecks": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"module": "commonjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "ES2018",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"declaration": true,
"baseUrl": ".",
"paths": {
"@languages/*": ["../languages/*"],
"*": ["node_modules/*", "src/types/*"]
}
},
"include": ["src/**/*"]
}

16
daemon/.eslintrc.js Executable file
View File

@ -0,0 +1,16 @@
module.exports = {
env: {
commonjs: true,
es6: true,
node: true
},
extends: "eslint:recommended",
globals: {
Atomics: "readonly",
SharedArrayBuffer: "readonly"
},
parserOptions: {
ecmaVersion: 2018
},
rules: {}
};

1
daemon/.npmrc Normal file
View File

@ -0,0 +1 @@
registry=https://registry.npmjs.org

4
daemon/.prettierrc.json Executable file
View File

@ -0,0 +1,4 @@
{
"printWidth": 100,
"trailingComma": "none"
}

9016
daemon/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

70
daemon/package.json Normal file
View File

@ -0,0 +1,70 @@
{
"name": "mcsmanager-daemon",
"version": "4.6.0",
"description": "Provides remote control capability for MCSManager to manage processes, scheduled tasks, I/O streams, and more",
"scripts": {
"dev": "ts-node --project tsconfig.json src/app.ts",
"build": "webpack --config webpack.config.js"
},
"homepage": "https://mcsmanager.com/",
"author": "https://github.com/unitwk",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/MCSManager/MCSManager"
},
"_moduleAliases": {
"@languages": "../languages"
},
"dependencies": {
"@iarna/toml": "^2.2.5",
"@koa/router": "^10.0.0",
"archiver": "^5.3.1",
"axios": "^1.8.2",
"compressing": "^1.10.0",
"dockerode": "4.0.5",
"formidable": "^3.5.1",
"fs-extra": "^9.0.1",
"i18next": "^21.8.14",
"iconv-lite": "^0.6.2",
"koa": "^2.16.1",
"koa-body-patch": "^6.0.1",
"koa-send": "^5.0.1",
"log4js": "^6.4.0",
"module-alias": "^2.2.3",
"node-schedule": "^2.0.0",
"node-stream-zip": "^1.15.0",
"os-utils": "0.0.14",
"pidusage": "^2.0.21",
"properties": "^1.2.1",
"rcon-srcds": "^2.1.0",
"socket.io": "^4.6.1",
"socket.io-client": "^4.7.5",
"uuid": "^8.3.2",
"yaml": "^1.10.2"
},
"devDependencies": {
"@types/archiver": "^5.3.1",
"@types/dockerode": "^3.2.7",
"@types/formidable": "^3.4.5",
"@types/fs-extra": "^9.0.11",
"@types/koa": "^2.13.4",
"@types/koa__router": "^8.0.7",
"@types/koa-send": "^4.1.3",
"@types/mocha": "^8.2.2",
"@types/node": "^18.11.18",
"@types/node-schedule": "^1.3.2",
"@types/os-utils": "0.0.1",
"@types/pidusage": "^2.0.1",
"@types/ssh2": "^1.11.7",
"@types/uuid": "^8.3.0",
"common": "file:../common",
"eslint": "^7.13.0",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.5",
"webpack": "^5.94.0",
"webpack-cli": "^4.10.0",
"webpack-node-externals": "^3.0.0"
}
}

169
daemon/src/app.ts Executable file
View File

@ -0,0 +1,169 @@
import "module-alias/register";
import http from "http";
import fs from "fs-extra";
import versionAdapter from "./service/version_adapter";
import { checkDependencies } from "./service/dependencies";
import { $t, i18next } from "./i18n";
import { getVersion, initVersionManager } from "./service/version";
import { globalConfiguration } from "./entity/config";
import { Server, Socket } from "socket.io";
import { LOCAL_PRESET_LANG_PATH } from "./const";
import logger from "./service/log";
import { GOLANG_ZIP_PATH, PTY_PATH } from "./const";
import * as router from "./service/router";
import * as koa from "./service/http";
import * as protocol from "./service/protocol";
import InstanceSubsystem from "./service/system_instance";
import "./service/async_task_service";
import "./service/async_task_service/quick_install";
import "./service/system_visual_data";
import { removeTrail } from "common";
initVersionManager();
const VERSION = getVersion();
console.log(`
______ _______________________ ___
___ |/ /_ ____/_ ___/__ |/ /_____ _____________ _______ _____________
__ /|_/ /_ / _____ \\__ /|_/ /_ __ \`/_ __ \\ __ \`/_ __ \`/ _ \\_ ___/
_ / / / / /___ ____/ /_ / / / / /_/ /_ / / / /_/ /_ /_/ // __/ /
/_/ /_/ \\____/ /____/ /_/ /_/ \\__,_/ /_/ /_/\\__,_/ _\\__, / \\___//_/
/____/
________
___ __ \\_____ ____________ ________________
__ / / / __ \`/ _ \\_ __ \`__ \\ __ \\_ __ \\
_ /_/ // /_/ // __/ / / / / / /_/ / / / /
/_____/ \\__,_/ \\___//_/ /_/ /_/\\____//_/ /_/
+ Copyright ${new Date().getFullYear()} MCSManager Dev <https://github.com/MCSManager>
+ Version ${VERSION}
`);
// Initialize the global configuration service
globalConfiguration.load();
const config = globalConfiguration.config;
// Detect whether the configuration file is from an older version and update it if so.
versionAdapter.detectConfig();
checkDependencies();
// Set language
if (fs.existsSync(LOCAL_PRESET_LANG_PATH)) {
i18next.changeLanguage(fs.readFileSync(LOCAL_PRESET_LANG_PATH, "utf-8"));
} else {
const lang = config.language || "en_us";
logger.info(`LANGUAGE: ${lang}`);
i18next.changeLanguage(lang);
}
logger.info($t("TXT_CODE_app.welcome"));
// Initialize HTTP service
const koaApp = koa.initKoa();
// Listen for Koa errors
koaApp.on("error", (error) => {
// Block all Koa framework error
// When Koa is attacked by a short connection flood, it is easy for error messages to swipe the screen, which may indirectly affect the operation of some applications
});
const httpServer = http.createServer(koaApp.callback());
httpServer.on("error", (err) => {
logger.error($t("TXT_CODE_app.httpSetupError"));
logger.error(err);
process.exit(1);
});
httpServer.listen(config.port, config.ip);
// Initialize Websocket service to HTTP service
const io = new Server(httpServer, {
serveClient: false,
pingInterval: 5000,
pingTimeout: 5000,
cookie: false,
path: removeTrail(config.prefix, "/") + "/socket.io",
cors: {
origin: "*",
methods: ["GET", "POST", "PUT", "DELETE"]
},
maxHttpBufferSize: 1e8
});
// Initialize application instance system
try {
InstanceSubsystem.loadInstances();
logger.info($t("TXT_CODE_app.instanceLoad", { n: InstanceSubsystem.getInstances().length }));
} catch (err) {
logger.error($t("TXT_CODE_app.instanceLoadError"), err);
process.exit(-1);
}
(function initCompressModule() {
try {
fs.chmodSync(GOLANG_ZIP_PATH, 0o755);
fs.chmodSync(PTY_PATH, 0o755);
} catch (error: any) {
logger.error(error?.message);
logger.error($t("TXT_CODE_a8b245fa"));
}
})();
// Initialize Websocket server
io.on("connection", (socket: Socket) => {
protocol.addGlobalSocket(socket);
router.navigation(socket);
socket.on("error", (err) => {
logger.error("Connection(): Socket.io Error:", err);
});
socket.on("disconnect", () => {
protocol.delGlobalSocket(socket);
for (const name of socket.eventNames()) socket.removeAllListeners(name);
});
});
process.on("uncaughtException", function (err) {
logger.error(`Error: UncaughtException:`, err);
});
process.on("unhandledRejection", (reason, p) => {
logger.error(`Error: UnhandledRejection:`, reason, p);
});
logger.info("----------------------------");
logger.info($t("TXT_CODE_app.started"));
logger.info($t("TXT_CODE_app.doc"));
logger.info($t("TXT_CODE_app.addr", { port: config.port }));
logger.info($t("TXT_CODE_app.configPathTip", { path: "" }));
logger.info($t("TXT_CODE_app.password", { key: config.key }));
logger.info($t("TXT_CODE_app.passwordTip"));
logger.info($t("TXT_CODE_app.exitTip"));
logger.info("----------------------------");
console.log("");
async function processExit() {
try {
console.log("");
logger.warn("Program received EXIT command.");
await InstanceSubsystem.exit();
logger.info("Exit.");
} catch (err) {
logger.error("ERROR:", err);
} finally {
process.exit(0);
}
}
["SIGTERM", "SIGINT", "SIGQUIT"].forEach(function (sig) {
process.on(sig, () => {
logger.warn(`${sig} close process signal detected.`);
processExit();
});
});
process.stdin.on("data", (v) => {
const command = v.toString().replace("\n", "").replace("\r", "").trim().toLowerCase();
if (command === "exit") processExit();
});

85
daemon/src/common/compress.ts Executable file
View File

@ -0,0 +1,85 @@
import path from "path";
import { t } from "i18next";
import logger from "../service/log";
import { ProcessWrapper } from "common";
import fs from "fs-extra";
import { GOLANG_ZIP_PATH } from "../const";
import { ZIP_TIMEOUT_SECONDS } from "../const";
const COMPRESS_ERROR_MSG = {
invalidName: t("TXT_CODE_3aa9f36"),
exitErr: t("TXT_CODE_2be83d36"),
startErr: t("TXT_CODE_37d839a4"),
timeoutErr: t("TXT_CODE_15c07350")
};
function checkFileName(fileName: string) {
const disableList = ['"', "'", "?", "|", "&"];
for (const iterator of disableList) {
if (fileName.includes(iterator)) return false;
}
return true;
}
export async function compress(
sourceZip: string,
files: string[],
fileCode?: string
): Promise<boolean> {
if (!checkFileName(sourceZip) || files.some((v) => !checkFileName(v)))
throw new Error(COMPRESS_ERROR_MSG.invalidName);
return await useZip(sourceZip, files, fileCode);
}
export async function decompress(
zipPath: string,
dest: string,
fileCode?: string
): Promise<boolean> {
if (!checkFileName(zipPath) || !checkFileName(dest))
throw new Error(COMPRESS_ERROR_MSG.invalidName);
return await useUnzip(zipPath, dest, fileCode || "utf-8");
}
// ./file-zip -mode 2 --zipPath aaa.zip --DistDirPath 123412124 --code GBK
async function useUnzip(sourceZip: string, destDir: string, code = "utf-8"): Promise<boolean> {
const params = [
"--mode=2",
`--zipPath=${path.basename(sourceZip)}`,
`--distDirPath=${path.normalize(destDir)}`,
`--code=${code}`
];
logger.info(`Function useUnzip(): Command: ${GOLANG_ZIP_PATH} ${params.join(" ")}`);
const subProcess = new ProcessWrapper(
GOLANG_ZIP_PATH,
params,
path.dirname(sourceZip),
ZIP_TIMEOUT_SECONDS,
code
);
subProcess.setErrMsg(COMPRESS_ERROR_MSG);
return subProcess.start();
}
// ./file-zip -mode 1 --file main.go --file file-zip --file 123 --file README.md --zipPath aaabb.zip
async function useZip(distZip: string, files: string[], code = "utf-8"): Promise<boolean> {
if (!files || files.length == 0) throw new Error(t("TXT_CODE_2038ec2c"));
const params = ["--mode=1", `--code=${code}`, `--zipPath=${path.basename(distZip)}`];
files.forEach((v) => {
params.push(`--file=${path.basename(v)}`);
});
logger.info(
`Function useZip(): Command: ${GOLANG_ZIP_PATH} ${params.join(" ")}, CWD: ${path.dirname(
distZip
)}`
);
const subProcess = new ProcessWrapper(
GOLANG_ZIP_PATH,
params,
path.dirname(distZip),
ZIP_TIMEOUT_SECONDS,
code
);
subProcess.setErrMsg(COMPRESS_ERROR_MSG);
return subProcess.start();
}

View File

@ -0,0 +1,2 @@
import { StorageSubsystem } from "common";
export default new StorageSubsystem();

27
daemon/src/const.ts Executable file
View File

@ -0,0 +1,27 @@
import os from "os";
import path from "path";
const SYS_INFO = `${os.platform()}_${os.arch()}${os.platform() === "win32" ? ".exe" : ""}`;
const ptyName = `pty_${SYS_INFO}`;
const frpcName = `frpc_${SYS_INFO}`;
const PTY_PATH = path.normalize(path.join(process.cwd(), "lib", ptyName));
const FRPC_PATH = path.normalize(path.join(process.cwd(), "lib", frpcName));
const FILENAME_BLACKLIST = ["\\", "/", ".", "'", '"', "?", "*", "<", ">"];
const LOCAL_PRESET_LANG_PATH = path.normalize(path.join(process.cwd(), "language"));
const IGNORE = "[IGNORE_LOG]";
const SYSTEM_TYPE = os.platform();
const ZIP_TIMEOUT_SECONDS = 60 * 40;
const GOLANG_ZIP_NAME = `file_zip_${SYSTEM_TYPE}_${os.arch()}${
SYSTEM_TYPE === "win32" ? ".exe" : ""
}`;
const GOLANG_ZIP_PATH = path.normalize(path.join(process.cwd(), "lib", GOLANG_ZIP_NAME));
export {
GOLANG_ZIP_PATH,
FILENAME_BLACKLIST,
PTY_PATH,
LOCAL_PRESET_LANG_PATH,
FRPC_PATH,
IGNORE,
ZIP_TIMEOUT_SECONDS
};

View File

@ -0,0 +1,5 @@
export default class InstanceCommand {
constructor(public info?: string) {}
async exec(instance: any): Promise<any> {}
async stop(instance: any) {}
}

View File

@ -0,0 +1,61 @@
import { $t } from "../../../i18n";
export function commandStringToArray(cmd: string) {
const QUOTES_KEY = "{quotes}";
let start = 0;
let len = cmd.length;
const cmdArray: string[] = [];
function _analyze() {
for (let index = start; index < len; index++) {
const ch = cmd[index];
if (ch === " ") {
findSpace(index);
start++;
continue;
}
if (ch === '"') {
index = findQuotes(index);
}
if (index + 1 >= len) {
findEnd();
break;
}
}
}
function findEnd() {
return cmdArray.push(cmd.slice(start));
}
function findSpace(endPoint: number) {
if (endPoint != start) {
const elem = cmd.slice(start, endPoint);
start = endPoint;
return cmdArray.push(elem);
}
}
function findQuotes(p: number) {
for (let index = p + 1; index < len; index++) {
const ch = cmd[index];
if (ch === '"') return index;
}
throw new Error($t("TXT_CODE_command.quotes"));
}
_analyze();
if (cmdArray.length == 0) {
return [];
}
for (const index in cmdArray) {
const element = cmdArray[index];
if (element[0] === '"' && element[element.length - 1] === '"')
cmdArray[index] = element.slice(1, element.length - 1);
while (cmdArray[index].indexOf(QUOTES_KEY) != -1)
cmdArray[index] = cmdArray[index].replace(QUOTES_KEY, '"');
}
return cmdArray;
}

View File

@ -0,0 +1,82 @@
import Instance from "../instance/instance";
import InstanceCommand from "./base/command";
import NullCommand from "./nullfunc";
import GeneralStartCommand from "./general/general_start";
import GeneralStopCommand from "./general/general_stop";
import GeneralKillCommand from "./general/general_kill";
import GeneralSendCommand from "./general/general_command";
import GeneralRestartCommand from "./general/general_restart";
import DockerStartCommand from "./docker/docker_start";
import TimeCheck from "./task/time";
import GeneralUpdateCommand from "./general/general_update";
import PtyStartCommand from "./pty/pty_start";
import RconCommand from "./steam/rcon_command";
import DockerResizeCommand from "./docker/docker_pty_resize";
import PtyResizeCommand from "./pty/pty_resize";
import GeneralInstallCommand from "./general/general_install";
import PingJavaMinecraftServerCommand from "./minecraft/mc_ping";
import PingMinecraftServerTask from "./task/mc_players";
// If you add a new "Preset", Please add the definition here.
export type IPresetCommand =
| "start"
| "stop"
| "restart"
| "kill"
| "update"
| "refreshPlayers"
| "command"
| "resize"
| "install";
// Instance function dispatcher
// Dispatch and assign different functions according to different types
export default class FunctionDispatcher extends InstanceCommand {
constructor() {
super("FunctionDispatcher");
}
async exec(instance: Instance) {
// initialize all modules
instance.lifeCycleTaskManager.clearLifeCycleTask();
instance.clearPreset();
// the component that the instance must mount
instance.lifeCycleTaskManager.registerLifeCycleTask(new TimeCheck());
// instance.lifeCycleTaskManager.registerLifeCycleTask(new OpenFrpTask());
// Instance general preset capabilities
instance.setPreset("command", new GeneralSendCommand());
instance.setPreset("stop", new GeneralStopCommand());
instance.setPreset("kill", new GeneralKillCommand());
instance.setPreset("restart", new GeneralRestartCommand());
instance.setPreset("update", new GeneralUpdateCommand());
instance.setPreset("refreshPlayers", new NullCommand());
instance.setPreset("install", new GeneralInstallCommand());
// Preset the basic operation mode according to the instance startup type
if (!instance.config.processType || instance.config.processType === "general") {
instance.setPreset("start", new GeneralStartCommand());
}
// Enable emulated terminal mode
if (instance.config.terminalOption.pty && instance.config.processType === "general") {
instance.setPreset("start", new PtyStartCommand());
instance.setPreset("resize", new PtyResizeCommand());
}
// Whether to enable Docker PTY mode
if (instance.config.processType === "docker") {
instance.setPreset("start", new DockerStartCommand());
instance.setPreset("resize", new DockerResizeCommand());
}
if (instance.config.enableRcon) {
instance.setPreset("command", new RconCommand());
}
// Minecraft Ping
if (instance.config.type.includes(Instance.TYPE_MINECRAFT_JAVA)) {
instance.setPreset("refreshPlayers", new PingJavaMinecraftServerCommand());
instance.lifeCycleTaskManager.registerLifeCycleTask(new PingMinecraftServerTask());
}
}
}

View File

@ -0,0 +1,20 @@
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
import { DockerProcessAdapter } from "../../../service/docker_process_service";
export default class DockerResizeCommand extends InstanceCommand {
constructor() {
super("ResizeTTY");
}
async exec(instance: Instance): Promise<any> {
const dockerProcess = instance?.process as Partial<DockerProcessAdapter>;
if (typeof dockerProcess?.container?.resize === "function") {
const { w, h } = instance.computeTerminalSize();
await dockerProcess?.container?.resize({
h,
w
});
}
}
}

View File

@ -0,0 +1,79 @@
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
import { t } from "i18next";
import { DefaultDocker } from "../../../service/docker_service";
export async function checkImage(name: string) {
const docker = new DefaultDocker();
try {
const image = docker.getImage(name);
const info = await image.inspect();
return info.Size > 0 ? true : false;
} catch (error: any) {
return false;
}
}
export default class DockerPullCommand extends InstanceCommand {
constructor() {
super("DockerPullCommand");
}
private stopFlag = false;
private stopped(instance: Instance) {
this.stopFlag = true;
instance.asynchronousTask = undefined;
}
private awaitImageDone(instance: Instance, name: string) {
return new Promise((resolve, reject) => {
let count = 0;
const task = setInterval(async () => {
count++;
instance.println("CONTAINER", t("TXT_CODE_977cb449"));
if (await checkImage(name)) {
clearInterval(task);
resolve(true);
}
if (count >= 20 * 15) {
clearInterval(task);
reject(new Error(t("TXT_CODE_9cae6f92")));
}
if (this.stopFlag) {
clearInterval(task);
reject(new Error(t("TXT_CODE_361a79c6")));
}
}, 3 * 1000);
});
}
async exec(instance: Instance) {
const imageName = instance.config.docker.image;
if (!imageName) throw new Error(t("TXT_CODE_17be5f70"));
const cachedStartCount = instance.startCount;
// If the image exists, there is no need to pull again.
if (await checkImage(imageName)) return;
try {
const docker = new DefaultDocker();
instance.println("CONTAINER", t("TXT_CODE_2fa46b8c") + imageName);
instance.asynchronousTask = this;
await docker.pull(imageName, {});
await this.awaitImageDone(instance, imageName);
if (cachedStartCount !== instance.startCount) return;
instance.println("CONTAINER", t("TXT_CODE_c68b0bef"));
} catch (err: any) {
if (cachedStartCount !== instance.startCount) return;
throw new Error([t("TXT_CODE_db37b7f9"), err?.message].join("\n"));
} finally {
this.stopped(instance);
}
}
async stop(instance: Instance): Promise<void> {
this.stopped(instance);
}
}

View File

@ -0,0 +1,42 @@
import { $t } from "../../../i18n";
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
import logger from "../../../service/log";
import fs from "fs-extra";
import DockerPullCommand from "./docker_pull";
import {
DockerProcessAdapter,
SetupDockerContainer,
StartupDockerProcessError
} from "../../../service/docker_process_service";
import AbsStartCommand from "../start";
export default class DockerStartCommand extends AbsStartCommand {
protected async createProcess(instance: Instance) {
if (!instance.hasCwdPath() || !instance.config.ie || !instance.config.oe)
throw new StartupDockerProcessError($t("TXT_CODE_a6424dcc"));
if (!fs.existsSync(instance.absoluteCwdPath())) fs.mkdirpSync(instance.absoluteCwdPath());
// Docker Image check
try {
await instance.forceExec(new DockerPullCommand());
} catch (error: any) {
throw error;
}
// Docker docks to the process adapter
const processAdapter = new DockerProcessAdapter(new SetupDockerContainer(instance));
await processAdapter.start({
isTty: instance.config.terminalOption.pty,
w: instance.config.terminalOption.ptyWindowCol,
h: instance.config.terminalOption.ptyWindowCol
});
instance.started(processAdapter);
logger.info(
$t("TXT_CODE_instance.successful", {
v: `${instance.config.nickname} ${instance.instanceUuid}`
})
);
}
}

View File

@ -0,0 +1,38 @@
import { $t } from "../../../i18n";
import Instance from "../../instance/instance";
import { encode } from "iconv-lite";
import InstanceCommand from "../base/command";
export const CTRL_C = "\x03";
export function isExitCommand(instance: Instance, buf: any) {
if (String(buf).toLowerCase() === "^c") {
instance.process?.kill("SIGINT");
return true;
}
if (buf == CTRL_C) {
instance.process?.write(CTRL_C);
return true;
}
return false;
}
export default class GeneralSendCommand extends InstanceCommand {
constructor() {
super("SendCommand");
}
async exec(instance: Instance, buf?: any): Promise<any> {
if (isExitCommand(instance, buf)) return;
// The server shutdown command needs to send a command, but before the server shutdown command is executed, the status will be set to the shutdown state.
// So here the command can only be executed by whether the process exists or not
if (instance?.process) {
instance.process.write(encode(buf, instance.config.ie));
if (instance.config.crlf === 2) return instance.process.write("\r\n");
return instance.process.write("\n");
} else {
instance.failure(new Error($t("TXT_CODE_command.instanceNotOpen")));
}
}
}

View File

@ -0,0 +1,66 @@
import { $t } from "../../../i18n";
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
import fs from "fs-extra";
import { QuickInstallTask } from "../../../service/async_task_service/quick_install";
import { IQuickStartPackages } from "common/global";
export default class GeneralInstallCommand extends InstanceCommand {
private process?: QuickInstallTask;
constructor() {
super("GeneralInstallCommand");
}
private stopped(instance: Instance) {
instance.asynchronousTask = undefined;
instance.setLock(false);
instance.status(Instance.STATUS_STOP);
}
async exec(instance: Instance, params?: IQuickStartPackages) {
if (instance.status() !== Instance.STATUS_STOP)
return instance.failure(new Error($t("TXT_CODE_general_update.statusErr_notStop")));
if (instance.asynchronousTask)
return instance.failure(new Error($t("TXT_CODE_general_update.statusErr_otherProgress")));
if (!params) throw new Error("GeneralInstallCommand: No params");
try {
instance.setLock(true);
instance.status(Instance.STATUS_BUSY);
instance.println($t("TXT_CODE_1704ea49"), $t("TXT_CODE_cbc235ad"));
if (instance.hasCwdPath()) {
await fs.remove(instance.absoluteCwdPath());
await fs.mkdirs(instance.absoluteCwdPath());
}
instance.println($t("TXT_CODE_1704ea49"), $t("TXT_CODE_906c5d6a"));
this.process = new QuickInstallTask(
instance.config.nickname,
params.targetLink,
params.setupInfo,
instance
);
instance.asynchronousTask = this;
instance.println($t("TXT_CODE_1704ea49"), $t("TXT_CODE_b9ca022b"));
await this.process.start();
await this.process.wait();
instance.println($t("TXT_CODE_1704ea49"), $t("TXT_CODE_f220ed78"));
} catch (err: any) {
instance.println(
$t("TXT_CODE_general_update.update"),
$t("TXT_CODE_general_update.error", { err })
);
} finally {
this.stopped(instance);
}
}
async stop(instance: Instance): Promise<void> {
instance.println(
$t("TXT_CODE_general_update.update"),
$t("TXT_CODE_general_update.killProcess")
);
this.stopped(instance);
await this.process?.stop();
}
}

View File

@ -0,0 +1,34 @@
import { $t } from "../../../i18n";
import logger from "../../../service/log";
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
export default class GeneralKillCommand extends InstanceCommand {
constructor() {
super("KillCommand");
}
async exec(instance: Instance) {
if (instance.status() === Instance.STATUS_STOP) return;
if (instance.startTimestamp && instance.startTimestamp + 6 * 1000 > Date.now()) {
return instance.failure(new Error($t("TXT_CODE_6259357c")));
}
instance.ignoreEventTaskOnce();
const task = instance?.asynchronousTask;
if (task && task.stop) {
task
.stop(instance)
.then(() => {})
.catch((err) => {
logger.error(`Instance ${instance.config.nickname} asynchronousTask stop error:`, err);
});
}
if (instance.process) {
await instance.process.kill("SIGKILL");
}
}
}

View File

@ -0,0 +1,47 @@
import { $t } from "../../../i18n";
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
export default class GeneralRestartCommand extends InstanceCommand {
constructor() {
super("GeneralRestartCommand");
}
async exec(instance: Instance) {
try {
instance.ignoreEventTaskOnce();
instance.println("INFO", $t("TXT_CODE_restart.start"));
instance.setLock(true);
await instance.execPreset("stop");
const startCount = instance.startCount;
// Check the instance status every second,
// if the instance status is stopped, restart the server immediately
const task = setInterval(async () => {
try {
if (startCount !== instance.startCount) {
throw new Error($t("TXT_CODE_restart.error1"));
}
if (
instance.status() !== Instance.STATUS_STOPPING &&
instance.status() !== Instance.STATUS_STOP
) {
throw new Error($t("TXT_CODE_restart.error2"));
}
if (instance.status() === Instance.STATUS_STOP) {
instance.println("INFO", $t("TXT_CODE_restart.restarting"));
instance.setLock(false);
clearInterval(task);
await instance.execPreset("start");
}
} catch (error: any) {
clearInterval(task);
instance.setLock(false);
instance.failure(error);
}
}, 1000);
} catch (error: any) {
instance.setLock(false);
instance.failure(error);
}
}
}

View File

@ -0,0 +1,120 @@
import { $t } from "../../../i18n";
import Instance from "../../instance/instance";
import logger from "../../../service/log";
import fs from "fs-extra";
import EventEmitter from "events";
import { IInstanceProcess } from "../../instance/interface";
import { ChildProcess, spawn } from "child_process";
import { commandStringToArray } from "../base/command_parser";
import { killProcess } from "common";
import AbsStartCommand from "../start";
// Error exception at startup
class StartupError extends Error {
constructor(msg: string) {
super(msg);
}
}
// Docker process adapter
class ProcessAdapter extends EventEmitter implements IInstanceProcess {
pid?: number | string;
constructor(private process: ChildProcess) {
super();
this.pid = this.process.pid;
process.stdout?.on("data", (text) => this.emit("data", text));
process.stderr?.on("data", (text) => this.emit("data", text));
process.on("exit", (code) => this.emit("exit", code));
}
public write(data?: string) {
return this.process.stdin?.write(data);
}
public kill(s?: any) {
if (this.pid) return killProcess(this.pid, this.process, s);
}
public async destroy() {
// remove all dynamically added event listeners
for (const n of this.eventNames()) this.removeAllListeners(n);
if (this.process.stdout)
for (const eventName of this.process.stdout.eventNames())
this.process.stdout.removeAllListeners(eventName);
if (this.process.stderr)
for (const eventName of this.process.stderr.eventNames())
this.process.stderr.removeAllListeners(eventName);
if (this.process)
for (const eventName of this.process.eventNames()) this.process.removeAllListeners(eventName);
this.process?.stdout?.destroy();
this.process?.stderr?.destroy();
if (this.process?.exitCode === null) {
this.process.kill("SIGTERM");
this.process.kill("SIGKILL");
}
}
}
export default class GeneralStartCommand extends AbsStartCommand {
async createProcess(instance: Instance, source = "") {
if (
(!instance.config.startCommand && instance.config.processType === "general") ||
!instance.hasCwdPath() ||
!instance.config.ie ||
!instance.config.oe
)
throw new StartupError($t("TXT_CODE_general_start.instanceConfigErr"));
if (!fs.existsSync(instance.absoluteCwdPath())) fs.mkdirpSync(instance.absoluteCwdPath());
// command parsing
const commandList = commandStringToArray(instance.config.startCommand);
const commandExeFile = commandList[0];
const commandParameters = commandList.slice(1);
if (commandList.length === 0) {
throw new StartupError($t("TXT_CODE_general_start.cmdEmpty"));
}
logger.info("----------------");
logger.info($t("TXT_CODE_general_start.startInstance", { source: source }));
logger.info($t("TXT_CODE_general_start.instanceUuid", { uuid: instance.instanceUuid }));
logger.info($t("TXT_CODE_general_start.startCmd", { cmdList: JSON.stringify(commandList) }));
logger.info($t("TXT_CODE_general_start.cwd", { cwd: instance.absoluteCwdPath() }));
logger.info("----------------");
// create child process
// Parameter 1 directly passes the process name or path (including spaces) without double quotes
const subProcess = spawn(commandExeFile, commandParameters, {
cwd: instance.absoluteCwdPath(),
stdio: "pipe",
windowsHide: true,
env: process.env
});
// child process creation result check
if (!subProcess || !subProcess.pid) {
instance.println(
"ERROR",
$t("TXT_CODE_general_start.pidErr", {
startCommand: instance.config.startCommand,
commandExeFile: commandExeFile,
commandParameters: JSON.stringify(commandParameters)
})
);
throw new StartupError($t("TXT_CODE_general_start.startErr"));
}
// create process adapter
const processAdapter = new ProcessAdapter(subProcess);
// generate open event
instance.started(processAdapter);
logger.info(
$t("TXT_CODE_general_start.startSuccess", {
instanceUuid: instance.instanceUuid,
pid: subProcess.pid
})
);
instance.println("INFO", $t("TXT_CODE_general_start.startOrdinaryTerminal"));
}
}

View File

@ -0,0 +1,41 @@
import { $t } from "../../../i18n";
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
export default class GeneralStopCommand extends InstanceCommand {
constructor() {
super("StopCommand");
}
async exec(instance: Instance) {
const stopCommand = instance.config.stopCommand;
if (instance.status() === Instance.STATUS_STOP || !instance.process)
return instance.failure(new Error($t("TXT_CODE_general_stop.notRunning")));
instance.status(Instance.STATUS_STOPPING);
instance.ignoreEventTaskOnce();
const stopCommandList = stopCommand.split("\n");
for (const stopCommand of stopCommandList) {
await instance.execPreset("command", stopCommand);
}
instance.print("\n");
instance.println("INFO", $t("TXT_CODE_pty_stop.execCmd", { stopCommand: `\n${stopCommand}` }));
const cacheStartCount = instance.startCount;
// If the instance is still in the stopped state after 10 minutes, restore the state
setTimeout(() => {
if (
instance.status() === Instance.STATUS_STOPPING &&
instance.startCount === cacheStartCount
) {
instance.println("ERROR", $t("TXT_CODE_general_stop.stopErr"));
instance.status(Instance.STATUS_RUNNING);
}
}, 1000 * 60 * 10);
return instance;
}
}

View File

@ -0,0 +1,60 @@
import { $t } from "../../../i18n";
import logger from "../../../service/log";
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
import { InstanceUpdateAction } from "../../../service/instance_update_action";
export default class GeneralUpdateCommand extends InstanceCommand {
private updateTask?: InstanceUpdateAction;
constructor() {
super("GeneralUpdateCommand");
}
private stopped(instance: Instance) {
instance.asynchronousTask = undefined;
instance.setLock(false);
instance.status(Instance.STATUS_STOP);
}
async exec(instance: Instance) {
if (instance.status() !== Instance.STATUS_STOP && instance.status() !== Instance.STATUS_BUSY)
return instance.failure(new Error($t("TXT_CODE_general_update.statusErr_notStop")));
if (instance.asynchronousTask)
return instance.failure(new Error($t("TXT_CODE_general_update.statusErr_otherProgress")));
try {
instance.setLock(true);
instance.asynchronousTask = this;
instance.status(Instance.STATUS_BUSY);
this.updateTask = new InstanceUpdateAction(instance);
await this.updateTask.start();
await this.updateTask.wait();
} catch (err: any) {
instance.println(
$t("TXT_CODE_general_update.update"),
$t("TXT_CODE_general_update.error", { err: err })
);
} finally {
this.stopped(instance);
}
}
async stop(instance: Instance): Promise<void> {
instance.asynchronousTask = undefined;
logger.info(
$t("TXT_CODE_general_update.terminateUpdate", { instanceUuid: instance.instanceUuid })
);
instance.println(
$t("TXT_CODE_general_update.update"),
$t("TXT_CODE_general_update.terminateUpdate", { instanceUuid: instance.instanceUuid })
);
instance.println(
$t("TXT_CODE_general_update.update"),
$t("TXT_CODE_general_update.killProcess")
);
await this.updateTask?.stop();
}
}

View File

@ -0,0 +1,32 @@
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
import { MCServerStatus, toNumber } from "common";
export default class PingJavaMinecraftServerCommand extends InstanceCommand {
constructor() {
super("PingJavaMinecraftServerCommand");
}
async exec(instance: Instance) {
const host = instance.config.pingConfig.ip || "localhost";
try {
if (instance.config.pingConfig.port) {
const result = await new MCServerStatus(instance.config.pingConfig.port, host).getStatus();
if (result.online) {
instance.info.mcPingOnline = true;
instance.info.currentPlayers = toNumber(result.current_players) ?? 0;
instance.info.maxPlayers = toNumber(result.max_players) ?? 0;
instance.info.version = result.version;
instance.info.latency = toNumber(result.latency) ?? 0;
} else {
instance.resetPingInfo();
}
return result;
}
} catch (error) {
instance.resetPingInfo();
// ignore error
}
return null;
}
}

View File

@ -0,0 +1,77 @@
import dgram from "dgram";
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
// Get Minecraft Bedrock server MOTD information
// Author: https://github.com/Mcayear
async function request(ip: string, port: number) {
const message = Buffer.from(
"01 00 00 00 00 00 06 18 20 00 FF FF 00 FE FE FE FE FD FD FD FD 12 34 56 78 A3 61 1C F8 BA 8F D5 60".replace(
/ /g,
""
),
"hex"
);
const client = dgram.createSocket("udp4");
var Config = {
ip,
port
};
return new Promise((r, j) => {
client.on("error", (err: any) => {
try {
client.close();
} finally {
j(err);
}
});
client.on("message", (data: any) => {
const result = data.toString().split(";");
try {
client.close();
} finally {
r(result);
}
});
client.send(message, Config.port, Config.ip, (err: any) => {
if (err) {
try {
client.close();
} finally {
j(err);
}
}
});
setTimeout(() => {
j("request timeout");
try {
client.close();
} catch (error: any) {}
}, 3000);
});
}
// Adapt to MCSManager lifecycle tasks
export default class MinecraftBedrockGetPlayersCommand extends InstanceCommand {
constructor() {
super("MinecraftBedrockGetPlayersCommand");
}
async exec(instance: Instance) {
if (instance.config.pingConfig.ip && instance.config.pingConfig.port) {
try {
const info: any = await request(
instance.config.pingConfig.ip,
instance.config.pingConfig.port
);
return {
version: info[3],
motd: info[0],
current_players: info[4],
max_players: info[5]
};
} catch (error: any) {}
}
return null;
}
}

View File

@ -0,0 +1,10 @@
import InstanceCommand from "./base/command";
export default class NullCommand extends InstanceCommand {
constructor() {
super("NullCommand");
}
async exec() {
// Do nothing.....
}
}

View File

@ -0,0 +1,25 @@
import { ProcessConfig } from "../instance/process_config";
import pidusage from "pidusage";
import InstanceCommand from "./base/command";
import Instance from "../instance/instance";
export default class ProcessInfoCommand extends InstanceCommand {
constructor() {
super("ProcessInfo");
}
async exec(instance: Instance): Promise<Object> {
let info: any = {
cpu: 0, // percentage (from 0 to 100*vcore)
memory: 0, // bytes
ppid: 0, // PPID
pid: 0, // PID
ctime: 0, // ms user + system time
elapsed: 0, // ms since the start of the process
timestamp: 0 // ms since epoch
};
if (instance.process && instance.process.pid) {
info = await pidusage(instance.process.pid);
}
return info;
}
}

View File

@ -0,0 +1,17 @@
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
import { GoPtyProcessAdapter } from "./pty_start";
export default class PtyResizeCommand extends InstanceCommand {
constructor() {
super("ResizeTTY");
}
async exec(instance: Instance): Promise<any> {
const pty = instance.process as Partial<GoPtyProcessAdapter>;
if (typeof pty?.resize === "function") {
const { w, h } = instance.computeTerminalSize();
pty?.resize(w, h);
}
}
}

View File

@ -0,0 +1,273 @@
import { $t } from "../../../i18n";
import os from "os";
import Instance from "../../instance/instance";
import logger from "../../../service/log";
import fs from "fs-extra";
import path from "path";
import readline from "readline";
import EventEmitter from "events";
import { IInstanceProcess } from "../../instance/interface";
import { ChildProcess, ChildProcessWithoutNullStreams, exec, spawn } from "child_process";
import { commandStringToArray } from "../base/command_parser";
import { killProcess } from "common";
import FunctionDispatcher from "../dispatcher";
import { PTY_PATH } from "../../../const";
import { Writable } from "stream";
import { v4 } from "uuid";
import AbsStartCommand from "../start";
interface IPtySubProcessCfg {
pid: number;
}
// Error exception at startup
class StartupError extends Error {
constructor(msg: string) {
super(msg);
}
}
const GO_PTY_MSG_TYPE = {
RESIZE: 0x04
};
// process adapter
export class GoPtyProcessAdapter extends EventEmitter implements IInstanceProcess {
private pipeClient?: Writable;
constructor(
private readonly process: ChildProcess,
public readonly pid: number,
public readonly pipeName: string
) {
super();
process.stdout?.on("data", (text) => this.emit("data", text));
process.stderr?.on("data", (text) => this.emit("data", text));
process.on("exit", (code) => this.emit("exit", code));
this.initNamedPipe();
}
private async initNamedPipe() {
try {
const fd = await fs.open(this.pipeName, "w");
const writePipe = fs.createWriteStream("", { fd });
writePipe.on("close", () => {});
writePipe.on("end", () => {});
writePipe.on("error", (err) => {
logger.error("Pipe error:", this.pipeName, err);
});
this.pipeClient = writePipe;
} catch (error) {
throw new Error(
$t("TXT_CODE_9d1d244f", {
pipeName: error
})
);
}
}
public resize(w: number, h: number) {
const MAX_W = 900;
if (w > MAX_W) w = MAX_W;
if (h > MAX_W) h = MAX_W;
const resizeStruct = JSON.stringify({ width: Number(w), height: Number(h) });
const len = resizeStruct.length;
const lenBuff = Buffer.alloc(2);
lenBuff.writeInt16BE(len, 0);
const buf = Buffer.from([GO_PTY_MSG_TYPE.RESIZE, ...lenBuff, ...Buffer.from(resizeStruct)]);
this.writeToNamedPipe(buf);
}
public writeToNamedPipe(data: Buffer) {
this.pipeClient?.write(data);
}
public write(data?: string) {
return this.process.stdin?.write(data);
}
public kill(s?: any) {
return killProcess(this.pid, this.process, s);
}
public async destroy() {
for (const n of this.eventNames()) this.removeAllListeners(n);
if (this.process.stdout)
for (const eventName of this.process.stdout.eventNames())
this.process.stdout.removeAllListeners(eventName);
if (this.process.stderr)
for (const eventName of this.process.stderr.eventNames())
this.process.stderr.removeAllListeners(eventName);
if (this.process)
for (const eventName of this.process.eventNames())
this.process.stdout?.removeAllListeners(eventName);
if (this.pipeClient)
for (const eventName of this.pipeClient.eventNames())
this.pipeClient.removeAllListeners(eventName);
this.pipeClient?.destroy();
this.process?.stdout?.destroy();
this.process?.stderr?.destroy();
if (this.process?.exitCode === null) {
this.process.kill("SIGTERM");
this.process.kill("SIGKILL");
}
fs.remove(this.pipeName, (err) => {});
}
}
export default class PtyStartCommand extends AbsStartCommand {
readPtySubProcessConfig(subProcess: ChildProcessWithoutNullStreams): Promise<IPtySubProcessCfg> {
return new Promise((r, j) => {
const errConfig = {
pid: 0
};
const rl = readline.createInterface({
input: subProcess.stdout,
crlfDelay: Infinity
});
rl.on("line", (line = "") => {
try {
rl.removeAllListeners();
const cfg = JSON.parse(line) as IPtySubProcessCfg;
if (cfg.pid == null) throw new Error("Error");
r(cfg);
} catch (error: any) {
r(errConfig);
}
});
setTimeout(() => {
r(errConfig);
}, 1000 * 3);
});
}
async createProcess(instance: Instance) {
if (
!instance.config.startCommand ||
!instance.hasCwdPath() ||
!instance.config.ie ||
!instance.config.oe
)
throw new StartupError($t("TXT_CODE_pty_start.cmdErr"));
if (!fs.existsSync(instance.absoluteCwdPath())) fs.mkdirpSync(instance.absoluteCwdPath());
if (!path.isAbsolute(path.normalize(instance.absoluteCwdPath())))
throw new StartupError($t("TXT_CODE_pty_start.mustAbsolutePath"));
// PTY mode correctness check
logger.info($t("TXT_CODE_pty_start.startPty", { source: "" }));
let checkPtyEnv = true;
if (!fs.existsSync(PTY_PATH)) {
instance.println("ERROR", $t("TXT_CODE_pty_start.startErr"));
checkPtyEnv = false;
}
if (checkPtyEnv === false) {
// Close the PTY type, reconfigure the instance function group, and restart the instance
instance.config.terminalOption.pty = false;
await instance.forceExec(new FunctionDispatcher());
await instance.execPreset("start"); // execute the preset command directly
return;
}
// Set the startup state & increase the number of startups
instance.status(Instance.STATUS_STARTING);
instance.startCount++;
// command parsing
let commandList: string[] = [];
if (os.platform() === "win32") {
// windows: cmd.exe /c {{startCommand}}
commandList = [instance.config.startCommand];
} else {
commandList = commandStringToArray(instance.config.startCommand);
}
if (commandList.length === 0)
return instance.failure(new StartupError($t("TXT_CODE_pty_start.cmdEmpty")));
const pipeId = v4();
const pipeLinuxDir = "/tmp/mcsmanager-instance-pipe";
if (!fs.existsSync(pipeLinuxDir)) fs.mkdirsSync(pipeLinuxDir);
let pipeName = `${pipeLinuxDir}/pipe-${pipeId}`;
if (os.platform() === "win32") {
pipeName = `\\\\.\\pipe\\mcsmanager-${pipeId}`;
}
const ptyParameter = [
"-size",
`${instance.config.terminalOption.ptyWindowCol},${instance.config.terminalOption.ptyWindowRow}`,
"-coder",
instance.config.oe,
"-dir",
instance.absoluteCwdPath(),
"-fifo",
pipeName,
"-cmd",
JSON.stringify(commandList)
];
logger.info("----------------");
logger.info($t("TXT_CODE_pty_start.sourceRequest", { source: "" }));
logger.info($t("TXT_CODE_pty_start.instanceUuid", { instanceUuid: instance.instanceUuid }));
logger.info($t("TXT_CODE_pty_start.startCmd", { cmd: commandList.join(" ") }));
logger.info($t("TXT_CODE_pty_start.ptyPath", { path: PTY_PATH }));
logger.info($t("TXT_CODE_pty_start.ptyParams", { param: ptyParameter.join(" ") }));
logger.info($t("TXT_CODE_pty_start.ptyCwd", { cwd: instance.absoluteCwdPath() }));
logger.info("----------------");
// create pty child process
// Parameter 1 directly passes the process name or path (including spaces) without double quotes
const subProcess = spawn(PTY_PATH, ptyParameter, {
cwd: path.dirname(PTY_PATH),
stdio: "pipe",
windowsHide: true,
env: {
...process.env,
TERM: "xterm-256color"
}
});
// pty child process creation result check
if (!subProcess || !subProcess.pid) {
instance.println(
"ERROR",
$t("TXT_CODE_pty_start.pidErr", {
startCommand: instance.config.startCommand,
path: PTY_PATH,
params: JSON.stringify(ptyParameter)
})
);
throw new StartupError($t("TXT_CODE_pty_start.instanceStartErr"));
}
// create process adapter
const ptySubProcessCfg = await this.readPtySubProcessConfig(subProcess);
const processAdapter = new GoPtyProcessAdapter(subProcess, ptySubProcessCfg.pid, pipeName);
// After reading the configuration, Need to check the process status
// The "processAdapter.pid" here represents the process created by the PTY process
if (subProcess.exitCode !== null || processAdapter.pid == null || processAdapter.pid === 0) {
instance.println(
"ERROR",
$t("TXT_CODE_pty_start.pidErr", {
startCommand: instance.config.startCommand,
path: PTY_PATH,
params: JSON.stringify(ptyParameter)
})
);
throw new StartupError($t("TXT_CODE_pty_start.instanceStartErr"));
}
// generate open event
instance.started(processAdapter);
logger.info(
$t("TXT_CODE_pty_start.startSuccess", {
instanceUuid: instance.instanceUuid,
pid: ptySubProcessCfg.pid
})
);
instance.println("INFO", $t("TXT_CODE_pty_start.startEmulatedTerminal"));
}
}

View File

@ -0,0 +1,58 @@
import { $t } from "../../i18n";
import Instance from "../instance/instance";
import InstanceCommand from "./base/command";
export class StartupError extends Error {
constructor(msg: string) {
super(msg);
}
}
export default abstract class AbsStartCommand extends InstanceCommand {
private async sleep() {
return new Promise((ok) => {
setTimeout(ok, 1000 * 2);
});
}
async exec(instance: Instance) {
if (instance.status() !== Instance.STATUS_STOP)
return instance.failure(new StartupError($t("TXT_CODE_start.instanceNotDown")));
try {
instance.setLock(true);
instance.status(Instance.STATUS_STARTING);
instance.startCount++;
instance.startTimestamp = Date.now();
if (instance.config.endTime) {
const endTime = instance.config.endTime;
if (endTime) {
if (endTime <= instance.startTimestamp) {
throw new Error($t("TXT_CODE_start.instanceMaturity"));
}
}
}
instance.print("\n\n");
instance.println("INFO", $t("TXT_CODE_start.startInstance"));
// prevent the dead-loop from starting
await this.sleep();
return await this.createProcess(instance);
} catch (error: any) {
try {
await instance.execPreset("kill");
} catch (ignore) {}
instance.releaseResources();
instance.status(Instance.STATUS_STOP);
instance.failure(error);
} finally {
instance.setLock(false);
}
}
protected abstract createProcess(instance: Instance): Promise<void>;
}

View File

@ -0,0 +1,58 @@
import { t } from "i18next";
import Instance from "../../instance/instance";
import InstanceCommand from "../base/command";
import Rcon from "rcon-srcds";
import { isExitCommand } from "../general/general_command";
async function sendRconCommand(instance: Instance, command: string) {
const targetIp = instance.config.rconIp || "localhost";
const rconServer = new Rcon({
port: instance.config.rconPort,
host: targetIp,
encoding: "utf8",
timeout: 1000 * 6
});
await rconServer.authenticate(instance.config.rconPassword);
if (!rconServer.isAuthenticated()) {
throw new Error(t("TXT_CODE_1b1b2934"));
}
return new Promise((resolve, reject) => {
let hasResult = false;
setTimeout(() => {
if (!hasResult) {
rconServer.disconnect().catch(() => {});
instance.print(`[RCON] ${t("TXT_CODE_386f2d66")}\n`);
resolve("");
}
}, 1000 * 10);
rconServer
.execute(command)
.then((res) => {
hasResult = true;
instance.print(`[RCON] ${res}\n`);
rconServer.disconnect().catch(() => {});
resolve(res);
})
.catch((err) => {
reject(err);
});
instance.print(`[RCON] <<< ${command}\n`);
});
}
export default class RconCommand extends InstanceCommand {
constructor(public readonly cmd?: string) {
super("RconSendCommand");
}
async exec(instance: Instance, text?: string): Promise<any> {
if (isExitCommand(instance, text)) return;
try {
if (text || this.cmd) {
await sendRconCommand(instance, String(text ?? this.cmd));
}
} catch (error: any) {
instance.println("RCON ERROR", error?.message || error);
}
}
}

View File

@ -0,0 +1,23 @@
import { ILifeCycleTask } from "../../instance/life_cycle";
import Instance from "../../instance/instance";
import { MCServerStatus } from "common";
// When the instance is running, continue to check the expiration time
export default class PingMinecraftServerTask implements ILifeCycleTask {
public status: number = 0;
public name: string = "TimeCheck";
private task?: NodeJS.Timeout;
async start(instance: Instance) {
this.task = setInterval(() => {
instance.execPreset("refreshPlayers");
}, 1000 * 60);
}
async stop(instance: Instance) {
instance.resetPingInfo();
clearInterval(this.task);
this.task = undefined;
}
}

View File

@ -0,0 +1,115 @@
import fs from "fs-extra";
import path from "path";
import os from "os";
import { ILifeCycleTask } from "../../instance/life_cycle";
import Instance from "../../instance/instance";
import logger from "../../../service/log";
import { $t } from "../../../i18n";
import { ProcessWrapper } from "common";
import { FRPC_PATH } from "../../../const";
import { downloadFileToLocalFile } from "../../../service/download";
export class OpenFrp {
public processWrapper?: ProcessWrapper;
constructor(public readonly token: string, public readonly tunnelId: string) {
// ./frpc -u <passowrd> -p <channel id>
this.processWrapper = new ProcessWrapper(
FRPC_PATH,
["-u", this.token, "-p", this.tunnelId],
path.dirname(FRPC_PATH)
);
}
public open() {
logger.info("Start openfrp:", FRPC_PATH);
this.processWrapper?.start();
if (!this.processWrapper?.getPid()) {
throw new Error("pid is null");
}
}
public stop() {
try {
if (this.processWrapper?.exitCode() == null) {
this.processWrapper?.kill();
}
this.processWrapper = undefined;
} catch (error: any) {}
}
}
export default class OpenFrpTask implements ILifeCycleTask {
public status: number = 0;
public name: string = "openfrp";
public static readonly FRP_EXE_NAME = `frpc_${os.platform()}_${os.arch()}${
os.platform() === "win32" ? ".exe" : ""
}`;
public static readonly FRP_EXE_PATH = path.normalize(
path.join(process.cwd(), "lib", OpenFrpTask.FRP_EXE_NAME)
);
public static readonly FRP_DOWNLOAD_ADDR = "https://mcsmanager.oss-cn-guangzhou.aliyuncs.com/";
async start(instance: Instance) {
const { openFrpToken, openFrpTunnelId } = instance.config?.extraServiceConfig;
if (!openFrpToken || !openFrpTunnelId) return;
if (!fs.existsSync(OpenFrpTask.FRP_EXE_PATH)) {
const tmpTask = setInterval(() => {
instance.println("FRP", $t("TXT_CODE_frp.installing"));
}, 2000);
try {
await downloadFileToLocalFile(
OpenFrpTask.FRP_DOWNLOAD_ADDR + OpenFrpTask.FRP_EXE_NAME,
OpenFrpTask.FRP_EXE_PATH
);
instance.println("FRP", $t("TXT_CODE_frp.done"));
} catch (error: any) {
logger.error($t("TXT_CODE_frp.downloadErr"), error);
instance.println("ERROR", $t("TXT_CODE_frp.downloadErr") + `: ${error}`);
fs.remove(OpenFrpTask.FRP_EXE_PATH, () => {});
return;
} finally {
clearInterval(tmpTask);
}
}
const frpProcess = new OpenFrp(openFrpToken, openFrpTunnelId);
frpProcess.processWrapper?.on("start", (pid: number) => {
if (pid) {
logger.info(
`Instance ${instance.config.nickname}(${instance.instanceUuid}) ${pid} Frp task started!`
);
logger.info(`Params: ${openFrpTunnelId} | ${openFrpToken}`);
instance.openFrp = frpProcess;
instance.info.openFrpStatus = true;
} else {
logger.warn(
`Instance ${instance.config.nickname}(${instance.instanceUuid}) Frp task start failed! Process ID is ${pid}`
);
}
});
frpProcess.processWrapper?.on("exit", () => {
logger.info(
`Instance ${instance.config.nickname}(${instance.instanceUuid}) Frp task stopped!`
);
instance.info.openFrpStatus = false;
instance.openFrp = undefined;
});
try {
frpProcess.open();
} catch (error: any) {
logger.warn(
`Instance ${instance.config.nickname}(${instance.instanceUuid}) Frp task Start failure! ERR:`
);
logger.warn(error);
}
}
async stop(instance: Instance) {
if (instance.openFrp) {
const frpProcess = instance.openFrp;
frpProcess.stop();
}
}
}

View File

@ -0,0 +1,30 @@
import { ILifeCycleTask } from "../../instance/life_cycle";
import Instance from "../../instance/instance";
// When the instance is running, continue to check the expiration time
export default class TimeCheck implements ILifeCycleTask {
public status: number = 0;
public name: string = "TimeCheck";
private task: any = null;
async start(instance: Instance) {
this.task = setInterval(async () => {
if (instance.config.endTime) {
const endTime = instance.config.endTime;
if (endTime) {
const currentTime = Date.now();
if (endTime <= currentTime) {
// Expired, execute the end process command
await instance.execPreset("kill");
clearInterval(this.task);
}
}
}
}, 1000 * 60 * 60);
}
async stop(instance: Instance) {
clearInterval(this.task);
}
}

50
daemon/src/entity/config.ts Executable file
View File

@ -0,0 +1,50 @@
import { v4 } from "uuid";
import StorageSubsystem from "../common/system_storage";
function builderPassword() {
const a = `${v4().replace(/\-/gim, "")}`;
const b = a.slice(0, a.length / 2 - 1);
const c = `${v4().replace(/\-/gim, "")}`;
return b + c;
}
// @Entity
class Config {
public version = 2;
public ip = "";
public port = 24444;
public prefix = "";
public key = builderPassword();
public maxFileTask = 2;
public maxZipFileSize = 200;
public language = "en_us";
public defaultInstancePath = "";
}
// daemon configuration class
class GlobalConfiguration {
public config = new Config();
private static readonly ID = "global";
load() {
let config: Config = StorageSubsystem.load("Config", Config, GlobalConfiguration.ID);
if (config == null) {
config = new Config();
StorageSubsystem.store("Config", GlobalConfiguration.ID, config);
}
this.config = config;
}
store() {
StorageSubsystem.store("Config", GlobalConfiguration.ID, this.config);
}
}
class GlobalEnv {
public fileTaskCount = 0;
}
const globalConfiguration = new GlobalConfiguration();
const globalEnv = new GlobalEnv();
export { globalConfiguration, Config, globalEnv };

14
daemon/src/entity/ctx.ts Executable file
View File

@ -0,0 +1,14 @@
import { Socket } from "socket.io";
export default class RouterContext {
constructor(
public uuid: string | null,
public socket: Socket,
public session?: any,
public event?: string
) {}
public response(data: any) {
return this;
}
}

View File

@ -0,0 +1,83 @@
import Instance from "./instance";
import os from "os";
import { IGlobalInstanceConfig, IGlobalInstanceDockerConfig } from "common/global";
interface IActionCommand {
name: string;
command: string;
}
type ProcessType = "general" | "docker";
// @Entity
export default class InstanceConfig implements IGlobalInstanceConfig {
public nickname = "Undefined";
public startCommand = "";
public stopCommand = "^C";
public cwd = ".";
public ie = "utf-8";
public oe = "utf-8";
public createDatetime = Date.now();
public lastDatetime = Date.now();
public type = Instance.TYPE_UNIVERSAL;
public tag: string[] = [];
public endTime: number = 0;
public fileCode: string = "utf-8";
public processType: ProcessType = "general";
public updateCommand: string = "";
public crlf = os.platform() === "win32" ? 2 : 1; // 1: \n 2: \r\n
public category = 0;
// Steam RCON protocol
public enableRcon = false;
public rconPassword = "";
public rconPort = 0;
public rconIp = "";
// custom command list
public actionCommandList: IActionCommand[] = [];
// terminal option
public terminalOption = {
haveColor: false,
pty: true,
ptyWindowCol: 164,
ptyWindowRow: 40
};
// Event task
public eventTask = {
autoStart: false,
autoRestart: false,
ignore: false
};
// Extend
public docker: IGlobalInstanceDockerConfig = {
containerName: "",
image: "",
ports: [],
extraVolumes: [],
memory: 0,
networkMode: "bridge",
networkAliases: [],
cpusetCpus: "",
cpuUsage: 0,
maxSpace: 0,
io: 0,
network: 0,
workingDir: "/workspace/",
env: [],
changeWorkdir: true
};
public pingConfig = {
ip: "",
port: 25565,
type: 1
};
public extraServiceConfig = {
openFrpTunnelId: "",
openFrpToken: ""
};
}

View File

@ -0,0 +1,445 @@
import { $t } from "../../i18n";
import iconv from "iconv-lite";
import path from "path";
import { EventEmitter } from "events";
import { IExecutable } from "./preset";
import InstanceCommand from "../commands/base/command";
import InstanceConfig from "./Instance_config";
import StorageSubsystem from "../../common/system_storage";
import { LifeCycleTaskManager } from "./life_cycle";
import { PresetCommandManager } from "./preset";
import FunctionDispatcher, { IPresetCommand } from "../commands/dispatcher";
import { IInstanceProcess } from "./interface";
import StartCommand from "../commands/start";
import { configureEntityParams, toText } from "common";
import { OpenFrp } from "../commands/task/openfrp";
import logger from "../../service/log";
import { t } from "i18next";
interface IInstanceInfo {
mcPingOnline: boolean;
currentPlayers: number;
maxPlayers: number;
version: string;
fileLock: number;
playersChart: Array<{ value: string }>;
openFrpStatus: boolean;
latency: number;
}
interface IWatcherInfo {
terminalSize: {
w: number;
h: number;
};
}
const LINE_MAX_SIZE = 1024;
const TERM_TEXT_YELLOW = "\x1B[0;33;1m";
const TERM_TEXT_GOLD = "\x1B[0;33m"; // Gold §6
const TERM_RESET = "\x1B[0m";
const IGNORE_TEXT = [
"\n\n",
TERM_TEXT_GOLD,
"[MCSMANAGER] ",
TERM_RESET,
TERM_TEXT_YELLOW,
t("TXT_CODE_c5ed896f"),
TERM_RESET,
"\n\n"
].join("");
export default class Instance extends EventEmitter {
public static readonly STATUS_BUSY = -1;
public static readonly STATUS_STOP = 0;
public static readonly STATUS_STOPPING = 1;
public static readonly STATUS_STARTING = 2;
public static readonly STATUS_RUNNING = 3;
public static readonly TYPE_UNIVERSAL = "universal";
public static readonly TYPE_MINECRAFT_JAVA = "minecraft/java";
public static readonly TYPE_MINECRAFT_BEDROCK = "minecraft/bedrock";
public instanceStatus: number = Instance.STATUS_STOP;
public instanceUuid: string = "";
public lock: boolean = false;
public startCount: number = 0;
public startTimestamp: number = 0;
public asynchronousTask?: IExecutable | null;
public openFrp?: OpenFrp;
public readonly lifeCycleTaskManager = new LifeCycleTaskManager(this);
public readonly presetCommandManager = new PresetCommandManager(this);
public config: InstanceConfig;
public info: IInstanceInfo = {
mcPingOnline: false,
currentPlayers: 0,
maxPlayers: 0,
version: "",
fileLock: 0,
playersChart: [],
openFrpStatus: false,
latency: 0
};
public watchers: Map<string, IWatcherInfo> = new Map();
public process?: IInstanceProcess;
private outputStack: string[] = [];
private outputLoopTask?: NodeJS.Timer;
// When initializing an instance, the instance must be initialized through uuid and configuration class, otherwise the instance will be unavailable
constructor(instanceUuid: string, config: InstanceConfig) {
super();
if (!instanceUuid || !config) throw new Error($t("TXT_CODE_instanceConf.initInstanceErr"));
// Basic information
this.instanceStatus = Instance.STATUS_STOP;
this.instanceUuid = instanceUuid;
// Action lock
this.lock = false;
this.config = config;
this.process = undefined;
this.startCount = 0;
}
isStoppedOrBusy() {
return [Instance.STATUS_STOP, Instance.STATUS_BUSY].includes(this.status());
}
// Pass in instance configuration, loosely and dynamically set configuration items for instance parameters
parameters(cfg: any, persistence = true) {
// If the instance type changes, default commands and lifecycle events must be reset
if (cfg?.type && cfg?.type != this.config.type) {
if (!this.isStoppedOrBusy())
throw new Error($t("TXT_CODE_instanceConf.cantModifyInstanceType"));
configureEntityParams(this.config, cfg, "type", String);
this.forceExec(new FunctionDispatcher());
}
if (cfg?.enableRcon != null && cfg?.enableRcon !== this.config.enableRcon) {
if (!this.isStoppedOrBusy()) throw new Error($t("TXT_CODE_bdfa3457"));
configureEntityParams(this.config, cfg, "enableRcon", Boolean);
this.forceExec(new FunctionDispatcher());
}
if (cfg?.processType && cfg?.processType !== this.config.processType) {
if (!this.isStoppedOrBusy())
throw new Error($t("TXT_CODE_instanceConf.cantModifyProcessType"));
configureEntityParams(this.config, cfg, "processType", String);
this.forceExec(new FunctionDispatcher());
}
// If the terminal type is changed, the default command must be reset
if (
cfg?.terminalOption?.pty != null &&
cfg?.terminalOption?.pty !== this.config.terminalOption.pty
) {
if (!this.isStoppedOrBusy()) throw new Error($t("TXT_CODE_instanceConf.cantModifyPtyModel"));
configureEntityParams(this.config.terminalOption, cfg.terminalOption, "pty", Boolean);
this.forceExec(new FunctionDispatcher());
}
// Only allow some configuration items to be modified when the server is stopped
if (this.isStoppedOrBusy() && cfg.terminalOption) {
configureEntityParams(this.config.terminalOption, cfg.terminalOption, "ptyWindowCol", Number);
configureEntityParams(this.config.terminalOption, cfg.terminalOption, "ptyWindowRow", Number);
}
if (cfg.tag instanceof Array) {
cfg.tag = cfg.tag.map((tag: any) => String(tag).trim());
this.config.tag = cfg.tag;
}
if (cfg?.extraServiceConfig) {
configureEntityParams(
this.config.extraServiceConfig,
cfg.extraServiceConfig,
"isOpenFrp",
Boolean
);
configureEntityParams(
this.config.extraServiceConfig,
cfg.extraServiceConfig,
"openFrpToken",
String
);
configureEntityParams(
this.config.extraServiceConfig,
cfg.extraServiceConfig,
"openFrpTunnelId",
String
);
}
configureEntityParams(this.config, cfg, "nickname", String);
configureEntityParams(this.config, cfg, "startCommand", String);
configureEntityParams(this.config, cfg, "stopCommand", String);
configureEntityParams(this.config, cfg, "updateCommand", String);
configureEntityParams(this.config, cfg, "cwd", String);
configureEntityParams(this.config, cfg, "ie", String);
configureEntityParams(this.config, cfg, "oe", String);
configureEntityParams(this.config, cfg, "crlf", Number);
configureEntityParams(this.config, cfg, "endTime", Number);
configureEntityParams(this.config, cfg, "fileCode", String);
configureEntityParams(this.config, cfg, "rconPassword", String);
configureEntityParams(this.config, cfg, "rconPort", Number);
configureEntityParams(this.config, cfg, "rconIp", String);
configureEntityParams(this.config, cfg, "category", Number);
if (cfg.docker) {
configureEntityParams(this.config.docker, cfg.docker, "containerName", String);
configureEntityParams(this.config.docker, cfg.docker, "image", String);
configureEntityParams(this.config.docker, cfg.docker, "memory", Number);
configureEntityParams(this.config.docker, cfg.docker, "ports");
configureEntityParams(this.config.docker, cfg.docker, "extraVolumes");
configureEntityParams(this.config.docker, cfg.docker, "maxSpace", Number);
configureEntityParams(this.config.docker, cfg.docker, "io", Number);
configureEntityParams(this.config.docker, cfg.docker, "network", Number);
configureEntityParams(this.config.docker, cfg.docker, "networkMode", String);
configureEntityParams(this.config.docker, cfg.docker, "networkAliases");
configureEntityParams(this.config.docker, cfg.docker, "cpusetCpus", String);
configureEntityParams(this.config.docker, cfg.docker, "cpuUsage", Number);
configureEntityParams(this.config.docker, cfg.docker, "env");
configureEntityParams(this.config.docker, cfg.docker, "workingDir", String);
configureEntityParams(this.config.docker, cfg.docker, "changeWorkdir", Boolean);
}
if (cfg.pingConfig) {
configureEntityParams(this.config.pingConfig, cfg.pingConfig, "ip", String);
configureEntityParams(this.config.pingConfig, cfg.pingConfig, "port", Number);
configureEntityParams(this.config.pingConfig, cfg.pingConfig, "type", Number);
}
if (cfg.eventTask) {
configureEntityParams(this.config.eventTask, cfg.eventTask, "autoStart", Boolean);
configureEntityParams(this.config.eventTask, cfg.eventTask, "autoRestart", Boolean);
configureEntityParams(this.config.eventTask, cfg.eventTask, "ignore", Boolean);
}
if (cfg.terminalOption) {
configureEntityParams(this.config.terminalOption, cfg.terminalOption, "haveColor", Boolean);
}
if (persistence) StorageSubsystem.store("InstanceConfig", this.instanceUuid, this.config);
}
setLock(bool: boolean) {
if (this.lock === true && bool === true) {
throw new Error($t("TXT_CODE_ca030197"));
}
this.lock = bool;
}
// force the command to execute
async forceExec(command: InstanceCommand) {
return await command.exec(this);
}
// set instance state or get state
status(v?: number) {
if (v != null) this.instanceStatus = v;
return this.instanceStatus;
}
// function that must be executed after the instance starts
// Trigger the open event and bind the data and exit events, etc.
started(process: IInstanceProcess) {
this.config.lastDatetime = Date.now();
const outputCode = this.config.terminalOption.pty ? "utf-8" : this.config.oe;
process.on("data", (text: any) => {
this.pushOutput(iconv.decode(text, outputCode));
});
process.on("exit", (code: number) => this.stopped(code));
this.process = process;
this.instanceStatus = Instance.STATUS_RUNNING;
this.emit("open", this);
// start all lifecycle tasks
this.lifeCycleTaskManager.execLifeCycleTask(1);
this.startOutputLoop();
}
// If the instance performs any operation exception, it must throw an exception through this function
// trigger failure event
failure(error: Error) {
this.emit("failure", error);
this.println("Operation Error", error.message ?? String(error));
throw error;
}
// function that must be executed after the instance has been closed
// trigger exit event
stopped(code = 0) {
this.releaseResources();
if (this.instanceStatus != Instance.STATUS_STOP) {
this.instanceStatus = Instance.STATUS_STOP;
this.startTimestamp = 0;
this.emit("exit", code);
StorageSubsystem.store("InstanceConfig", this.instanceUuid, this.config);
}
// Close all lifecycle tasks
this.stopOutputLoop();
this.lifeCycleTaskManager.execLifeCycleTask(0);
// If automatic restart is enabled, the startup operation is performed immediately
if (!this.config.eventTask.ignore && this.config.eventTask.autoRestart) {
this.execPreset("start")
.then(() => {
this.println($t("TXT_CODE_instanceConf.info"), $t("TXT_CODE_instanceConf.autoRestart"));
})
.catch((err) => {
this.println(
$t("TXT_CODE_instanceConf.error"),
$t("TXT_CODE_instanceConf.autoRestartErr", { err: err })
);
});
}
this.config.eventTask.ignore = false;
// Turn off the warning immediately after startup, usually the startup command is written incorrectly
const currentTimestamp = new Date().getTime();
const startThreshold = 2 * 1000;
if (currentTimestamp - this.startTimestamp < startThreshold) {
this.println("ERROR", $t("TXT_CODE_aae2918f"));
}
}
ignoreEventTaskOnce() {
if (this.config.eventTask) this.config.eventTask.ignore = true;
}
// custom output method, formatting
println(level: string, text: string) {
const str = `[${level}] ${text}\n`;
this.emit("data", str);
}
// custom output method
print(data: any) {
this.emit("data", data);
}
// Release resources (mainly release process-related resources)
releaseResources() {
try {
this.process?.destroy();
} catch (error: any) {
logger.error(`Instance ${this.instanceUuid}, Release resources error: ${error}`);
} finally {
this.process = undefined;
}
}
// destroy this instance
destroy() {
if (this.process && this.process.pid) {
this.process.kill("SIGKILL");
}
this.process = undefined;
}
fullTime() {
const date = new Date();
return date.toLocaleDateString() + " " + date.getHours() + ":" + date.getMinutes();
}
hasCwdPath() {
return !!this.config.cwd;
}
absoluteCwdPath() {
if (!this.config || !this.config.cwd) throw new Error("Instance config error, cwd is Null!");
if (path.isAbsolute(this.config.cwd)) return path.normalize(this.config.cwd);
return path.normalize(path.join(process.cwd(), this.config.cwd));
}
// execute the preset command action
async execPreset(action: IPresetCommand, p?: any) {
if (this.presetCommandManager) {
return await this.presetCommandManager.execPreset(action, p);
}
throw new Error(`Preset Manager does not exist`);
}
setPreset(action: IPresetCommand, cmd: InstanceCommand) {
this.presetCommandManager.setPreset(action, cmd);
}
getPreset(action: IPresetCommand) {
return this.presetCommandManager.getPreset(action);
}
clearPreset() {
this.presetCommandManager.clearPreset();
}
computeTerminalSize() {
let minW = this.config.terminalOption.ptyWindowCol;
let minH = this.config.terminalOption.ptyWindowRow;
for (const iterator of this.watchers.values()) {
const { w, h } = iterator.terminalSize;
if (w && h) {
if (w < minW) minW = w;
if (h < minH) minH = h;
}
}
return {
w: minW,
h: minH
};
}
public resetPingInfo() {
this.info.mcPingOnline = false;
this.info.currentPlayers = 0;
this.info.maxPlayers = 0;
this.info.version = "";
this.info.latency = 0;
}
public parseTextParams(text: string) {
text = text.replace(/\{mcsm_workspace\}/gim, this.absoluteCwdPath());
text = text.replace(/\{mcsm_instance_id\}/gim, this.instanceUuid);
text = text.replace(/\{mcsm_cwd\}/gim, this.absoluteCwdPath());
return text;
}
private pushOutput(data: string) {
if (data.length > LINE_MAX_SIZE * 100) {
this.outputStack.push(IGNORE_TEXT);
} else if (data.length > LINE_MAX_SIZE) {
for (let index = 0; index < Math.ceil(data.length / LINE_MAX_SIZE); index++) {
const tmp = data.slice(index * LINE_MAX_SIZE, (index + 1) * LINE_MAX_SIZE);
if (tmp) this.outputStack.push(tmp);
}
} else {
this.outputStack.push(data);
}
if (this.outputStack.length >= 100) {
this.outputStack.splice(0, 50);
this.outputStack.splice(0, 0, IGNORE_TEXT);
}
}
private startOutputLoop() {
this.stopOutputLoop();
this.outputLoopTask = setInterval(() => {
if (this.outputStack.length > 0) {
const buf = this.outputStack.splice(0, 10);
this.emit("data", buf.join(""));
}
}, 50);
}
private stopOutputLoop() {
if (this.outputLoopTask) clearInterval(this.outputLoopTask);
this.outputLoopTask = undefined;
}
}

View File

@ -0,0 +1,9 @@
import { EventEmitter } from "events";
// Instance specific process interface
export interface IInstanceProcess extends EventEmitter {
pid?: number | string;
kill: (signal?: any) => any;
destroy: () => void;
write: (data?: any) => any;
}

View File

@ -0,0 +1,38 @@
import Instance from "./instance";
export interface ILifeCycleTask {
name: string; // task name
status: number; // Running status, the default is 0, the task manager will automatically change
start: (instance: Instance) => Promise<void>;
stop: (instance: Instance) => Promise<void>;
}
export class LifeCycleTaskManager {
// list of life cycle tasks
public readonly lifeCycleTask: ILifeCycleTask[] = [];
constructor(private self: any) {}
registerLifeCycleTask(task: ILifeCycleTask) {
this.lifeCycleTask.push(task);
}
execLifeCycleTask(type: 1 | 0) {
if (type == 1) {
this.lifeCycleTask.forEach((v) => {
if (v.status === 0) v.start(this.self);
v.status = 1;
});
} else {
this.lifeCycleTask.forEach((v) => {
if (v.status === 1) v.stop(this.self);
v.status = 0;
});
}
}
clearLifeCycleTask() {
this.execLifeCycleTask(0);
this.lifeCycleTask.splice(0, this.lifeCycleTask.length);
}
}

View File

@ -0,0 +1,30 @@
import { $t } from "../../i18n";
import { IPresetCommand } from "../commands/dispatcher";
export interface IExecutable {
exec: (a: any, b?: any) => Promise<any>;
stop?: (a: any) => Promise<void>;
}
export class PresetCommandManager {
public readonly preset = new Map<IPresetCommand, IExecutable>();
constructor(private self: any) {}
setPreset(action: IPresetCommand, cmd: IExecutable) {
this.preset.set(action, cmd);
}
getPreset(action: IPresetCommand) {
return this.preset.get(action);
}
async execPreset(action: IPresetCommand, p?: any) {
const cmd = this.preset.get(action);
if (!cmd) throw new Error($t("TXT_CODE_preset.actionErr", { action: action }));
return await cmd.exec(this.self, p);
}
clearPreset() {
this.preset.clear();
}
}

View File

@ -0,0 +1,77 @@
import { $t } from "../../i18n";
import yaml from "yaml";
import toml from "@iarna/toml";
import properties from "properties";
import path from "path";
import fs from "fs-extra";
const CONFIG_FILE_ENCODE = "utf-8";
export interface IProcessConfig {
fileName: string;
path: string;
type: string;
info: string | null;
redirect: string;
from?: string;
fromLink?: string | null;
}
export class ProcessConfig {
constructor(public iProcessConfig: IProcessConfig) {
iProcessConfig.path = path.normalize(iProcessConfig.path);
}
// Automatically parse the local file according to the type and return the configuration object
read(): any {
const text = fs.readFileSync(this.iProcessConfig.path, { encoding: CONFIG_FILE_ENCODE });
if (this.iProcessConfig.type === "yml") {
return yaml.parse(text);
}
if (this.iProcessConfig.type == "toml") {
return toml.parse(text);
}
if (this.iProcessConfig.type === "properties") {
return properties.parse(text);
}
if (this.iProcessConfig.type === "json") {
return JSON.parse(text);
}
if (this.iProcessConfig.type === "txt") {
return text;
}
}
// Automatically save to the local configuration file according to the parameter object
write(object: Object | toml.JsonMap) {
let text = "";
if (this.iProcessConfig.type === "yml") {
text = yaml.stringify(object);
}
if (this.iProcessConfig.type === "toml") {
text = toml.stringify(<toml.JsonMap>object);
}
if (this.iProcessConfig.type === "properties") {
text = properties.stringify(object, {
unicode: true
});
text = text.replace(/ = /gim, "=");
if (this.iProcessConfig.fileName == "server.properties") {
text = text.replace(/\\\\u/gim, "\\u");
}
}
if (this.iProcessConfig.type === "json") {
text = JSON.stringify(object, null, 4);
}
if (this.iProcessConfig.type === "txt") {
text = object.toString();
}
if (!text && this.iProcessConfig.type !== "txt")
throw new Error($t("TXT_CODE_process_config.writEmpty"));
fs.writeFileSync(this.iProcessConfig.path, text, { encoding: CONFIG_FILE_ENCODE });
}
exists() {
return fs.existsSync(this.iProcessConfig.path);
}
}

60
daemon/src/i18n/index.ts Executable file
View File

@ -0,0 +1,60 @@
// I18n init configuration (Daemon)
// If you want to add the language of your own country, you need to add the code here.
import i18next from "i18next";
import zh_cn from "@languages/zh_CN.json";
import en_us from "@languages/en_US.json";
import zh_tw from "@languages/zh_TW.json";
import ja_JP from "@languages/ja_JP.json";
import es_ES from "@languages/es_ES.json";
import fr_FR from "@languages/fr_FR.json";
import ru_RU from "@languages/ru_RU.json";
import ko_KR from "@languages/ko_KR.json";
import de_DE from "@languages/de_DE.json";
import pt_BR from "@languages/pt_BR.json";
i18next.init({
interpolation: {
escapeValue: false
},
lng: "en_us",
fallbackLng: "en_us",
resources: {
en_us: {
translation: en_us
},
zh_cn: {
translation: zh_cn
},
zh_tw: {
translation: zh_tw
},
ja_jp: {
translation: ja_JP
},
es_es: {
translation: es_ES
},
fr_fr: {
translation: fr_FR
},
ru_ru: {
translation: ru_RU
},
ko_kr: {
translation: ko_KR
},
de_de: {
translation: de_DE
},
pt_br: {
translation: pt_BR
}
}
});
// alias
const $t = i18next.t;
export { $t, i18next };

View File

@ -0,0 +1,503 @@
import { $t } from "../i18n";
import fs from "fs-extra";
import * as protocol from "../service/protocol";
import { routerApp } from "../service/router";
import InstanceSubsystem from "../service/system_instance";
import Instance from "../entity/instance/instance";
import logger from "../service/log";
import path from "path";
import { IInstanceDetail, IJson } from "../service/interfaces";
import ProcessInfoCommand from "../entity/commands/process_info";
import FileManager from "../service/system_file";
import { ProcessConfig } from "../entity/instance/process_config";
import { TaskCenter } from "../service/async_task_service";
import { createQuickInstallTask } from "../service/async_task_service/quick_install";
import { QuickInstallTask } from "../service/async_task_service/quick_install";
import { toNumber } from "common";
import { arrayUnique } from "common";
// Some instances operate router authentication middleware
routerApp.use((event, ctx, data, next) => {
if (event === "instance/new" && data) return next();
if (event === "instance/overview") return next();
if (event === "instance/select") return next();
if (event === "instance/asynchronous") return next();
if (event === "instance/query_asynchronous") return next();
if (event === "instance/stop_asynchronous") return next();
if (event.startsWith("instance")) {
if (data.instanceUuids) return next();
const instanceUuid = data.instanceUuid;
if (!InstanceSubsystem.exists(instanceUuid)) {
return protocol.error(ctx, event, {
instanceUuid: instanceUuid,
err: `The operation failed, the instance ${instanceUuid} does not exist.`
});
}
}
next();
});
// Get the list of instances of this daemon (query)
routerApp.on("instance/select", (ctx, data) => {
const page = toNumber(data.page) ?? 1;
const pageSize = toNumber(data.pageSize) ?? 1;
const condition = data.condition;
const targetTag = data.condition.tag;
const overview: IInstanceDetail[] = [];
// keyword condition query
const queryWrapper = InstanceSubsystem.getQueryMapWrapper();
const allTags: string[] = [];
let searchTags: string[] = [];
if (targetTag instanceof Array && targetTag.length > 0) {
searchTags = targetTag.map((v) => String(v).trim());
}
let result = queryWrapper.select<Instance>((v) => {
if (v.config.tag) allTags.push(...v.config.tag);
if (InstanceSubsystem.isGlobalInstance(v)) return false;
if (!v.config.nickname.toLowerCase().includes(condition.instanceName.toLowerCase()))
return false;
if (condition.status && v.instanceStatus !== Number(condition.status)) return false;
if (searchTags.length > 0) {
const myTags = v.config.tag || [];
const res = myTags.filter((v) => searchTags.includes(v));
if (res.length === 0 || res.length !== searchTags.length) return false;
}
return true;
});
result = result.sort((a, b) => (a.config.nickname > b.config.nickname ? 1 : -1));
// paging function
const pageResult = queryWrapper.page<Instance>(result, page, pageSize);
// filter unwanted data
pageResult.data.forEach((instance) => {
overview.push({
instanceUuid: instance.instanceUuid,
started: instance.startCount,
status: instance.status(),
config: instance.config,
info: instance.info
});
});
overview.sort((a, b) => {
if (a.status !== b.status) {
return b.status - a.status;
}
return a.config.nickname >= b.config.nickname ? 1 : -1;
});
protocol.response(ctx, {
page: pageResult.page,
pageSize: pageResult.pageSize,
maxPage: pageResult.maxPage,
allTags: arrayUnique(allTags).slice(0, 60),
data: overview
});
});
// Get an overview of this daemon instance
routerApp.on("instance/overview", (ctx) => {
const overview: IInstanceDetail[] = [];
InstanceSubsystem.getInstances().forEach((instance) => {
overview.push({
instanceUuid: instance.instanceUuid,
started: instance.startCount,
status: instance.status(),
config: instance.config,
info: instance.info
});
});
protocol.msg(ctx, "instance/overview", overview);
});
// Get an overview of some instances of this daemon
routerApp.on("instance/section", (ctx, data) => {
const instanceUuids = data.instanceUuids as string[];
const overview: IInstanceDetail[] = [];
InstanceSubsystem.getInstances().forEach((instance) => {
instanceUuids.forEach((targetUuid) => {
if (targetUuid === instance.instanceUuid) {
overview.push({
instanceUuid: instance.instanceUuid,
started: instance.startCount,
status: instance.status(),
config: instance.config,
info: instance.info
});
}
});
});
protocol.msg(ctx, "instance/section", overview);
});
// View details of a single instance
routerApp.on("instance/detail", async (ctx, data) => {
try {
const instanceUuid = data.instanceUuid;
const instance = InstanceSubsystem.getInstance(instanceUuid);
if (!instance) throw new Error($t("TXT_CODE_3bfb9e04"));
let processInfo = null;
let space = 0;
try {
// Parts that may be wrong due to file permissions, avoid affecting the acquisition of the entire configuration
processInfo = await instance.forceExec(new ProcessInfoCommand());
} catch (err: any) {}
protocol.msg(ctx, "instance/detail", {
instanceUuid: instance.instanceUuid,
started: instance.startCount,
status: instance.status(),
config: instance.config,
info: instance.info,
space,
processInfo
});
} catch (err: any) {
protocol.error(ctx, "instance/detail", { err: err.message });
}
});
// create a new application instance
routerApp.on("instance/new", (ctx, data) => {
const config = data;
try {
const newInstance = InstanceSubsystem.createInstance(config);
protocol.msg(ctx, "instance/new", {
instanceUuid: newInstance.instanceUuid,
config: newInstance.config
});
} catch (err: any) {
protocol.error(ctx, "instance/new", { instanceUuid: null, err: err.message });
}
});
// update instance data
routerApp.on("instance/update", (ctx, data) => {
const instanceUuid = data.instanceUuid;
const config = data.config;
try {
InstanceSubsystem.getInstance(instanceUuid)?.parameters(config);
protocol.msg(ctx, "instance/update", { instanceUuid });
} catch (err: any) {
protocol.error(ctx, "instance/update", { instanceUuid: instanceUuid, err: err.message });
}
});
// Request to forward all IO data of an instance
routerApp.on("instance/forward", (ctx, data) => {
const targetInstanceUuid = data.instanceUuid;
const isforward: boolean = data.forward;
try {
// InstanceSubsystem.getInstance(targetInstanceUuid);
if (isforward) {
logger.info(
$t("TXT_CODE_Instance_router.requestIO", {
id: ctx.socket.id,
targetInstanceUuid: targetInstanceUuid
})
);
InstanceSubsystem.forward(targetInstanceUuid, ctx.socket);
} else {
logger.info(
$t("TXT_CODE_Instance_router.cancelIO", {
id: ctx.socket.id,
targetInstanceUuid: targetInstanceUuid
})
);
InstanceSubsystem.stopForward(targetInstanceUuid, ctx.socket);
}
protocol.msg(ctx, "instance/forward", { instanceUuid: targetInstanceUuid });
} catch (err: any) {
protocol.error(ctx, "instance/forward", { instanceUuid: targetInstanceUuid, err: err.message });
}
});
// open the instance
routerApp.on("instance/open", async (ctx, data) => {
const disableResponse = data.disableResponse;
for (const instanceUuid of data.instanceUuids) {
const instance = InstanceSubsystem.getInstance(instanceUuid);
try {
await instance!.execPreset("start");
if (!disableResponse) protocol.msg(ctx, "instance/open", { instanceUuid });
} catch (err: any) {
if (!disableResponse) {
logger.error(
$t("TXT_CODE_Instance_router.openInstanceErr", { instanceUuid: instanceUuid }),
err
);
protocol.error(ctx, "instance/open", { instanceUuid: instanceUuid, err: err.message });
}
}
}
});
// close the instance
routerApp.on("instance/stop", async (ctx, data) => {
const disableResponse = data.disableResponse;
for (const instanceUuid of data.instanceUuids) {
const instance = InstanceSubsystem.getInstance(instanceUuid);
try {
if (!instance) throw new Error($t("TXT_CODE_3bfb9e04"));
await instance.execPreset("stop");
//Note: Removing this reply will cause the front-end response to be slow, because the front-end will wait for the panel-side message to be forwarded
if (!disableResponse) protocol.msg(ctx, "instance/stop", { instanceUuid });
} catch (err: any) {
if (!disableResponse)
protocol.error(ctx, "instance/stop", { instanceUuid: instanceUuid, err: err.message });
}
}
});
// restart the instance
routerApp.on("instance/restart", async (ctx, data) => {
const disableResponse = data.disableResponse;
for (const instanceUuid of data.instanceUuids) {
const instance = InstanceSubsystem.getInstance(instanceUuid);
try {
if (!instance) throw new Error($t("TXT_CODE_3bfb9e04"));
await instance.execPreset("restart");
if (!disableResponse) protocol.msg(ctx, "instance/restart", { instanceUuid });
} catch (err: any) {
if (!disableResponse)
protocol.error(ctx, "instance/restart", { instanceUuid: instanceUuid, err: err.message });
}
}
});
// terminate instance method
routerApp.on("instance/kill", async (ctx, data) => {
const disableResponse = data.disableResponse;
for (const instanceUuid of data.instanceUuids) {
const instance = InstanceSubsystem.getInstance(instanceUuid);
if (!instance) continue;
try {
await instance.execPreset("kill");
if (!disableResponse) protocol.msg(ctx, "instance/kill", { instanceUuid });
} catch (err: any) {
if (!disableResponse)
protocol.error(ctx, "instance/kill", { instanceUuid: instanceUuid, err: err.message });
}
}
});
// Send a command to the application instance
routerApp.on("instance/command", async (ctx, data) => {
const disableResponse = data.disableResponse;
const instanceUuid = data.instanceUuid;
const command = data.command || "";
const instance = InstanceSubsystem.getInstance(instanceUuid);
try {
if (!instance) throw new Error($t("TXT_CODE_3bfb9e04"));
await instance.execPreset("command", command);
if (!disableResponse) protocol.msg(ctx, "instance/command", { instanceUuid });
} catch (err: any) {
if (!disableResponse)
protocol.error(ctx, "instance/command", { instanceUuid: instanceUuid, err: err.message });
}
});
// delete instance
routerApp.on("instance/delete", (ctx, data) => {
const instanceUuids = data.instanceUuids;
const deleteFile = data.deleteFile;
for (const instanceUuid of instanceUuids) {
try {
InstanceSubsystem.removeInstance(instanceUuid, deleteFile);
} catch (err: any) {}
}
protocol.msg(ctx, "instance/delete", instanceUuids);
});
// perform complex asynchronous tasks
routerApp.on("instance/asynchronous", (ctx, data) => {
const instanceUuid = data.instanceUuid;
const taskName = data.taskName;
const parameter = data.parameter;
const instance = InstanceSubsystem.getInstance(instanceUuid);
logger.info(
$t("TXT_CODE_Instance_router.performTasks", {
id: ctx.socket.id,
uuid: instanceUuid,
taskName: taskName
})
);
// Install instance via preset package
if (taskName === "install_instance" && instance) {
instance
.execPreset("install", parameter)
.then(() => {})
.catch((err) => {
logger.error(
$t("TXT_CODE_Instance_router.performTasksErr", {
uuid: instance.instanceUuid,
taskName: taskName,
err: err
})
);
});
}
// Instance software update via Command
if (taskName === "update" && instance) {
instance
.execPreset("update", parameter)
.then(() => {})
.catch((err) => {
logger.error(
$t("TXT_CODE_Instance_router.performTasksErr", {
uuid: instance.instanceUuid,
taskName: taskName,
err: err
})
);
});
}
// Quick install Minecraft server task
if (taskName === "quick_install") {
const newInstanceName = String(parameter.newInstanceName);
const targetLink = String(parameter.targetLink);
logger.info(`Quick install: Name: ${newInstanceName} | Download: ${targetLink}`);
const task = createQuickInstallTask(targetLink, newInstanceName, parameter.setupInfo);
return protocol.response(ctx, task.toObject());
}
protocol.response(ctx, true);
});
// Terminate the execution of complex asynchronous tasks
routerApp.on("instance/stop_asynchronous", (ctx, data) => {
const instanceUuid = data.instanceUuid;
const { taskId } = data.parameter;
const instance = InstanceSubsystem.getInstance(instanceUuid);
// Multi-instance async task
if (taskId && typeof taskId === "string") {
const task = TaskCenter.getTask(taskId);
if (!task) throw new Error(`Async Task ID: ${taskId} does not exist`);
task.stop();
return protocol.response(ctx, true);
}
// Singleton async task
const task = instance?.asynchronousTask;
if (task && task.stop) {
task
.stop(instance)
.then(() => {})
.catch((err) => {});
} else {
return protocol.error(
ctx,
"instance/stop_asynchronous",
$t("TXT_CODE_Instance_router.taskEmpty")
);
}
protocol.response(ctx, true);
});
// Query async task status
routerApp.on("instance/query_asynchronous", (ctx, data) => {
const taskId = data.parameter.taskId as string | undefined;
const taskName = data.taskName as string;
const taskNameTypeMap: IJson<string> = {
quick_install: QuickInstallTask.TYPE
};
const type = String(taskNameTypeMap[taskName] || QuickInstallTask.TYPE);
if (!taskId) {
const result = [];
for (const task of TaskCenter.getTasks(type)) {
result.push({
taskId: task.taskId,
status: task.status(),
detail: task.toObject()
});
}
protocol.response(ctx, result);
} else {
const task = TaskCenter.getTask(String(taskId));
if (task)
protocol.response(ctx, {
taskId: task.taskId,
status: task.status(),
detail: task.toObject()
});
}
});
routerApp.on("instance/process_config/list", (ctx, data) => {
const instanceUuid = data.instanceUuid;
const files = data.files;
const result: any[] = [];
try {
const instance = InstanceSubsystem.getInstance(instanceUuid);
if (!instance) throw new Error($t("TXT_CODE_3bfb9e04"));
const fileManager = new FileManager(instance.absoluteCwdPath());
for (const filePath of files) {
if (fileManager.check(filePath)) {
result.push({
file: filePath,
check: true
});
}
}
protocol.response(ctx, result);
} catch (err: any) {
protocol.responseError(ctx, err);
}
});
// Get or update the content of the instance specified file
routerApp.on("instance/process_config/file", (ctx, data) => {
const instanceUuid = data.instanceUuid;
const fileName = data.fileName;
const config = data.config || null;
const fileType = data.type;
try {
const instance = InstanceSubsystem.getInstance(instanceUuid);
if (!instance) throw new Error($t("TXT_CODE_3bfb9e04"));
const fileManager = new FileManager(instance.absoluteCwdPath());
if (!fileManager.check(fileName)) throw new Error($t("TXT_CODE_Instance_router.accessFileErr"));
const filePath = path.normalize(path.join(instance.absoluteCwdPath(), fileName));
const processConfig = new ProcessConfig({
fileName: fileName,
redirect: fileName,
path: filePath,
type: fileType,
info: null,
fromLink: null
});
if (config) {
processConfig.write(config);
return protocol.response(ctx, true);
} else {
const json = processConfig.read();
return protocol.response(ctx, json);
}
} catch (err: any) {
protocol.responseError(ctx, err);
}
});
// Get instance terminal log
routerApp.on("instance/outputlog", async (ctx, data) => {
const instanceUuid = data.instanceUuid;
try {
const filePath = path.join(InstanceSubsystem.LOG_DIR, `${instanceUuid}.log`);
if (fs.existsSync(filePath)) {
const text = await fs.readFile(filePath, { encoding: "utf-8" });
return protocol.response(ctx, text);
}
protocol.responseError(ctx, new Error($t("TXT_CODE_Instance_router.terminalLogNotExist")), {
disablePrint: true
});
} catch (err: any) {
protocol.responseError(ctx, err);
}
});

View File

@ -0,0 +1,72 @@
import { $t } from "../i18n";
import { routerApp } from "../service/router";
import * as protocol from "../service/protocol";
import { globalConfiguration } from "../entity/config";
import logger from "../service/log";
import RouterContext from "../entity/ctx";
import { IGNORE } from "../const";
import { LOGIN_BY_TOP_LEVEL, loginSuccessful } from "../service/mission_passport";
// latest verification time
const AUTH_TIMEOUT = 6000;
// Top-level authority authentication middleware (this is the first place for any authority authentication middleware)
routerApp.use(async (event, ctx, _, next) => {
const socket = ctx.socket;
// release all data flow controllers
if (event.startsWith("stream")) return next();
// Except for the auth controller, which is publicly accessible, other business controllers must be authorized before they can be accessed
if (event === "auth") return await next();
if (!ctx.session) throw new Error("Session does not exist in authentication middleware.");
if (
ctx.session.key === globalConfiguration.config.key &&
ctx.session.type === LOGIN_BY_TOP_LEVEL &&
ctx.session.login &&
ctx.session.id
) {
return await next();
}
logger.warn(
$t("TXT_CODE_auth_router.notAccess", {
id: socket.id,
address: socket.handshake.address,
event: event
})
);
return protocol.error(ctx, "error", IGNORE, {
disablePrint: true
});
});
// authentication controller
routerApp.on("auth", (ctx, data) => {
if (data === globalConfiguration.config.key) {
// The authentication is passed, and the registered session is a trusted session
logger.info(
$t("TXT_CODE_auth_router.access", {
id: ctx.socket.id,
address: ctx.socket.handshake.address
})
);
loginSuccessful(ctx, data);
protocol.msg(ctx, "auth", true);
} else {
protocol.msg(ctx, "auth", false);
}
});
// Connected event for timeout authentication close
routerApp.on("connection", (ctx) => {
const session = ctx.session;
setTimeout(() => {
if (!session.login) {
ctx.socket.disconnect();
logger.info(
$t("TXT_CODE_auth_router.disconnect", {
id: ctx.socket.id,
address: ctx.socket.handshake.address
})
);
}
}, AUTH_TIMEOUT);
});

View File

@ -0,0 +1,114 @@
import { $t } from "../i18n";
import { DockerManager } from "../service/docker_service";
import * as protocol from "../service/protocol";
import { routerApp } from "../service/router";
import * as fs from "fs-extra";
import path from "path";
import { v4 } from "uuid";
import logger from "../service/log";
import os from "os";
// Get the image list of this system
routerApp.on("environment/images", async (ctx, data) => {
try {
const docker = new DockerManager().getDocker();
const result = await docker.listImages();
protocol.response(ctx, result);
} catch (error: any) {
protocol.responseError(ctx, $t("TXT_CODE_environment_router.dockerInfoErr"));
}
});
// Get the list of containers in this system
routerApp.on("environment/containers", async (ctx, data) => {
try {
const docker = new DockerManager().getDocker();
const result = await docker.listContainers();
protocol.response(ctx, result);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// Get the network list of this system
routerApp.on("environment/networkModes", async (ctx, data) => {
try {
const docker = new DockerManager().getDocker();
const result = await docker.listNetworks();
protocol.response(ctx, result);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// create image
routerApp.on("environment/new_image", async (ctx, data) => {
try {
const dockerFileText = data.dockerFile;
const name = data.name;
const tag = data.tag;
// Initialize the image file directory and Dockerfile
const uuid = v4();
const dockerFileDir = path.normalize(path.join(process.cwd(), "tmp", uuid));
if (!fs.existsSync(dockerFileDir)) fs.mkdirsSync(dockerFileDir);
// write to DockerFile
const dockerFilepath = path.normalize(path.join(dockerFileDir, "Dockerfile"));
await fs.writeFile(dockerFilepath, dockerFileText, { encoding: "utf-8" });
logger.info(
$t("TXT_CODE_environment_router.crateImage", {
name: name,
tag: tag,
dockerFileText: dockerFileText
})
);
// pre-response
protocol.response(ctx, true);
// start creating
const dockerImageName = `${name}:${tag}`;
try {
await new DockerManager().startBuildImage(dockerFileDir, dockerImageName);
logger.info($t("TXT_CODE_environment_router.crateSuccess", { name: name, tag: tag }));
} catch (error: any) {
logger.info(
$t("TXT_CODE_environment_router.crateErr", { name: name, tag: tag, error: error })
);
}
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// delete image
routerApp.on("environment/del_image", async (ctx, data) => {
try {
const imageId = data.imageId;
const docker = new DockerManager().getDocker();
const image = docker.getImage(imageId);
if (image) {
logger.info($t("TXT_CODE_environment_router.delImage", { imageId: imageId }));
await image.remove();
} else {
throw new Error("Image does not exist");
}
protocol.response(ctx, true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// Get the progress of all mirroring tasks
routerApp.on("environment/progress", async (ctx) => {
try {
const data: any = {};
DockerManager.builderProgress.forEach((v, k) => {
data[k] = v;
});
protocol.response(ctx, data);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});

197
daemon/src/routers/file_router.ts Executable file
View File

@ -0,0 +1,197 @@
import { $t } from "../i18n";
import * as protocol from "../service/protocol";
import { routerApp } from "../service/router";
import InstanceSubsystem from "../service/system_instance";
import { getFileManager, getWindowsDisks } from "../service/file_router_service";
import { globalConfiguration, globalEnv } from "../entity/config";
import os from "os";
// Some routers operate router authentication middleware
routerApp.use((event, ctx, data, next) => {
if (event.startsWith("file/")) {
const instanceUuid = data.instanceUuid;
if (!InstanceSubsystem.exists(instanceUuid)) {
return protocol.error(ctx, event, {
instanceUuid: instanceUuid,
err: $t("TXT_CODE_file_router.instanceNotExist", { instanceUuid: instanceUuid })
});
}
}
next();
});
// List the files in the specified instance working directory
routerApp.on("file/list", (ctx, data) => {
try {
const fileManager = getFileManager(data.instanceUuid);
const { page, pageSize, target, fileName } = data;
fileManager.cd(target);
const overview = fileManager.list(page, pageSize, fileName);
protocol.response(ctx, overview);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// File chmod (only Linux)
routerApp.on("file/chmod", async (ctx, data) => {
try {
const fileManager = getFileManager(data.instanceUuid);
const { chmod, target, deep } = data;
await fileManager.chmod(target, chmod, deep);
protocol.response(ctx, true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// Query the status of the file management system
routerApp.on("file/status", async (ctx, data) => {
try {
const instance = InstanceSubsystem.getInstance(data.instanceUuid);
if (!instance) throw new Error($t("TXT_CODE_3bfb9e04"));
protocol.response(ctx, {
instanceFileTask: instance.info.fileLock ?? 0,
globalFileTask: globalEnv.fileTaskCount ?? 0,
platform: os.platform(),
isGlobalInstance: data.instanceUuid === InstanceSubsystem.GLOBAL_INSTANCE_UUID,
disks: getWindowsDisks()
});
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// Create a new file
routerApp.on("file/touch", (ctx, data) => {
try {
const target = data.target;
const fileManager = getFileManager(data.instanceUuid);
fileManager.newFile(target);
protocol.response(ctx, true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// Create a directory
routerApp.on("file/mkdir", (ctx, data) => {
try {
const target = data.target;
const fileManager = getFileManager(data.instanceUuid);
fileManager.mkdir(target);
protocol.response(ctx, true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// copy the file
routerApp.on("file/copy", async (ctx, data) => {
try {
// [["a.txt","b.txt"],["cxz","zzz"]]
const targets = data.targets;
const fileManager = getFileManager(data.instanceUuid);
for (const target of targets) {
fileManager.copy(target[0], target[1]);
}
protocol.response(ctx, true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// move the file
routerApp.on("file/move", async (ctx, data) => {
try {
// [["a.txt","b.txt"],["cxz","zzz"]]
const targets = data.targets;
const fileManager = getFileManager(data.instanceUuid);
for (const target of targets) {
await fileManager.move(target[0], target[1]);
}
protocol.response(ctx, true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// Delete Files
routerApp.on("file/delete", async (ctx, data) => {
try {
const targets = data.targets;
const fileManager = getFileManager(data.instanceUuid);
for (const target of targets) {
// async delete
fileManager.delete(target);
}
protocol.response(ctx, true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// edit file
routerApp.on("file/edit", async (ctx, data) => {
try {
const target = data.target;
const text = data.text;
const fileManager = getFileManager(data.instanceUuid);
const result = await fileManager.edit(target, text);
protocol.response(ctx, result ? result : true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});
// compress/decompress the file
routerApp.on("file/compress", async (ctx, data) => {
const maxFileTask = globalConfiguration.config.maxFileTask;
try {
const source = data.source;
const targets = data.targets;
const type = data.type;
const code = data.code;
const fileManager = getFileManager(data.instanceUuid);
const instance = InstanceSubsystem.getInstance(data.instanceUuid);
if (!instance) throw new Error($t("TXT_CODE_3bfb9e04"));
if (instance.info.fileLock >= maxFileTask) {
throw new Error(
$t("TXT_CODE_file_router.unzipLimit", {
maxFileTask: maxFileTask,
fileLock: instance.info.fileLock
})
);
}
// Statistics of the number of tasks in a single instance file and the number of tasks in the entire daemon process
function fileTaskStart() {
if (instance) {
instance.info.fileLock++;
globalEnv.fileTaskCount++;
}
}
function fileTaskEnd() {
if (instance) {
instance.info.fileLock--;
globalEnv.fileTaskCount--;
}
}
// start decompressing or compressing the file
fileTaskStart();
try {
if (type === 1) {
await fileManager.zip(source, targets, code);
} else {
await fileManager.unzip(source, targets, code);
}
protocol.response(ctx, true);
} catch (error: any) {
throw error;
} finally {
fileTaskEnd();
}
} catch (error: any) {
protocol.responseError(ctx, error);
}
});

139
daemon/src/routers/http_router.ts Executable file
View File

@ -0,0 +1,139 @@
import { $t } from "../i18n";
import Router from "@koa/router";
import send from "koa-send";
import fs from "fs-extra";
import path from "path";
import { missionPassport } from "../service/mission_passport";
import InstanceSubsystem from "../service/system_instance";
import FileManager from "../service/system_file";
import formidable from "formidable";
import { clearUploadFiles } from "../tools/filepath";
import logger from "../service/log";
const router = new Router();
// Define the HTTP home page display route
router.all("/", async (ctx) => {
ctx.body = "[MCSManager Daemon] Status: OK | reference: https://mcsmanager.com/";
ctx.status = 200;
});
// file download route
router.get("/download/:key/:fileName", async (ctx) => {
const key = ctx.params.key;
const paramsFileName = ctx.params.fileName;
try {
// Get the task from the task center
const mission = missionPassport.getMission(key, "download");
if (!mission) throw new Error((ctx.body = "Access denied: No task found"));
const instance = InstanceSubsystem.getInstance(mission.parameter.instanceUuid);
if (!instance) throw new Error($t("TXT_CODE_http_router.instanceNotExist"));
if (!FileManager.checkFileName(paramsFileName))
throw new Error($t("TXT_CODE_http_router.fileNameNotSpec"));
const cwd = instance.absoluteCwdPath();
const fileRelativePath = mission.parameter.fileName;
// Check for file cross-directory security risks
const fileManager = new FileManager(cwd);
if (!fileManager.check(fileRelativePath))
throw new Error((ctx.body = "Access denied: Invalid destination"));
// send File
const fileAbsPath = fileManager.toAbsolutePath(fileRelativePath);
const fileDir = path.dirname(fileAbsPath);
const fileName = path.basename(fileAbsPath);
ctx.set("Content-Type", "application/octet-stream");
await send(ctx, fileName, { root: fileDir + "/", hidden: true });
} catch (error: any) {
ctx.body = $t("TXT_CODE_http_router.downloadErr", { error: error.message });
ctx.status = 500;
} finally {
missionPassport.deleteMission(key);
}
});
// File upload route
router.post("/upload/:key", async (ctx) => {
const key = String(ctx.params.key);
const unzip = Boolean(ctx.query.unzip);
const zipCode = String(ctx.query.code);
let tmpFiles: formidable.File | formidable.File[] | undefined;
try {
const mission = missionPassport.getMission(key, "upload");
if (!mission) throw new Error("Access denied: No task found");
const instance = InstanceSubsystem.getInstance(mission.parameter.instanceUuid);
if (!instance) throw new Error("Access denied: No instance found");
const uploadDir = mission.parameter.uploadDir;
const cwd = instance.absoluteCwdPath();
const tmpFiles = ctx.request.files?.file;
if (tmpFiles) {
let uploadedFile: formidable.File;
if (tmpFiles instanceof Array) {
uploadedFile = tmpFiles[0];
} else {
throw new Error("Access denied: Files must a array!");
}
const originFileName = uploadedFile.originalFilename || "";
if (!FileManager.checkFileName(path.basename(originFileName)))
throw new Error("Access denied: Malformed file name");
const fileManager = new FileManager(cwd);
const ext = path.extname(originFileName);
const basename = path.basename(originFileName, ext);
let tempFileSaveName = basename + ext;
let counter = 1;
while (
fs.existsSync(
fileManager.toAbsolutePath(path.normalize(path.join(uploadDir, tempFileSaveName)))
) &&
ctx.query.overwrite === "false"
) {
if (counter == 1) {
tempFileSaveName = `${basename}-copy${ext}`;
} else {
tempFileSaveName = `${basename}-copy-${counter}${ext}`;
}
counter++;
}
let fileSaveRelativePath = path.normalize(path.join(uploadDir, tempFileSaveName));
if (!fileManager.checkPath(fileSaveRelativePath))
throw new Error("Access denied: Invalid destination");
const fileSaveAbsolutePath = fileManager.toAbsolutePath(fileSaveRelativePath);
logger.info(
"Browser Upload File:",
fileSaveAbsolutePath,
"File size:",
Number(uploadedFile.size / 1024 / 1024).toFixed(0),
"MB"
);
await fs.move(uploadedFile.filepath, fileSaveAbsolutePath, {
overwrite: true
});
if (unzip) {
const instanceFiles = new FileManager(instance.absoluteCwdPath());
instanceFiles.unzip(fileSaveAbsolutePath, ".", zipCode);
}
ctx.body = "OK";
return;
}
ctx.body = "Access denied: No file found";
ctx.status = 500;
} catch (error: any) {
ctx.body = error.message;
ctx.status = 500;
} finally {
missionPassport.deleteMission(key);
if (tmpFiles) clearUploadFiles(tmpFiles);
}
});
export default router;

View File

@ -0,0 +1,53 @@
import * as protocol from "../service/protocol";
import { routerApp } from "../service/router";
import InstanceSubsystem from "../service/system_instance";
import Instance from "../entity/instance/instance";
import { systemInfo } from "common";
import { getVersion } from "../service/version";
import { globalConfiguration } from "../entity/config";
import i18next from "i18next";
import logger from "../service/log";
import fs from "fs-extra";
import { LOCAL_PRESET_LANG_PATH } from "../const";
import VisualDataSubsystem from "../service/system_visual_data";
// Get the basic information of the daemon system
routerApp.on("info/overview", async (ctx) => {
const daemonVersion = getVersion();
let total = 0;
let running = 0;
InstanceSubsystem.getInstances().forEach((v) => {
total++;
if (v.status() == Instance.STATUS_RUNNING) running++;
});
const info = {
version: daemonVersion,
process: {
cpu: process.cpuUsage().system,
memory: process.memoryUsage().heapUsed,
cwd: process.cwd()
},
instance: {
running,
total
},
system: systemInfo(),
cpuMemChart: VisualDataSubsystem.getSystemChartArray()
};
protocol.response(ctx, info);
});
routerApp.on("info/setting", async (ctx, data) => {
const language = String(data.language);
try {
logger.warn("Language change:", language);
i18next.changeLanguage(language);
fs.remove(LOCAL_PRESET_LANG_PATH, () => {});
globalConfiguration.config.language = language;
globalConfiguration.store();
protocol.response(ctx, true);
} catch (error: any) {
protocol.responseError(ctx, error);
}
});

View File

@ -0,0 +1,76 @@
import path from "path";
import RouterContext from "../entity/ctx";
import * as protocol from "../service/protocol";
import InstanceSubsystem from "../service/system_instance";
import fs from "fs-extra";
const MAX_LOG_SIZE = 512;
// buffer
const buffer = new Map<string, string>();
setInterval(() => {
buffer.forEach((buf, instanceUuid) => {
if (!buf || !instanceUuid) return;
const logFilePath = path.join(InstanceSubsystem.LOG_DIR, `${instanceUuid}.log`);
if (!fs.existsSync(InstanceSubsystem.LOG_DIR)) fs.mkdirsSync(InstanceSubsystem.LOG_DIR);
try {
const fileInfo = fs.statSync(logFilePath);
if (fileInfo && fileInfo.size > 1024 * MAX_LOG_SIZE) fs.removeSync(logFilePath);
} catch (err: any) {}
fs.writeFile(logFilePath, buf, { encoding: "utf-8", flag: "a" }, () => {
buffer.set(instanceUuid, "");
});
});
}, 500);
// output stream record to buffer
async function outputLog(instanceUuid: string, text: string) {
const buf = (buffer.get(instanceUuid) ?? "") + text;
if (buf.length > 1024 * 1024) buffer.set(instanceUuid, "");
buffer.set(instanceUuid, buf ?? null);
}
// instance output stream event
// By default, it is added to the data cache to control the sending rate to ensure its stability
InstanceSubsystem.on("data", (instanceUuid: string, text: string) => {
InstanceSubsystem.forEachForward(instanceUuid, (socket) => {
protocol.msg(new RouterContext(null, socket), "instance/stdout", {
instanceUuid: instanceUuid,
text: text
});
});
// Append the output to the log file
outputLog(instanceUuid, text)
.then(() => {})
.catch(() => {});
});
// instance exit event
InstanceSubsystem.on("exit", (obj: any) => {
InstanceSubsystem.forEachForward(obj.instanceUuid, (socket) => {
protocol.msg(new RouterContext(null, socket), "instance/stopped", {
instanceUuid: obj.instanceUuid,
instanceName: obj.instanceName
});
});
});
// instance start event
InstanceSubsystem.on("open", (obj: any) => {
InstanceSubsystem.forEachForward(obj.instanceUuid, (socket) => {
protocol.msg(new RouterContext(null, socket), "instance/opened", {
instanceUuid: obj.instanceUuid,
instanceName: obj.instanceName
});
});
});
// Instance failure event (usually used for startup failure, or other operation failures)
InstanceSubsystem.on("failure", (obj: any) => {
InstanceSubsystem.forEachForward(obj.instanceUuid, (socket) => {
protocol.msg(new RouterContext(null, socket), "instance/failure", {
instanceUuid: obj.instanceUuid,
instanceName: obj.instanceName
});
});
});

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