mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2025-01-31 04:46:11 +01:00
Merge branch 'dev' into bugfix/malformed-server-ping-data
This commit is contained in:
commit
f28be1a3b0
1
.gitignore
vendored
1
.gitignore
vendored
@ -38,3 +38,4 @@ docker/*
|
||||
!docker/docker-compose.yml
|
||||
lang_sort_log.txt
|
||||
lang_sort.txt
|
||||
app/migrations/status
|
||||
|
@ -5,8 +5,7 @@
|
||||
stages:
|
||||
- lint
|
||||
- test
|
||||
- prod-deployment
|
||||
- dev-deployment
|
||||
- build-and-deploy
|
||||
- release
|
||||
|
||||
variables:
|
||||
|
@ -1,81 +1,42 @@
|
||||
# yamllint disable rule:line-length
|
||||
---
|
||||
docker-build-dev:
|
||||
docker-build:
|
||||
image: docker:latest
|
||||
services:
|
||||
- name: docker:dind
|
||||
stage: dev-deployment
|
||||
stage: build-and-deploy
|
||||
tags:
|
||||
- docker_priv
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == 'dev'
|
||||
environment:
|
||||
name: development
|
||||
before_script:
|
||||
- |
|
||||
apk --no-cache add jq
|
||||
MAJOR=$(cat app/config/version.json | jq '.major' )
|
||||
MINOR=$(cat app/config/version.json | jq '.minor' )
|
||||
SUB=$(cat app/config/version.json | jq '.sub' )
|
||||
- |
|
||||
apk --no-cache add curl
|
||||
latest_tag=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | sed -Ene '/^ *"tag_name": *"(v.+)",$/s//\1/p')
|
||||
echo "Using buildx version $latest_tag"
|
||||
curl -sSLo docker-buildx "https://github.com/docker/buildx/releases/download/$latest_tag/buildx-$latest_tag.linux-amd64"
|
||||
chmod a+x docker-buildx
|
||||
mkdir -p ~/.docker/cli-plugins
|
||||
mv docker-buildx ~/.docker/cli-plugins/docker-buildx
|
||||
docker version
|
||||
- docker run --rm --privileged aptman/qus -- -r
|
||||
- docker run --rm --privileged aptman/qus -s -- -p aarch64 x86_64
|
||||
- echo $CI_JOB_TOKEN | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
|
||||
- echo $DOCKERHUB_TOKEN | docker login -u "$DOCKERHUB_USER" --password-stdin $DOCKERHUB_REGISTRY
|
||||
script:
|
||||
- |
|
||||
tag=":$CI_COMMIT_REF_SLUG"
|
||||
VERSION="${MAJOR}.${MINOR}.${SUB}"
|
||||
- |
|
||||
echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag"
|
||||
echo "Crafty Version: $VERSION"
|
||||
- docker context create tls-environment
|
||||
- docker buildx create --name zedBuilder --use tls-environment
|
||||
- docker buildx build
|
||||
--cache-from type=registry,ref="$CI_REGISTRY_IMAGE${tag}"
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1
|
||||
--build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")"
|
||||
--build-arg "BUILD_REF=${CI_COMMIT_SHA}"
|
||||
--build-arg "CRAFTY_VER=${VERSION}"
|
||||
--provenance false
|
||||
--tag "$CI_REGISTRY_IMAGE${tag}"
|
||||
--tag "arcadiatechnology/crafty-4${tag}"
|
||||
--platform linux/arm64/v8,linux/amd64
|
||||
--push .
|
||||
after_script:
|
||||
- |
|
||||
docker buildx rm zedBuilder && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance."
|
||||
docker context rm tls-environment || true
|
||||
echo "Please review multi-arch manifests are present:"
|
||||
docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"
|
||||
|
||||
docker-build-prod:
|
||||
image: docker:latest
|
||||
services:
|
||||
- name: docker:dind
|
||||
stage: prod-deployment
|
||||
tags:
|
||||
- docker_priv
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
# Development branch
|
||||
- if: $CI_COMMIT_BRANCH == 'dev'
|
||||
variables:
|
||||
ENVIRONMENT_NAME: "development"
|
||||
DOCKER_TAGS: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG arcadiatechnology/crafty-4:$CI_COMMIT_REF_SLUG"
|
||||
# Production branch (main) when not scheduled
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE != "schedule"
|
||||
variables:
|
||||
ENVIRONMENT_NAME: "production"
|
||||
# We'll set the version in the script and append stable tags
|
||||
DOCKER_TAGS: "" # We'll determine in script
|
||||
# Scheduled nightly builds on main
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
variables:
|
||||
ENVIRONMENT_NAME: "nightly"
|
||||
DOCKER_TAGS: "$CI_REGISTRY_IMAGE:nightly arcadiatechnology/crafty-4:nightly"
|
||||
|
||||
environment:
|
||||
name: production
|
||||
name: $ENVIRONMENT_NAME
|
||||
|
||||
before_script:
|
||||
- |
|
||||
apk --no-cache add jq
|
||||
MAJOR=$(cat app/config/version.json | jq '.major' )
|
||||
MINOR=$(cat app/config/version.json | jq '.minor' )
|
||||
SUB=$(cat app/config/version.json | jq '.sub' )
|
||||
apk --no-cache add jq curl
|
||||
MAJOR=$(cat app/config/version.json | jq -r '.major')
|
||||
MINOR=$(cat app/config/version.json | jq -r '.minor')
|
||||
SUB=$(cat app/config/version.json | jq -r '.sub')
|
||||
VERSION="${MAJOR}.${MINOR}.${SUB}"
|
||||
- |
|
||||
apk --no-cache add curl
|
||||
latest_tag=$(curl -s https://api.github.com/repos/docker/buildx/releases/latest | sed -Ene '/^ *"tag_name": *"(v.+)",$/s//\1/p')
|
||||
echo "Using buildx version $latest_tag"
|
||||
curl -sSLo docker-buildx "https://github.com/docker/buildx/releases/download/$latest_tag/buildx-$latest_tag.linux-amd64"
|
||||
@ -87,30 +48,61 @@ docker-build-prod:
|
||||
- docker run --rm --privileged aptman/qus -s -- -p aarch64 x86_64
|
||||
- echo $CI_JOB_TOKEN | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
|
||||
- echo $DOCKERHUB_TOKEN | docker login -u "$DOCKERHUB_USER" --password-stdin $DOCKERHUB_REGISTRY
|
||||
- docker context create tls-environment-$CI_JOB_ID
|
||||
- docker buildx create --name zedBuilder-$CI_JOB_ID --use tls-environment-$CI_JOB_ID
|
||||
|
||||
script:
|
||||
- echo "Running on branch '$CI_COMMIT_BRANCH', environment- $ENVIRONMENT_NAME"
|
||||
- echo "Crafty Version- $VERSION"
|
||||
|
||||
# If DOCKER_TAGS is empty (production default branch and not schedule), we set stable tags:
|
||||
# This scenario adds both VERSION and 'latest' tags.
|
||||
- |
|
||||
VERSION="${MAJOR}.${MINOR}.${SUB}"
|
||||
if [ "$ENVIRONMENT_NAME" = "production" ] && [ -z "$DOCKER_TAGS" ]; then
|
||||
DOCKER_TAGS="$CI_REGISTRY_IMAGE:${VERSION} \
|
||||
$CI_REGISTRY_IMAGE:latest \
|
||||
arcadiatechnology/crafty-4:${VERSION} \
|
||||
arcadiatechnology/crafty-4:latest"
|
||||
fi
|
||||
|
||||
- echo "Using the following tags- $DOCKER_TAGS"
|
||||
|
||||
# Prepare build command
|
||||
# We break DOCKER_TAGS into separate --tag arguments
|
||||
- TARGS=""
|
||||
- for t in $DOCKER_TAGS; do TARGS="$TARGS --tag $t"; done
|
||||
- echo "Tag arguments- $TARGS"
|
||||
|
||||
# Conditional build command: omit cache if schedule
|
||||
- |
|
||||
echo "Running on branch '$CI_COMMIT_BRANCH'"
|
||||
echo "Crafty Version: $VERSION"
|
||||
- docker context create tls-environment
|
||||
- docker buildx create --name zedBuilder --use tls-environment
|
||||
- docker buildx build
|
||||
--cache-from type=registry,ref="$CI_REGISTRY_IMAGE:latest"
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1
|
||||
--build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")"
|
||||
--build-arg "BUILD_REF=${CI_COMMIT_SHA}"
|
||||
--build-arg "CRAFTY_VER=${VERSION}"
|
||||
--provenance false
|
||||
--tag "$CI_REGISTRY_IMAGE:$VERSION"
|
||||
--tag "$CI_REGISTRY_IMAGE:latest"
|
||||
--tag "arcadiatechnology/crafty-4:$VERSION"
|
||||
--tag "arcadiatechnology/crafty-4:latest"
|
||||
--platform linux/arm64/v8,linux/amd64
|
||||
if [ "$CI_PIPELINE_SOURCE" = "schedule" ]; then
|
||||
echo "Omitting cache for nightly build."
|
||||
docker buildx build \
|
||||
--build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" \
|
||||
--build-arg "BUILD_REF=${CI_COMMIT_SHA}" \
|
||||
--build-arg "CRAFTY_VER=${VERSION}" \
|
||||
--provenance false \
|
||||
$TARGS \
|
||||
--platform linux/arm64/v8,linux/amd64 \
|
||||
--push .
|
||||
else
|
||||
echo "Using cache for build."
|
||||
docker buildx build \
|
||||
--cache-from type=registry,ref="$CI_REGISTRY_IMAGE:dev" \
|
||||
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
||||
--build-arg "BUILD_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")" \
|
||||
--build-arg "BUILD_REF=${CI_COMMIT_SHA}" \
|
||||
--build-arg "CRAFTY_VER=${VERSION}" \
|
||||
--provenance false \
|
||||
$TARGS \
|
||||
--platform linux/arm64/v8,linux/amd64 \
|
||||
--push .
|
||||
fi
|
||||
|
||||
after_script:
|
||||
- |
|
||||
docker buildx rm zedBuilder && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance."
|
||||
docker context rm tls-environment || true
|
||||
echo "Please review multi-arch manifests are present:"
|
||||
docker buildx imagetools inspect "$CI_REGISTRY_IMAGE${tag}"
|
||||
- docker buildx rm zedBuilder-$CI_JOB_ID && echo "Successfully Stopped builder instance" || echo "Failed to stop builder instance."
|
||||
- docker context rm tls-environment-$CI_JOB_ID || true
|
||||
- echo "Please review multi-arch manifests are present:"
|
||||
- if [ "$ENVIRONMENT_NAME" = "development" ]; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG"; fi
|
||||
- if [ "$ENVIRONMENT_NAME" = "production" ] && [ -n "$VERSION" ]; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:$VERSION"; fi
|
||||
- if [ "$ENVIRONMENT_NAME" = "nightly" ]; then docker buildx imagetools inspect "$CI_REGISTRY_IMAGE:nightly"; fi
|
||||
|
@ -9,6 +9,8 @@ yamllint:
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH"
|
||||
script:
|
||||
- yamllint .
|
||||
@ -22,6 +24,8 @@ jsonlint:
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH"
|
||||
script:
|
||||
- |
|
||||
@ -37,6 +41,8 @@ black:
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH"
|
||||
script:
|
||||
- black --check --verbose -- .
|
||||
@ -50,10 +56,12 @@ pylint:
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH"
|
||||
before_script:
|
||||
- apk update
|
||||
- apk add gcc python3-dev linux-headers build-base
|
||||
- apk add gcc python3-dev linux-headers build-base rust cargo
|
||||
- pip3 install --no-cache-dir -r requirements.txt
|
||||
script:
|
||||
- pylint --exit-zero --load-plugins=pylint_gitlab --output-format=gitlab-codeclimate:codeclimate.json $(find -type f -name "*.py" ! -path "**/.venv/**" ! -path "**/app/migrations/**")
|
||||
@ -75,6 +83,8 @@ sonarcloud-check:
|
||||
when: never
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH"
|
||||
variables:
|
||||
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
|
||||
@ -85,26 +95,28 @@ sonarcloud-check:
|
||||
- .sonar/cache
|
||||
script:
|
||||
- sonar-scanner
|
||||
|
||||
# Lang file checking
|
||||
lang-check:
|
||||
stage: lint
|
||||
image: alpine:latest
|
||||
tags:
|
||||
- saas-linux-medium-amd64
|
||||
rules:
|
||||
- if: "$CODE_QUALITY_DISABLED"
|
||||
when: never
|
||||
- if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH"
|
||||
allow_failure: true
|
||||
before_script:
|
||||
- apk add --no-cache jq bash
|
||||
script:
|
||||
- chmod +x .gitlab/scripts/lang_sort.sh
|
||||
- bash .gitlab/scripts/lang_sort.sh ./app/translations/
|
||||
after_script:
|
||||
- if [ -f .gitlab/scripts/lang_sort_log.txt ]; then cat .gitlab/scripts/lang_sort_log.txt; fi
|
||||
artifacts:
|
||||
paths:
|
||||
- .gitlab/scripts/lang_sort_log.txt
|
||||
expire_in: 1 week
|
||||
# lang-check:
|
||||
# stage: lint
|
||||
# image: alpine:latest
|
||||
# tags:
|
||||
# - saas-linux-medium-amd64
|
||||
# rules:
|
||||
# - if: "$CODE_QUALITY_DISABLED"
|
||||
# when: never
|
||||
# - if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
# when: never
|
||||
# - if: "$CI_COMMIT_TAG || $CI_COMMIT_BRANCH"
|
||||
# allow_failure: true
|
||||
# before_script:
|
||||
# - apk add --no-cache jq bash
|
||||
# script:
|
||||
# - chmod +x .gitlab/scripts/lang_sort.sh
|
||||
# - bash .gitlab/scripts/lang_sort.sh ./app/translations/
|
||||
# after_script:
|
||||
# - if [ -f .gitlab/scripts/lang_sort_log.txt ]; then cat .gitlab/scripts/lang_sort_log.txt; fi
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - .gitlab/scripts/lang_sort_log.txt
|
||||
# expire_in: 1 week
|
||||
# DISABLED - As Weblate managed.
|
||||
|
@ -4,6 +4,8 @@ release:
|
||||
stage: release
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:latest
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: $CI_COMMIT_TAG
|
||||
needs:
|
||||
- job: win-prod-build
|
||||
|
@ -1,13 +1,15 @@
|
||||
# yamllint disable rule:line-length
|
||||
---
|
||||
win-dev-build:
|
||||
stage: dev-deployment
|
||||
stage: build-and-deploy
|
||||
tags:
|
||||
- win64
|
||||
cache:
|
||||
paths:
|
||||
- .venv/
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: "$CI_COMMIT_BRANCH == 'dev'"
|
||||
environment:
|
||||
name: development
|
||||
@ -48,13 +50,15 @@ win-dev-build:
|
||||
- app\classes\**\*
|
||||
|
||||
win-prod-build:
|
||||
stage: prod-deployment
|
||||
stage: build-and-deploy
|
||||
tags:
|
||||
- win64
|
||||
cache:
|
||||
paths:
|
||||
- .venv/
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
|
||||
- if: $CI_COMMIT_TAG
|
||||
environment:
|
||||
|
25
CHANGELOG.md
25
CHANGELOG.md
@ -1,13 +1,30 @@
|
||||
# Changelog
|
||||
## --- [4.4.4] - 2024/TBD
|
||||
## --- [4.4.5] - 2024/TBD
|
||||
### New features
|
||||
TBD
|
||||
### Refactor
|
||||
- Refactor and standardize all JSON validator errors returning human readable translations ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/786))
|
||||
- Improve docker-build CI/CD, supporting nightly builds ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/813))
|
||||
### Bug fixes
|
||||
TBD
|
||||
- Bump requests to resolve yank for CVE-2024-35195 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/808))
|
||||
### Tweaks
|
||||
TBD
|
||||
- Bump Docker base image `22.04` -> `24.04` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812))
|
||||
- Bump python pip `2.0.3` -> `24.3.1` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812))
|
||||
- Bump python setuptools `50.3.2` -> `75.6.0` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/812))
|
||||
- Bump tornado for CVE-2024-52804 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/814))
|
||||
### Lang
|
||||
TBD
|
||||
- Weblate Translation Platform Integration
|
||||
- Remove incomplete labels from translation files to better support new translation workflow ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/810))
|
||||
- New langs added `ja_JP`, `ko_KR` ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/811))
|
||||
<br><br>
|
||||
|
||||
## --- [4.4.4] - 2024/10/03
|
||||
### Bug fixes
|
||||
- Migrations | Fix orphan schedule configurations crashing migration operation ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/796))
|
||||
- Fix logic issue causing bedrock wizard's root files buttons to not respond to user click events ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/797))
|
||||
- Reset crash detection counter after crash detection process detects successful start ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/798))
|
||||
- Update new bedrock DL url and correctly bubble up exception on DL fail - Thanks @sarcastron ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/802))
|
||||
- Bump cryptography for GHSA-h4gh-qq45-vh27 ([Merge Request](https://gitlab.com/crafty-controller/crafty-4/-/merge_requests/803))
|
||||
<br><br>
|
||||
|
||||
## --- [4.4.3] - 2024/08/08
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:22.04
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
@ -36,7 +36,7 @@ WORKDIR /crafty
|
||||
COPY --chown=crafty:root requirements.txt ./
|
||||
RUN python3 -m venv ./.venv \
|
||||
&& . .venv/bin/activate \
|
||||
&& pip3 install --no-cache-dir --upgrade setuptools==50.3.2 pip==22.0.3 \
|
||||
&& pip3 install --no-cache-dir --upgrade setuptools==75.6.0 pip==24.3.1 \
|
||||
&& pip3 install --no-cache-dir -r requirements.txt \
|
||||
&& deactivate
|
||||
USER root
|
||||
|
@ -1,5 +1,5 @@
|
||||
[![Crafty Logo](app/frontend/static/assets/images/logo_long.svg)](https://craftycontrol.com)
|
||||
# Crafty Controller 4.4.4
|
||||
# Crafty Controller 4.4.5
|
||||
> Python based Control Panel for your Minecraft Server
|
||||
|
||||
## What is Crafty Controller?
|
||||
|
@ -37,9 +37,16 @@ class UsersController:
|
||||
permission.name
|
||||
for permission in PermissionsCrafty.get_permissions_list()
|
||||
],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
},
|
||||
"quantity": {"type": "number", "minimum": -1},
|
||||
"enabled": {"type": "boolean"},
|
||||
"quantity": {
|
||||
"type": "number",
|
||||
"minimum": -1,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"enabled": {"type": "boolean", "error": "typeBool", "fill": True},
|
||||
}
|
||||
self.user_jsonschema_props: t.Final = {
|
||||
"username": {
|
||||
@ -49,6 +56,8 @@ class UsersController:
|
||||
"pattern": "^[a-z0-9_]+$",
|
||||
"examples": ["admin"],
|
||||
"title": "Username",
|
||||
"error": "userName",
|
||||
"fill": True,
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
@ -62,11 +71,15 @@ class UsersController:
|
||||
"format": "email",
|
||||
"examples": ["default@example.com"],
|
||||
"title": "E-Mail",
|
||||
"error": "typeEmail",
|
||||
"fill": True,
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"examples": [True],
|
||||
"title": "Enabled",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"lang": {
|
||||
"type": "string",
|
||||
@ -74,16 +87,30 @@ class UsersController:
|
||||
"minLength": 2,
|
||||
"examples": ["en"],
|
||||
"title": "Language",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"superuser": {
|
||||
"type": "boolean",
|
||||
"examples": [False],
|
||||
"title": "Superuser",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"manager": {
|
||||
"type": ["integer", "null"],
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"theme": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"manager": {"type": ["integer", "null"]},
|
||||
"theme": {"type": "string"},
|
||||
"permissions": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": _permissions_props,
|
||||
@ -92,13 +119,25 @@ class UsersController:
|
||||
},
|
||||
"roles": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"minLength": 1,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"hints": {"type": "boolean"},
|
||||
"server_order": {"type": "string"},
|
||||
"hints": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"server_order": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
}
|
||||
|
||||
# **********************************************************************************
|
||||
|
@ -58,6 +58,7 @@ class Helpers:
|
||||
|
||||
def __init__(self):
|
||||
self.root_dir = os.path.abspath(os.path.curdir)
|
||||
self.read_annc = False
|
||||
self.config_dir = os.path.join(self.root_dir, "app", "config")
|
||||
self.webroot = os.path.join(self.root_dir, "app", "frontend")
|
||||
self.servers_dir = os.path.join(self.root_dir, "servers")
|
||||
@ -79,6 +80,7 @@ class Helpers:
|
||||
|
||||
self.translation = Translation(self)
|
||||
self.update_available = False
|
||||
self.migration_notifications = []
|
||||
self.ignored_names = ["crafty_managed.txt", "db_stats"]
|
||||
self.crafty_starting = False
|
||||
self.minimum_password_length = 8
|
||||
@ -128,24 +130,33 @@ class Helpers:
|
||||
"Chrome/104.0.0.0 Safari/537.36"
|
||||
),
|
||||
}
|
||||
target_win = 'https://minecraft.azureedge.net/bin-win/[^"]*'
|
||||
target_linux = 'https://minecraft.azureedge.net/bin-linux/[^"]*'
|
||||
|
||||
target_win = 'https://www.minecraft.net/bedrockdedicatedserver/bin-win/[^"]*'
|
||||
target_linux = (
|
||||
'https://www.minecraft.net/bedrockdedicatedserver/bin-linux/[^"]*'
|
||||
)
|
||||
try:
|
||||
# Get minecraft server download page
|
||||
# (hopefully the don't change the structure)
|
||||
download_page = get(url, headers=headers, timeout=1)
|
||||
|
||||
download_page.raise_for_status()
|
||||
# Search for our string targets
|
||||
win_download_url = re.search(target_win, download_page.text).group(0)
|
||||
linux_download_url = re.search(target_linux, download_page.text).group(0)
|
||||
win_search_result = re.search(target_win, download_page.text)
|
||||
linux_search_result = re.search(target_linux, download_page.text)
|
||||
if win_search_result is None or linux_search_result is None:
|
||||
raise RuntimeError(
|
||||
"Could not determine download URL from minecraft.net."
|
||||
)
|
||||
|
||||
win_download_url = win_search_result.group(0)
|
||||
linux_download_url = linux_search_result.group(0)
|
||||
print(win_download_url, linux_download_url)
|
||||
if os.name == "nt":
|
||||
return win_download_url
|
||||
|
||||
return linux_download_url
|
||||
except Exception as e:
|
||||
logger.error(f"Unable to resolve remote bedrock download url! \n{e}")
|
||||
raise e
|
||||
return False
|
||||
|
||||
def get_execution_java(self, value, execution_command):
|
||||
@ -614,11 +625,49 @@ class Helpers:
|
||||
|
||||
return version_data
|
||||
|
||||
def get_announcements(self):
|
||||
def check_migrations(self) -> None:
|
||||
if self.read_annc is False:
|
||||
self.read_annc = True
|
||||
for file in os.listdir(
|
||||
os.path.join(self.root_dir, "app", "migrations", "status")
|
||||
):
|
||||
with open(
|
||||
os.path.join(self.root_dir, "app", "migrations", "status", file),
|
||||
"r",
|
||||
encoding="utf-8",
|
||||
) as notif_file:
|
||||
file_json = json.load(notif_file)
|
||||
for notif in file_json:
|
||||
if not file_json[notif].get("status"):
|
||||
self.migration_notifications.append(file_json[notif])
|
||||
|
||||
def get_announcements(self, lang=None):
|
||||
try:
|
||||
data = []
|
||||
response = requests.get("https://craftycontrol.com/notify", timeout=2)
|
||||
data = json.loads(response.content)
|
||||
if not lang:
|
||||
lang = self.get_setting("language")
|
||||
self.check_migrations()
|
||||
for migration_warning in self.migration_notifications:
|
||||
if not migration_warning.get("status"):
|
||||
data.append(
|
||||
{
|
||||
"id": migration_warning.get("pid"),
|
||||
"title": self.translation.translate(
|
||||
"notify",
|
||||
f"{migration_warning.get('type')}_title",
|
||||
lang,
|
||||
),
|
||||
"date": "",
|
||||
"desc": self.translation.translate(
|
||||
"notify",
|
||||
f"{migration_warning.get('type')}_desc",
|
||||
lang,
|
||||
),
|
||||
"link": "",
|
||||
}
|
||||
)
|
||||
if self.update_available:
|
||||
data.append(self.update_available)
|
||||
return data
|
||||
|
@ -217,15 +217,16 @@ class ImportHelpers:
|
||||
FileHelpers.del_dirs(temp_dir)
|
||||
|
||||
def download_bedrock_server(self, path, new_id):
|
||||
bedrock_url = Helpers.get_latest_bedrock_url()
|
||||
download_thread = threading.Thread(
|
||||
target=self.download_threaded_bedrock_server,
|
||||
daemon=True,
|
||||
args=(path, new_id),
|
||||
args=(path, new_id, bedrock_url),
|
||||
name=f"{new_id}_download",
|
||||
)
|
||||
download_thread.start()
|
||||
|
||||
def download_threaded_bedrock_server(self, path, new_id):
|
||||
def download_threaded_bedrock_server(self, path, new_id, bedrock_url):
|
||||
"""
|
||||
Downloads the latest Bedrock server, unzips it, sets necessary permissions.
|
||||
|
||||
@ -236,10 +237,8 @@ class ImportHelpers:
|
||||
This method handles exceptions and logs errors for each step of the process.
|
||||
"""
|
||||
try:
|
||||
bedrock_url = Helpers.get_latest_bedrock_url()
|
||||
if bedrock_url:
|
||||
file_path = os.path.join(path, "bedrock_server.zip")
|
||||
|
||||
success = FileHelpers.ssl_get_file(
|
||||
bedrock_url, path, "bedrock_server.zip"
|
||||
)
|
||||
@ -263,6 +262,7 @@ class ImportHelpers:
|
||||
logger.critical(
|
||||
f"Failed to download bedrock executable during server creation! \n{e}"
|
||||
)
|
||||
raise e
|
||||
|
||||
ServersController.finish_import(new_id)
|
||||
server_users = PermissionsServers.get_server_user_list(new_id)
|
||||
|
@ -1053,8 +1053,10 @@ class ServerInstance:
|
||||
|
||||
running = self.check_running()
|
||||
|
||||
# if all is okay, we just exit out
|
||||
# if all is okay, we set the restart count to 0 and just exit out
|
||||
if running:
|
||||
Console.debug("Successfully found process. Resetting crash counter to 0")
|
||||
self.restart_count = 0
|
||||
return
|
||||
# check the exit code -- This could be a fix for /stop
|
||||
if str(self.process.returncode) in self.settings["ignored_exits"].split(","):
|
||||
|
@ -11,7 +11,14 @@ class BaseApiHandler(BaseHandler):
|
||||
|
||||
# {{{ 405 Method Not Allowed as JSON
|
||||
def _unimplemented_method(self, *_args: str, **_kwargs: str) -> None:
|
||||
self.finish_json(405, {"status": "error", "error": "METHOD_NOT_ALLOWED"})
|
||||
self.finish_json(
|
||||
405,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "METHOD_NOT_ALLOWED",
|
||||
"error_data": "METHOD NOT ALLOWED",
|
||||
},
|
||||
)
|
||||
|
||||
head = _unimplemented_method # type: Callable[..., Optional[Awaitable[None]]]
|
||||
get = _unimplemented_method # type: Callable[..., Optional[Awaitable[None]]]
|
||||
|
@ -977,6 +977,8 @@ class PanelHandler(BaseHandler):
|
||||
for file in sorted(
|
||||
os.listdir(os.path.join(self.helper.root_dir, "app", "translations"))
|
||||
):
|
||||
if file == "humanized_index.json":
|
||||
continue
|
||||
if file.endswith(".json"):
|
||||
if file.split(".")[0] not in self.helper.get_setting(
|
||||
"disabled_language_files"
|
||||
|
@ -261,7 +261,11 @@ class PublicHandler(BaseHandler):
|
||||
)
|
||||
return self.finish_json(
|
||||
403,
|
||||
{"status": "error", "error": error_msg},
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID CREDENTIALS",
|
||||
"error_data": error_msg,
|
||||
},
|
||||
)
|
||||
else:
|
||||
self.redirect("/login?")
|
||||
|
@ -68,7 +68,12 @@ class ApiAuthLoginHandler(BaseApiHandler):
|
||||
)
|
||||
return self.finish_json(
|
||||
401,
|
||||
{"status": "error", "error": "INCORRECT_CREDENTIALS", "token": None},
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INCORRECT_CREDENTIALS",
|
||||
"error_data": "INVALID CREDENTIALS",
|
||||
"token": None,
|
||||
},
|
||||
)
|
||||
|
||||
if not user_data.enabled:
|
||||
@ -78,7 +83,13 @@ class ApiAuthLoginHandler(BaseApiHandler):
|
||||
f" IP {self.get_remote_ip()} account disabled"
|
||||
)
|
||||
self.finish_json(
|
||||
403, {"status": "error", "error": "ACCOUNT_DISABLED", "token": None}
|
||||
403,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "ACCOUNT_DISABLED",
|
||||
"error_data": "ACCOUNT DISABLED",
|
||||
"token": None,
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
@ -123,5 +134,9 @@ class ApiAuthLoginHandler(BaseApiHandler):
|
||||
)
|
||||
self.finish_json(
|
||||
401,
|
||||
{"status": "error", "error": "INCORRECT_CREDENTIALS"},
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INCORRECT_CREDENTIALS",
|
||||
"error_data": "INCORRECT CREDENTIALS",
|
||||
},
|
||||
)
|
||||
|
@ -29,7 +29,7 @@ class ApiAnnounceIndexHandler(BaseApiHandler):
|
||||
_,
|
||||
) = auth_data
|
||||
|
||||
data = self.helper.get_announcements()
|
||||
data = self.helper.get_announcements(auth_data[4]["lang"])
|
||||
if not data:
|
||||
return self.finish_json(
|
||||
424,
|
||||
@ -115,7 +115,14 @@ class ApiAnnounceIndexHandler(BaseApiHandler):
|
||||
if str(data["id"]) in str(res):
|
||||
cleared_notifs.append(data["id"])
|
||||
else:
|
||||
self.finish_json(200, {"status": "error", "error": "INVALID_DATA"})
|
||||
self.finish_json(
|
||||
200,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_DATA",
|
||||
"error_data": "INVALID NOTIFICATION ID",
|
||||
},
|
||||
)
|
||||
return
|
||||
updata = {"cleared_notifs": ",".join(cleared_notifs)}
|
||||
self.controller.users.update_user(auth_data[4]["user_id"], updata)
|
||||
|
@ -18,7 +18,16 @@ class ApiCraftyLogIndexHandler(BaseApiHandler):
|
||||
) = auth_data
|
||||
|
||||
if not superuser:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
log_types = ["audit", "session", "schedule"]
|
||||
if log_type not in log_types:
|
||||
|
@ -9,29 +9,111 @@ from app.classes.web.base_api_handler import BaseApiHandler
|
||||
config_json_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"https_port": {"type": "integer"},
|
||||
"https_port": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"language": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"cookie_expire": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"show_errors": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"history_max_age": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"stats_update_frequency_seconds": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"delete_default_json": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"show_contribute_link": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"virtual_terminal_lines": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"max_log_lines": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"max_audit_entries": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"disabled_language_files": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
},
|
||||
"stream_size_GB": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"keywords": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
},
|
||||
"allow_nsfw_profile_pictures": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"enable_user_self_delete": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"reset_secrets_on_next_boot": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"monitored_mounts": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
},
|
||||
"dir_size_poll_freq_minutes": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"crafty_logs_delete_after_days": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"big_bucket_repo": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"cookie_expire": {"type": "integer"},
|
||||
"show_errors": {"type": "boolean"},
|
||||
"history_max_age": {"type": "integer"},
|
||||
"stats_update_frequency_seconds": {"type": "integer"},
|
||||
"delete_default_json": {"type": "boolean"},
|
||||
"show_contribute_link": {"type": "boolean"},
|
||||
"virtual_terminal_lines": {"type": "integer"},
|
||||
"max_log_lines": {"type": "integer"},
|
||||
"max_audit_entries": {"type": "integer"},
|
||||
"disabled_language_files": {"type": "array"},
|
||||
"stream_size_GB": {"type": "integer"},
|
||||
"keywords": {"type": "array"},
|
||||
"allow_nsfw_profile_pictures": {"type": "boolean"},
|
||||
"enable_user_self_delete": {"type": "boolean"},
|
||||
"reset_secrets_on_next_boot": {"type": "boolean"},
|
||||
"monitored_mounts": {"type": "array"},
|
||||
"dir_size_poll_freq_minutes": {"type": "integer"},
|
||||
"crafty_logs_delete_after_days": {"type": "integer"},
|
||||
"big_bucket_repo": {"type": "string"},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -39,8 +121,16 @@ config_json_schema = {
|
||||
customize_json_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"photo": {"type": "string"},
|
||||
"opacity": {"type": "string"},
|
||||
"photo": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"opacity": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -49,7 +139,11 @@ customize_json_schema = {
|
||||
photo_delete_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"photo": {"type": "string"},
|
||||
"photo": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -75,7 +169,16 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler):
|
||||
get_only_ids = self.get_query_argument("ids", None) == "true"
|
||||
|
||||
if not superuser:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.finish_json(
|
||||
200,
|
||||
@ -98,24 +201,42 @@ class ApiCraftyConfigIndexHandler(BaseApiHandler):
|
||||
(_, _, _, superuser, user, _) = auth_data
|
||||
|
||||
if not superuser:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
data = orjson.loads(self.request.body)
|
||||
except orjson.JSONDecodeError as e:
|
||||
except orjson.JSONDecodeError as why:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
||||
400,
|
||||
{"status": "error", "error": "INVALID_JSON", "error_data": str(why)},
|
||||
)
|
||||
|
||||
try:
|
||||
validate(data, config_json_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
@ -152,7 +273,16 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler):
|
||||
get_only_ids = self.get_query_argument("ids", None) == "true"
|
||||
|
||||
if not superuser:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.finish_json(
|
||||
200,
|
||||
@ -181,7 +311,16 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler):
|
||||
_,
|
||||
) = auth_data
|
||||
if not superuser:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
data = orjson.loads(self.request.body)
|
||||
@ -247,7 +386,16 @@ class ApiCraftyCustomizeIndexHandler(BaseApiHandler):
|
||||
return
|
||||
|
||||
if not auth_data[4]["superuser"]:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
|
@ -6,7 +6,7 @@ from app.classes.web.base_api_handler import BaseApiHandler
|
||||
server_dir_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"new_dir": {"type": "string"},
|
||||
"new_dir": {"type": "string", "error": "typeString"},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -31,7 +31,16 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler):
|
||||
get_only_ids = self.get_query_argument("ids", None) == "true"
|
||||
|
||||
if not superuser:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.finish_json(
|
||||
200,
|
||||
@ -61,29 +70,52 @@ class ApiCraftyConfigServerDirHandler(BaseApiHandler):
|
||||
) = auth_data
|
||||
|
||||
if not auth_data:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": "NOT AUTHORIZED",
|
||||
},
|
||||
)
|
||||
|
||||
if not auth_data[4]["superuser"]:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
if self.helper.is_env_docker():
|
||||
raise NotImplementedError
|
||||
|
||||
try:
|
||||
data = orjson.loads(self.request.body)
|
||||
except orjson.JSONDecodeError as e:
|
||||
except orjson.JSONDecodeError as why:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_JSON", "error_data": str(e)}
|
||||
400,
|
||||
{"status": "error", "error": "INVALID_JSON", "error_data": str(why)},
|
||||
)
|
||||
|
||||
try:
|
||||
validate(data, server_dir_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {offending_key}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
if self.helper.dir_migration:
|
||||
|
@ -16,7 +16,14 @@ class ApiCraftyJarCacheIndexHandler(BaseApiHandler):
|
||||
) = auth_data
|
||||
|
||||
if not auth_data[4]["superuser"]:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": "NOT A SUPER USER",
|
||||
},
|
||||
)
|
||||
|
||||
self.controller.big_bucket.manual_refresh_cache()
|
||||
self.finish_json(
|
||||
|
@ -13,10 +13,25 @@ logger = logging.getLogger(__name__)
|
||||
files_get_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {"type": "string", "minLength": 1},
|
||||
"folder": {"type": "string"},
|
||||
"upload": {"type": "boolean", "default": "False"},
|
||||
"unzip": {"type": "boolean", "default": "True"},
|
||||
"page": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "filesPageLen",
|
||||
"fill": True,
|
||||
},
|
||||
"folder": {"type": "string", "error": "typeString", "fill": True},
|
||||
"upload": {
|
||||
"type": "boolean",
|
||||
"default": "False",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"unzip": {
|
||||
"type": "boolean",
|
||||
"default": "True",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -37,7 +52,14 @@ class ApiImportFilesIndexHandler(BaseApiHandler):
|
||||
and not auth_data[4]["superuser"]
|
||||
):
|
||||
# if the user doesn't have Files or Backup permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": "INSUFFICEN PERMISSIONS",
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
@ -47,13 +69,21 @@ class ApiImportFilesIndexHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, files_get_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
# TODO: limit some columns for specific permissions?
|
||||
|
@ -47,7 +47,14 @@ class ApiFilesUploadHandler(BaseApiHandler):
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "NOT_AUTHORIZED"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
@ -60,7 +67,14 @@ class ApiFilesUploadHandler(BaseApiHandler):
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "NOT_AUTHORIZED"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
u_type = "server_upload"
|
||||
@ -111,9 +125,9 @@ class ApiFilesUploadHandler(BaseApiHandler):
|
||||
try:
|
||||
file_size = int(self.request.headers.get("fileSize", None))
|
||||
total_chunks = int(self.request.headers.get("totalChunks", 0))
|
||||
except TypeError:
|
||||
except TypeError as why:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "TYPE ERROR", "data": {}}
|
||||
400, {"status": "error", "error": "TYPE ERROR", "error_data": {why}}
|
||||
)
|
||||
self.chunk_index = self.request.headers.get("chunkId")
|
||||
if u_type == "server_upload":
|
||||
|
@ -6,7 +6,12 @@ class ApiNotFoundHandler(BaseApiHandler):
|
||||
def _not_found(self, page: str) -> None:
|
||||
self.finish_json(
|
||||
404,
|
||||
{"status": "error", "error": "API_HANDLER_NOT_FOUND", "page": page},
|
||||
{
|
||||
"status": "error",
|
||||
"error": "API_HANDLER_NOT_FOUND",
|
||||
"error_data": f"{page} not found",
|
||||
"page": page,
|
||||
},
|
||||
)
|
||||
|
||||
head = _not_found # type: Callable[..., Optional[Awaitable[None]]]
|
||||
|
@ -12,25 +12,30 @@ create_role_schema = {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": r"^[^,\[\]]*$",
|
||||
"error": "roleName",
|
||||
},
|
||||
"servers": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"server_id": {
|
||||
"type": "string",
|
||||
"minimum": 1,
|
||||
"error": "roleServerId",
|
||||
},
|
||||
"permissions": {
|
||||
"type": "string",
|
||||
"pattern": r"^[01]{8}$", # 8 bits, see EnumPermissionsServer
|
||||
"error": "roleServerPerms",
|
||||
},
|
||||
},
|
||||
"required": ["server_id", "permissions"],
|
||||
},
|
||||
},
|
||||
"manager": {"type": ["integer", "null"]},
|
||||
"manager": {"type": ["integer", "null"], "error": "roleManager"},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -42,19 +47,24 @@ basic_create_role_schema = {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "roleName",
|
||||
},
|
||||
"servers": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"server_id": {
|
||||
"type": "string",
|
||||
"minimum": 1,
|
||||
"error": "roleServerId",
|
||||
},
|
||||
"permissions": {
|
||||
"type": "string",
|
||||
"pattern": "^[01]{8}$", # 8 bits, see EnumPermissionsServer
|
||||
"pattern": r"^[01]{8}$", # 8 bits, see EnumPermissionsServer
|
||||
"error": "roleServerPerms",
|
||||
},
|
||||
},
|
||||
"required": ["server_id", "permissions"],
|
||||
@ -87,7 +97,16 @@ class ApiRolesIndexHandler(BaseApiHandler):
|
||||
not superuser
|
||||
and EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_permissions_crafty
|
||||
):
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.finish_json(
|
||||
200,
|
||||
@ -120,7 +139,16 @@ class ApiRolesIndexHandler(BaseApiHandler):
|
||||
not superuser
|
||||
and EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_permissions_crafty
|
||||
):
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
data = orjson.loads(self.request.body)
|
||||
@ -134,13 +162,21 @@ class ApiRolesIndexHandler(BaseApiHandler):
|
||||
validate(data, create_role_schema)
|
||||
else:
|
||||
validate(data, basic_create_role_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
@ -165,7 +201,12 @@ class ApiRolesIndexHandler(BaseApiHandler):
|
||||
|
||||
if self.controller.roles.get_roleid_by_name(role_name) is not None:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "ROLE_NAME_ALREADY_EXISTS"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "ROLE_NAME_ALREADY_EXISTS",
|
||||
"error_data": "UNIQUE VALUE ERROR",
|
||||
},
|
||||
)
|
||||
|
||||
role_id = self.controller.roles.add_role_advanced(role_name, servers, manager)
|
||||
|
@ -11,25 +11,30 @@ modify_role_schema = {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"pattern": r"^[^,\[\]]*$",
|
||||
"error": "roleName",
|
||||
},
|
||||
"servers": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"server_id": {
|
||||
"type": "string",
|
||||
"minimum": 1,
|
||||
"error": "roleServerId",
|
||||
},
|
||||
"permissions": {
|
||||
"type": "string",
|
||||
"pattern": r"^[01]{8}$", # 8 bits, see EnumPermissionsServer
|
||||
"error": "roleServerPerms",
|
||||
},
|
||||
},
|
||||
"required": ["server_id", "permissions"],
|
||||
},
|
||||
},
|
||||
"manager": {"type": ["integer", "null"]},
|
||||
"manager": {"type": ["integer", "null"], "error": "roleManager"},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -41,19 +46,24 @@ basic_modify_role_schema = {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "roleName",
|
||||
},
|
||||
"servers": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"server_id": {
|
||||
"type": "string",
|
||||
"minimum": 1,
|
||||
"error": "roleServerId",
|
||||
},
|
||||
"permissions": {
|
||||
"type": "string",
|
||||
"pattern": "^[01]{8}$", # 8 bits, see EnumPermissionsServer
|
||||
"pattern": r"^[01]{8}$", # 8 bits, see EnumPermissionsServer
|
||||
"error": "roleServerPerms",
|
||||
},
|
||||
},
|
||||
"required": ["server_id", "permissions"],
|
||||
@ -83,15 +93,26 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
|
||||
not superuser
|
||||
and EnumPermissionsCrafty.ROLES_CONFIG not in exec_user_permissions_crafty
|
||||
):
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
self.finish_json(
|
||||
200,
|
||||
{"status": "ok", "data": self.controller.roles.get_role(role_id)},
|
||||
)
|
||||
except DoesNotExist:
|
||||
self.finish_json(404, {"status": "error", "error": "ROLE_NOT_FOUND"})
|
||||
except DoesNotExist as why:
|
||||
self.finish_json(
|
||||
404, {"status": "error", "error": "ROLE_NOT_FOUND", "error_data": why}
|
||||
)
|
||||
|
||||
def delete(self, role_id: str):
|
||||
auth_data = self.authenticate_user()
|
||||
@ -110,7 +131,16 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
|
||||
str(role.get("manager", "no manager found")) != str(auth_data[4]["user_id"])
|
||||
and not superuser
|
||||
):
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.controller.roles.remove_role(role_id)
|
||||
|
||||
@ -165,13 +195,21 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
|
||||
validate(data, modify_role_schema)
|
||||
else:
|
||||
validate(data, basic_modify_role_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
@ -188,11 +226,13 @@ class ApiRolesRoleIndexHandler(BaseApiHandler):
|
||||
data.get("servers", None),
|
||||
manager,
|
||||
)
|
||||
except DoesNotExist:
|
||||
return self.finish_json(404, {"status": "error", "error": "ROLE_NOT_FOUND"})
|
||||
except IntegrityError:
|
||||
except DoesNotExist as why:
|
||||
return self.finish_json(
|
||||
404, {"status": "error", "error": "ROLE_NAME_EXISTS"}
|
||||
404, {"status": "error", "error": "ROLE_NOT_FOUND", "error_data": why}
|
||||
)
|
||||
except IntegrityError as why:
|
||||
return self.finish_json(
|
||||
404, {"status": "error", "error": "ROLE_NAME_EXISTS", "error_data": why}
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
user["user_id"],
|
||||
|
@ -20,7 +20,16 @@ class ApiRolesRoleServersHandler(BaseApiHandler):
|
||||
get_only_ids = self.get_query_argument("ids", None) == "true"
|
||||
|
||||
if not superuser:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.finish_json(
|
||||
200,
|
||||
|
@ -16,7 +16,16 @@ class ApiRolesRoleUsersHandler(BaseApiHandler):
|
||||
) = auth_data
|
||||
|
||||
if not superuser:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
all_user_ids = self.controller.users.get_all_user_ids()
|
||||
|
||||
|
@ -23,15 +23,23 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["My Server"],
|
||||
"minLength": 2,
|
||||
"pattern": "^[^/\\\\]*$",
|
||||
"pattern": r"^[^/\\\\#]*$",
|
||||
"error": "serverCreateName",
|
||||
},
|
||||
"roles": {
|
||||
"title": "Roles to add",
|
||||
"type": "array",
|
||||
"examples": [1, 2, 3],
|
||||
"error": "typeList",
|
||||
},
|
||||
"roles": {"title": "Roles to add", "type": "array", "examples": [1, 2, 3]},
|
||||
"stop_command": {
|
||||
"title": "Stop command",
|
||||
"description": '"" means the default for the server creation type.',
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"examples": ["stop", "end"],
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"log_location": {
|
||||
"title": "Log file",
|
||||
@ -39,11 +47,15 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"examples": ["./logs/latest.log", "./proxy.log.0"],
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"crashdetection": {
|
||||
"title": "Crash detection",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"autostart": {
|
||||
"title": "Autostart",
|
||||
@ -51,6 +63,8 @@ new_server_schema = {
|
||||
+ " automatically when Crafty is launched.",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"autostart_delay": {
|
||||
"title": "Autostart delay",
|
||||
@ -58,12 +72,16 @@ new_server_schema = {
|
||||
"type": "number",
|
||||
"default": 10,
|
||||
"minimum": 0,
|
||||
"error": "typeIntMinVal0",
|
||||
"fill": True,
|
||||
},
|
||||
"monitoring_type": {
|
||||
"title": "Server monitoring type",
|
||||
"type": "string",
|
||||
"default": "minecraft_java",
|
||||
"enum": ["minecraft_java", "minecraft_bedrock", "none"],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
# TODO: SteamCMD, RakNet, etc.
|
||||
},
|
||||
"minecraft_java_monitoring_data": {
|
||||
@ -77,6 +95,8 @@ new_server_schema = {
|
||||
"default": "127.0.0.1",
|
||||
"examples": ["127.0.0.1"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"port": {
|
||||
"title": "Port",
|
||||
@ -84,6 +104,8 @@ new_server_schema = {
|
||||
"examples": [25565],
|
||||
"default": 25565,
|
||||
"minimum": 0,
|
||||
"error": "typeIntMinVal0",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -98,6 +120,8 @@ new_server_schema = {
|
||||
"default": "127.0.0.1",
|
||||
"examples": ["127.0.0.1"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"port": {
|
||||
"title": "Port",
|
||||
@ -105,6 +129,8 @@ new_server_schema = {
|
||||
"examples": [19132],
|
||||
"default": 19132,
|
||||
"minimum": 0,
|
||||
"error": "typeIntMinVal0",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -114,6 +140,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"default": "minecraft_java",
|
||||
"enum": ["minecraft_java", "minecraft_bedrock", "custom"],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
},
|
||||
"minecraft_java_create_data": {
|
||||
"title": "Java creation data",
|
||||
@ -125,10 +153,14 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"default": "download_jar",
|
||||
"enum": ["download_jar", "import_server", "import_zip"],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
},
|
||||
"download_jar_create_data": {
|
||||
"title": "JAR download data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": [
|
||||
"type",
|
||||
"version",
|
||||
@ -141,6 +173,8 @@ new_server_schema = {
|
||||
"title": "Jar Category",
|
||||
"type": "string",
|
||||
"examples": ["Mc_java_servers", "Mc_java_proxies"],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
},
|
||||
"properties": {
|
||||
"type": {
|
||||
@ -148,12 +182,16 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["Paper"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"version": {
|
||||
"title": "Server JAR Version",
|
||||
"type": "string",
|
||||
"examples": ["1.18.2"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"mem_min": {
|
||||
"title": "Minimum JVM memory (in GiBs)",
|
||||
@ -161,6 +199,8 @@ new_server_schema = {
|
||||
"examples": [1],
|
||||
"default": 1,
|
||||
"exclusiveMinimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"mem_max": {
|
||||
"title": "Maximum JVM memory (in GiBs)",
|
||||
@ -168,6 +208,8 @@ new_server_schema = {
|
||||
"examples": [2],
|
||||
"default": 2,
|
||||
"exclusiveMinimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"server_properties_port": {
|
||||
"title": "Port",
|
||||
@ -175,17 +217,23 @@ new_server_schema = {
|
||||
"examples": [25565],
|
||||
"default": 25565,
|
||||
"minimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"agree_to_eula": {
|
||||
"title": "Agree to the EULA",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
"import_server_create_data": {
|
||||
"title": "Import server data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": [
|
||||
"existing_server_path",
|
||||
"jarfile",
|
||||
@ -200,6 +248,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/var/opt/server"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"jarfile": {
|
||||
"title": "JAR file",
|
||||
@ -207,6 +257,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["paper.jar", "jars/vanilla-1.12.jar"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"mem_min": {
|
||||
"title": "Minimum JVM memory (in GiBs)",
|
||||
@ -214,6 +266,8 @@ new_server_schema = {
|
||||
"examples": [1],
|
||||
"default": 1,
|
||||
"exclusiveMinimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"mem_max": {
|
||||
"title": "Maximum JVM memory (in GiBs)",
|
||||
@ -221,6 +275,8 @@ new_server_schema = {
|
||||
"examples": [2],
|
||||
"default": 2,
|
||||
"exclusiveMinimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"server_properties_port": {
|
||||
"title": "Port",
|
||||
@ -228,17 +284,23 @@ new_server_schema = {
|
||||
"examples": [25565],
|
||||
"default": 25565,
|
||||
"minimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"agree_to_eula": {
|
||||
"title": "Agree to the EULA",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
"import_zip_create_data": {
|
||||
"title": "Import ZIP server data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": [
|
||||
"zip_path",
|
||||
"zip_root",
|
||||
@ -254,6 +316,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/var/opt/server.zip"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"zip_root": {
|
||||
"title": "Server root directory",
|
||||
@ -261,6 +325,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/", "/paper-server/", "server-1"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"jarfile": {
|
||||
"title": "JAR file",
|
||||
@ -268,6 +334,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["paper.jar", "jars/vanilla-1.12.jar"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"mem_min": {
|
||||
"title": "Minimum JVM memory (in GiBs)",
|
||||
@ -275,6 +343,8 @@ new_server_schema = {
|
||||
"examples": [1],
|
||||
"default": 1,
|
||||
"exclusiveMinimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"mem_max": {
|
||||
"title": "Maximum JVM memory (in GiBs)",
|
||||
@ -282,6 +352,8 @@ new_server_schema = {
|
||||
"examples": [2],
|
||||
"default": 2,
|
||||
"exclusiveMinimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"server_properties_port": {
|
||||
"title": "Port",
|
||||
@ -289,11 +361,15 @@ new_server_schema = {
|
||||
"examples": [25565],
|
||||
"default": 25565,
|
||||
"minimum": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"agree_to_eula": {
|
||||
"title": "Agree to the EULA",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -342,10 +418,14 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"default": "import_server",
|
||||
"enum": ["download_exe", "import_server", "import_zip"],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
},
|
||||
"download_exe_create_data": {
|
||||
"title": "Import server data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": [],
|
||||
"properties": {
|
||||
"agree_to_eula": {
|
||||
@ -358,6 +438,8 @@ new_server_schema = {
|
||||
"import_server_create_data": {
|
||||
"title": "Import server data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": ["existing_server_path", "executable"],
|
||||
"properties": {
|
||||
"existing_server_path": {
|
||||
@ -366,6 +448,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/var/opt/server"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"executable": {
|
||||
"title": "Executable File",
|
||||
@ -374,6 +458,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["bedrock_server.exe"],
|
||||
"minlength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"command": {
|
||||
"title": "Command",
|
||||
@ -381,12 +467,16 @@ new_server_schema = {
|
||||
"default": "echo foo bar baz",
|
||||
"examples": ["LD_LIBRARY_PATH=. ./bedrock_server"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
"import_zip_create_data": {
|
||||
"title": "Import ZIP server data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": ["zip_path", "zip_root", "command"],
|
||||
"properties": {
|
||||
"zip_path": {
|
||||
@ -395,6 +485,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/var/opt/server.zip"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"executable": {
|
||||
"title": "Executable File",
|
||||
@ -403,6 +495,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["bedrock_server.exe"],
|
||||
"minlength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"zip_root": {
|
||||
"title": "Server root directory",
|
||||
@ -410,6 +504,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/", "/paper-server/", "server-1"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"command": {
|
||||
"title": "Command",
|
||||
@ -417,6 +513,8 @@ new_server_schema = {
|
||||
"default": "echo foo bar baz",
|
||||
"examples": ["LD_LIBRARY_PATH=. ./bedrock_server"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -464,6 +562,8 @@ new_server_schema = {
|
||||
"custom_create_data": {
|
||||
"title": "Custom creation data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": [
|
||||
"working_directory",
|
||||
"executable_update",
|
||||
@ -476,28 +576,38 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"examples": ["/mnt/mydrive/server-configs/", "./subdirectory", ""],
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"executable_update": {
|
||||
"title": "Executable Updation",
|
||||
"description": "Also configurable later on and for other servers",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": ["enabled", "file", "url"],
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"title": "Enabled",
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"file": {
|
||||
"title": "Executable to update",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"examples": ["./paper.jar"],
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"url": {
|
||||
"title": "URL to download the executable from",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -506,6 +616,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"default": "raw_exec",
|
||||
"enum": ["raw_exec", "import_server", "import_zip"],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
},
|
||||
"raw_exec_create_data": {
|
||||
"title": "Raw execution command create data",
|
||||
@ -518,12 +630,16 @@ new_server_schema = {
|
||||
"default": "echo foo bar baz",
|
||||
"examples": ["caddy start"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
}
|
||||
},
|
||||
},
|
||||
"import_server_create_data": {
|
||||
"title": "Import server data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": ["existing_server_path", "command"],
|
||||
"properties": {
|
||||
"existing_server_path": {
|
||||
@ -532,6 +648,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/var/opt/server"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"command": {
|
||||
"title": "Command",
|
||||
@ -539,12 +657,16 @@ new_server_schema = {
|
||||
"default": "echo foo bar baz",
|
||||
"examples": ["caddy start"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
"import_zip_create_data": {
|
||||
"title": "Import ZIP server data",
|
||||
"type": "object",
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
"required": ["zip_path", "zip_root", "command"],
|
||||
"properties": {
|
||||
"zip_path": {
|
||||
@ -553,6 +675,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/var/opt/server.zip"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"zip_root": {
|
||||
"title": "Server root directory",
|
||||
@ -560,6 +684,8 @@ new_server_schema = {
|
||||
"type": "string",
|
||||
"examples": ["/", "/paper-server/", "server-1"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"command": {
|
||||
"title": "Command",
|
||||
@ -567,6 +693,8 @@ new_server_schema = {
|
||||
"default": "echo foo bar baz",
|
||||
"examples": ["caddy start"],
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -690,7 +818,16 @@ class ApiServersIndexHandler(BaseApiHandler):
|
||||
) = auth_data
|
||||
|
||||
if EnumPermissionsCrafty.SERVER_CREATION not in exec_user_crafty_permissions:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
data = orjson.loads(self.request.body)
|
||||
@ -700,13 +837,21 @@ class ApiServersIndexHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, new_server_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
# Check to make sure port is allowable
|
||||
@ -722,10 +867,27 @@ class ApiServersIndexHandler(BaseApiHandler):
|
||||
port = 19132
|
||||
if port > 65535 or port < 1:
|
||||
self.finish_json(
|
||||
405, {"status": "error", "error": "DATA CONSTRAINT FAILED"}
|
||||
405,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "DATA CONSTRAINT FAILED",
|
||||
"error_data": "1 - 65535",
|
||||
},
|
||||
)
|
||||
return
|
||||
try:
|
||||
new_server_id = self.controller.create_api_server(data, user["user_id"])
|
||||
except Exception as e:
|
||||
self.controller.servers.stats.record_stats()
|
||||
|
||||
self.finish_json(
|
||||
503,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "Could not create server",
|
||||
"error_data": str(e),
|
||||
},
|
||||
)
|
||||
|
||||
self.controller.servers.stats.record_stats()
|
||||
|
||||
|
@ -18,7 +18,16 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -28,7 +37,16 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.COMMANDS not in server_permissions:
|
||||
# if the user doesn't have Commands permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
if action == "clone_server":
|
||||
if (
|
||||
@ -49,7 +67,12 @@ class ApiServersServerActionHandler(BaseApiHandler):
|
||||
self._clone_server(server_id, auth_data[4]["user_id"])
|
||||
return self.finish_json(200, {"status": "ok"})
|
||||
return self.finish_json(
|
||||
200, {"status": "error", "error": "SERVER_LIMIT_REACHED"}
|
||||
200,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "SERVER_LIMIT_REACHED",
|
||||
"error_data": "LIMIT REACHED",
|
||||
},
|
||||
)
|
||||
if action == "eula":
|
||||
return self._agree_eula(server_id, auth_data[4]["user_id"])
|
||||
|
@ -14,7 +14,12 @@ logger = logging.getLogger(__name__)
|
||||
BACKUP_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"filename": {"type": "string", "minLength": 5},
|
||||
"filename": {
|
||||
"type": "string",
|
||||
"minLength": 5,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -22,14 +27,47 @@ BACKUP_SCHEMA = {
|
||||
BACKUP_PATCH_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backup_name": {"type": "string", "minLength": 3},
|
||||
"backup_location": {"type": "string", "minLength": 1},
|
||||
"max_backups": {"type": "integer"},
|
||||
"compress": {"type": "boolean"},
|
||||
"shutdown": {"type": "boolean"},
|
||||
"before": {"type": "string"},
|
||||
"after": {"type": "string"},
|
||||
"excluded_dirs": {"type": "array"},
|
||||
"backup_name": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"error": "backupName",
|
||||
},
|
||||
"backup_location": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"max_backups": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"compress": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"shutdown": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"before": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"after": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"excluded_dirs": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -38,13 +76,37 @@ BACKUP_PATCH_SCHEMA = {
|
||||
BASIC_BACKUP_PATCH_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backup_name": {"type": "string", "minLength": 3},
|
||||
"max_backups": {"type": "integer"},
|
||||
"compress": {"type": "boolean"},
|
||||
"shutdown": {"type": "boolean"},
|
||||
"before": {"type": "string"},
|
||||
"after": {"type": "string"},
|
||||
"excluded_dirs": {"type": "array"},
|
||||
"backup_name": {"type": "string", "minLength": 3, "error": "backupName"},
|
||||
"max_backups": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"compress": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"shutdown": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"before": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"after": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"excluded_dirs": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -179,13 +241,21 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, BACKUP_SCHEMA)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
@ -202,7 +272,8 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
||||
temp_dir = Helpers.unzip_backup_archive(backup_location, zip_name)
|
||||
except (FileNotFoundError, NotADirectoryError) as e:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": f"NO BACKUP FOUND {e}"}
|
||||
400,
|
||||
{"status": "error", "error": "NO BACKUP FOUND", "error_data": e},
|
||||
)
|
||||
if server_data["type"] == "minecraft-java":
|
||||
new_server = self.controller.restore_java_zip_server(
|
||||
@ -314,13 +385,21 @@ class ApiServersServerBackupsBackupIndexHandler(BaseApiHandler):
|
||||
validate(data, BACKUP_PATCH_SCHEMA)
|
||||
else:
|
||||
validate(data, BASIC_BACKUP_PATCH_SCHEMA)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
backup_conf = self.controller.management.get_backup_config(backup_id)
|
||||
@ -405,13 +484,21 @@ class ApiServersServerBackupsBackupFilesIndexHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, BACKUP_SCHEMA)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
self.helper.validate_traversal(
|
||||
@ -432,7 +519,7 @@ class ApiServersServerBackupsBackupFilesIndexHandler(BaseApiHandler):
|
||||
)
|
||||
except Exception as e:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": f"DELETE FAILED with error {e}"}
|
||||
400, {"status": "error", "error": "DELETE FAILED", "error_data": e}
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
auth_data[4]["user_id"],
|
||||
|
@ -11,14 +11,43 @@ logger = logging.getLogger(__name__)
|
||||
backup_patch_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backup_name": {"type": "string", "minLength": 3},
|
||||
"backup_location": {"type": "string", "minLength": 1},
|
||||
"max_backups": {"type": "integer"},
|
||||
"compress": {"type": "boolean"},
|
||||
"shutdown": {"type": "boolean"},
|
||||
"before": {"type": "string"},
|
||||
"after": {"type": "string"},
|
||||
"excluded_dirs": {"type": "array"},
|
||||
"backup_name": {"type": "string", "minLength": 3, "error": "backupName"},
|
||||
"backup_location": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"max_backups": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"compress": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"shutdown": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"before": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"after": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"excluded_dirs": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -27,13 +56,37 @@ backup_patch_schema = {
|
||||
basic_backup_patch_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backup_name": {"type": "string", "minLength": 3},
|
||||
"max_backups": {"type": "integer"},
|
||||
"compress": {"type": "boolean"},
|
||||
"shutdown": {"type": "boolean"},
|
||||
"before": {"type": "string"},
|
||||
"after": {"type": "string"},
|
||||
"excluded_dirs": {"type": "array"},
|
||||
"backup_name": {"type": "string", "minLength": 3, "error": "backupName"},
|
||||
"max_backups": {
|
||||
"type": "integer",
|
||||
"error": "typeInt",
|
||||
"fill": True,
|
||||
},
|
||||
"compress": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"shutdown": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"before": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"after": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"excluded_dirs": {
|
||||
"type": "array",
|
||||
"error": "typeList",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -54,7 +107,16 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
self.finish_json(
|
||||
200, self.controller.management.get_backups_by_server(server_id)
|
||||
)
|
||||
@ -76,18 +138,35 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler):
|
||||
validate(data, backup_patch_schema)
|
||||
else:
|
||||
validate(data, basic_backup_patch_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -97,7 +176,16 @@ class ApiServersServerBackupsIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.BACKUP not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
# Set the backup location automatically for non-super users. We should probably
|
||||
# make the default location configurable for SU eventually
|
||||
if not auth_data[4]["superuser"]:
|
||||
|
@ -14,8 +14,17 @@ logger = logging.getLogger(__name__)
|
||||
files_get_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"page": {"type": "string", "minLength": 1},
|
||||
"path": {"type": "string"},
|
||||
"page": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -24,8 +33,16 @@ files_get_schema = {
|
||||
files_patch_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {"type": "string"},
|
||||
"contents": {"type": "string"},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"contents": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -34,7 +51,11 @@ files_patch_schema = {
|
||||
files_unzip_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"folder": {"type": "string"},
|
||||
"folder": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -43,9 +64,21 @@ files_unzip_schema = {
|
||||
files_create_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"parent": {"type": "string"},
|
||||
"name": {"type": "string"},
|
||||
"directory": {"type": "boolean"},
|
||||
"parent": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"directory": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -54,8 +87,16 @@ files_create_schema = {
|
||||
files_rename_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {"type": "string"},
|
||||
"new_name": {"type": "string"},
|
||||
"path": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"new_name": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -64,7 +105,12 @@ files_rename_schema = {
|
||||
file_delete_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"filename": {"type": "string", "minLength": 5},
|
||||
"filename": {
|
||||
"type": "string",
|
||||
"minLength": 5,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -79,7 +125,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -92,7 +147,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
and EnumPermissionsServer.BACKUP not in server_permissions
|
||||
):
|
||||
# if the user doesn't have Files or Backup permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
@ -210,7 +274,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -220,7 +293,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
except json.decoder.JSONDecodeError as e:
|
||||
@ -229,13 +311,21 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, file_delete_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
if not Helpers.validate_traversal(
|
||||
@ -259,7 +349,9 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
# but not a true boolean value
|
||||
if proc == True: # pylint: disable=singleton-comparison
|
||||
return self.finish_json(200, {"status": "ok"})
|
||||
return self.finish_json(500, {"status": "error", "error": str(proc)})
|
||||
return self.finish_json(
|
||||
500, {"status": "error", "error": "SERVER RUNNING", "error_data": str(proc)}
|
||||
)
|
||||
|
||||
def patch(self, server_id: str, _backup_id):
|
||||
auth_data = self.authenticate_user()
|
||||
@ -268,7 +360,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -278,7 +379,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
except json.decoder.JSONDecodeError as e:
|
||||
@ -287,13 +397,21 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, files_patch_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
if not Helpers.validate_traversal(
|
||||
@ -322,7 +440,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -332,7 +459,16 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
except json.decoder.JSONDecodeError as e:
|
||||
@ -341,13 +477,21 @@ class ApiServersServerFilesIndexHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, files_create_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
path = os.path.join(data["parent"], data["name"])
|
||||
@ -389,7 +533,16 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -399,7 +552,16 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
except json.decoder.JSONDecodeError as e:
|
||||
@ -408,13 +570,21 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, files_rename_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
path = data["path"]
|
||||
@ -455,7 +625,16 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -465,7 +644,16 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
except json.decoder.JSONDecodeError as e:
|
||||
@ -474,13 +662,21 @@ class ApiServersServerFilesCreateHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, files_create_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
path = os.path.join(data["parent"], data["name"])
|
||||
@ -522,7 +718,16 @@ class ApiServersServerFilesZipHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -532,7 +737,16 @@ class ApiServersServerFilesZipHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.FILES not in server_permissions:
|
||||
# if the user doesn't have Files permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
except json.decoder.JSONDecodeError as e:
|
||||
@ -541,13 +755,21 @@ class ApiServersServerFilesZipHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, files_unzip_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
folder = data["folder"]
|
||||
|
@ -14,7 +14,16 @@ class ApiServersServerHistoryHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
srv = ServersController().get_server_instance_by_id(server_id)
|
||||
history = srv.get_server_history()
|
||||
|
@ -12,24 +12,101 @@ logger = logging.getLogger(__name__)
|
||||
server_patch_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"server_name": {"type": "string", "minLength": 2, "pattern": "^[^/\\\\]*$"},
|
||||
"backup_path": {"type": "string"},
|
||||
"executable": {"type": "string"},
|
||||
"log_path": {"type": "string", "minLength": 1},
|
||||
"execution_command": {"type": "string", "minLength": 1},
|
||||
"java_selection": {"type": "string"},
|
||||
"auto_start": {"type": "boolean"},
|
||||
"auto_start_delay": {"type": "integer", "minimum": 0},
|
||||
"crash_detection": {"type": "boolean"},
|
||||
"stop_command": {"type": "string"},
|
||||
"executable_update_url": {"type": "string"},
|
||||
"server_ip": {"type": "string", "minLength": 1},
|
||||
"server_port": {"type": "integer"},
|
||||
"shutdown_timeout": {"type": "integer", "minimum": 0},
|
||||
"logs_delete_after": {"type": "integer", "minimum": 0},
|
||||
"ignored_exits": {"type": "string"},
|
||||
"show_status": {"type": "boolean"},
|
||||
"count_players": {"type": "boolean"},
|
||||
"server_name": {
|
||||
"type": "string",
|
||||
"minLength": 2,
|
||||
"pattern": r"^[^/\\\\#]*$",
|
||||
"error": "serverCreateName",
|
||||
},
|
||||
"backup_path": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"executable": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"log_path": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "serverLogPath",
|
||||
},
|
||||
"execution_command": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "serverExeCommand",
|
||||
},
|
||||
"java_selection": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"auto_start": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"auto_start_delay": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"error": "typeIntMinVal0",
|
||||
"fill": True,
|
||||
},
|
||||
"crash_detection": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"stop_command": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"executable_update_url": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"server_ip": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"server_port": {
|
||||
"type": "integer",
|
||||
"error": "typeInt",
|
||||
"fill": True,
|
||||
},
|
||||
"shutdown_timeout": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"error": "typeIntMinVal0",
|
||||
"fill": True,
|
||||
},
|
||||
"logs_delete_after": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"error": "typeIntMinVal0",
|
||||
"fill": True,
|
||||
},
|
||||
"ignored_exits": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"show_status": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"count_players": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -37,17 +114,64 @@ server_patch_schema = {
|
||||
basic_server_patch_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"server_name": {"type": "string", "minLength": 1},
|
||||
"executable": {"type": "string"},
|
||||
"java_selection": {"type": "string"},
|
||||
"auto_start": {"type": "boolean"},
|
||||
"auto_start_delay": {"type": "integer", "minimum": 0},
|
||||
"crash_detection": {"type": "boolean"},
|
||||
"stop_command": {"type": "string"},
|
||||
"shutdown_timeout": {"type": "integer"},
|
||||
"logs_delete_after": {"type": "integer", "minimum": 0},
|
||||
"ignored_exits": {"type": "string"},
|
||||
"count_players": {"type": "boolean"},
|
||||
"server_name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"error": "serverCreateName",
|
||||
"fill": True,
|
||||
},
|
||||
"executable": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"java_selection": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"auto_start": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"auto_start_delay": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"error": "typeIntMinVal0",
|
||||
"fill": True,
|
||||
},
|
||||
"crash_detection": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"stop_command": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"shutdown_timeout": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"logs_delete_after": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"error": "typeIntMinVal0",
|
||||
"fill": True,
|
||||
},
|
||||
"ignored_exits": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"count_players": {
|
||||
"type": "boolean",
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -62,7 +186,16 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
server_obj = self.controller.servers.get_server_obj(server_id)
|
||||
server = model_to_dict(server_obj)
|
||||
@ -89,19 +222,36 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
validate(data, server_patch_schema)
|
||||
else:
|
||||
validate(data, basic_server_patch_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -111,7 +261,16 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Config permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
server_obj = self.controller.servers.get_server_obj(server_id)
|
||||
java_flag = False
|
||||
@ -125,7 +284,12 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
setattr(server_obj, "execution_command", command)
|
||||
except ValueError:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID EXECUTION COMMAND"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID EXECUTION COMMAND",
|
||||
"error_data": "INVALID COMMAND",
|
||||
},
|
||||
)
|
||||
java_flag = True
|
||||
|
||||
@ -154,7 +318,16 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -164,7 +337,16 @@ class ApiServersServerIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Config permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
logger.info(
|
||||
(
|
||||
|
@ -29,7 +29,16 @@ class ApiServersServerLogsHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -39,7 +48,16 @@ class ApiServersServerLogsHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.LOGS not in server_permissions:
|
||||
# if the user doesn't have Logs permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
server_data = self.controller.servers.get_server_data_by_id(server_id)
|
||||
|
||||
|
@ -14,7 +14,16 @@ class ApiServersServerStatsHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
srv = ServersController().get_server_instance_by_id(server_id)
|
||||
latest = srv.stats_helper.get_latest_server_stats()
|
||||
|
@ -15,7 +15,16 @@ class ApiServersServerStdinHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -25,7 +34,16 @@ class ApiServersServerStdinHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.COMMANDS not in server_permissions:
|
||||
# if the user doesn't have Commands permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
svr = self.controller.servers.get_server_obj_optional(server_id)
|
||||
if svr is None:
|
||||
@ -35,7 +53,16 @@ class ApiServersServerStdinHandler(BaseApiHandler):
|
||||
"Crafty can't access the server object. "
|
||||
"Please report this to the devs"
|
||||
)
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
decoded = self.request.body.decode("utf-8")
|
||||
self.controller.management.add_to_audit_log(
|
||||
auth_data[4]["user_id"],
|
||||
@ -50,5 +77,9 @@ class ApiServersServerStdinHandler(BaseApiHandler):
|
||||
)
|
||||
self.finish_json(
|
||||
200,
|
||||
{"status": "error", "error": "SERVER_NOT_RUNNING"},
|
||||
{
|
||||
"status": "error",
|
||||
"error": "SERVER_NOT_RUNNING",
|
||||
"error_data": "SERVER NOT RUNNING",
|
||||
},
|
||||
)
|
||||
|
@ -13,18 +13,32 @@ logger = logging.getLogger(__name__)
|
||||
new_task_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"default": True,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"action_id": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"interval": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"interval": {"type": "integer"},
|
||||
"interval_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@ -37,13 +51,43 @@ new_task_schema = {
|
||||
# CRON tasks:
|
||||
"",
|
||||
],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
},
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"pattern": r"\d{1,2}:\d{1,2}",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"command": {
|
||||
"type": ["string", "null"],
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"one_time": {
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"cron_string": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"parent": {
|
||||
"type": ["integer", "null"],
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"delay": {
|
||||
"type": "integer",
|
||||
"default": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"start_time": {"type": "string", "pattern": r"\d{1,2}:\d{1,2}"},
|
||||
"command": {"type": ["string", "null"]},
|
||||
"one_time": {"type": "boolean", "default": False},
|
||||
"cron_string": {"type": "string", "default": ""},
|
||||
"parent": {"type": ["integer", "null"]},
|
||||
"delay": {"type": "integer", "default": 0},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -68,19 +112,36 @@ class ApiServersServerTasksIndexHandler(BaseApiHandler):
|
||||
|
||||
try:
|
||||
validate(data, new_task_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -90,7 +151,16 @@ class ApiServersServerTasksIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
data["server_id"] = server_id
|
||||
if not data.get("start_time"):
|
||||
data["start_time"] = "00:00"
|
||||
|
@ -18,14 +18,24 @@ task_patch_schema = {
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"default": True,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"action": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"action_id": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"interval": {
|
||||
"type": "integer",
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"interval": {"type": "integer"},
|
||||
"interval_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@ -38,14 +48,48 @@ task_patch_schema = {
|
||||
# CRON tasks:
|
||||
"",
|
||||
],
|
||||
"error": "enumErr",
|
||||
"fill": True,
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"pattern": r"\d{1,2}:\d{1,2}",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"command": {
|
||||
"type": ["string", "null"],
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"one_time": {
|
||||
"type": "boolean",
|
||||
"default": False,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
"cron_string": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"parent": {
|
||||
"type": ["integer", "null"],
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"delay": {
|
||||
"type": "integer",
|
||||
"default": 0,
|
||||
"error": "typeInteger",
|
||||
"fill": True,
|
||||
},
|
||||
"name": {"type": "string"},
|
||||
"start_time": {"type": "string", "pattern": r"\d{1,2}:\d{1,2}"},
|
||||
"command": {"type": ["string", "null"]},
|
||||
"one_time": {"type": "boolean", "default": False},
|
||||
"cron_string": {"type": "string", "default": ""},
|
||||
"parent": {"type": ["integer", "null"]},
|
||||
"delay": {"type": "integer", "default": 0},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
"minProperties": 1,
|
||||
@ -66,7 +110,16 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
self.finish_json(200, self.controller.management.get_scheduled_task(task_id))
|
||||
|
||||
def delete(self, server_id: str, task_id: str):
|
||||
@ -82,13 +135,23 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
self.tasks_manager.remove_job(task_id)
|
||||
except Exception:
|
||||
except Exception as why:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "NO SCHEDULE FOUND"}
|
||||
400,
|
||||
{"status": "error", "error": "NO SCHEDULE FOUND", "error_data": why},
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
auth_data[4]["user_id"],
|
||||
@ -114,19 +177,36 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
||||
|
||||
try:
|
||||
validate(data, task_patch_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -136,7 +216,16 @@ class ApiServersServerTasksTaskIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.SCHEDULE not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
# Checks to make sure some doofus didn't actually make the newly
|
||||
# created task a child of itself.
|
||||
|
@ -14,13 +14,40 @@ class ApiServersServerUsersHandler(BaseApiHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
if EnumPermissionsCrafty.USER_CONFIG not in auth_data[1]:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
if EnumPermissionsCrafty.ROLES_CONFIG not in auth_data[1]:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.finish_json(
|
||||
200,
|
||||
|
@ -16,16 +16,45 @@ new_webhook_schema = {
|
||||
"webhook_type": {
|
||||
"type": "string",
|
||||
"enum": WebhookFactory.get_supported_providers(),
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"bot_name": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"trigger": {
|
||||
"type": "array",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"body": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"color": {
|
||||
"type": "string",
|
||||
"default": "#005cd1",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"name": {"type": "string"},
|
||||
"url": {"type": "string"},
|
||||
"bot_name": {"type": "string"},
|
||||
"trigger": {"type": "array"},
|
||||
"body": {"type": "string"},
|
||||
"color": {"type": "string", "default": "#005cd1"},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"default": True,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
@ -47,7 +76,16 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
self.finish_json(
|
||||
200,
|
||||
{
|
||||
@ -70,19 +108,36 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler):
|
||||
|
||||
try:
|
||||
validate(data, new_webhook_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -92,7 +147,16 @@ class ApiServersServerWebhooksIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
data["server_id"] = server_id
|
||||
|
||||
self.controller.management.add_to_audit_log(
|
||||
|
@ -17,16 +17,45 @@ webhook_patch_schema = {
|
||||
"webhook_type": {
|
||||
"type": "string",
|
||||
"enum": WebhookFactory.get_supported_providers(),
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"bot_name": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"trigger": {
|
||||
"type": "array",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"body": {
|
||||
"type": "string",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"color": {
|
||||
"type": "string",
|
||||
"default": "#005cd1",
|
||||
"error": "typeString",
|
||||
"fill": True,
|
||||
},
|
||||
"name": {"type": "string"},
|
||||
"url": {"type": "string"},
|
||||
"bot_name": {"type": "string"},
|
||||
"trigger": {"type": "array"},
|
||||
"body": {"type": "string"},
|
||||
"color": {"type": "string", "default": "#005cd1"},
|
||||
"enabled": {
|
||||
"type": "boolean",
|
||||
"default": True,
|
||||
"error": "typeBool",
|
||||
"fill": True,
|
||||
},
|
||||
},
|
||||
"additionalProperties": False,
|
||||
@ -48,13 +77,27 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
if (
|
||||
not str(webhook_id)
|
||||
in self.controller.management.get_webhooks_by_server(server_id).keys()
|
||||
):
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "NO WEBHOOK FOUND"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NO WEBHOOK FOUND",
|
||||
"error_data": "NOT FOUND",
|
||||
},
|
||||
)
|
||||
self.finish_json(
|
||||
200,
|
||||
@ -77,13 +120,27 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
self.controller.management.delete_webhook(webhook_id)
|
||||
except Exception:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "NO WEBHOOK FOUND"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NO WEBHOOK FOUND",
|
||||
"error_data": "NOT FOUND",
|
||||
},
|
||||
)
|
||||
self.controller.management.add_to_audit_log(
|
||||
auth_data[4]["user_id"],
|
||||
@ -108,19 +165,36 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
|
||||
try:
|
||||
validate(data, webhook_patch_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -130,7 +204,16 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
data["server_id"] = server_id
|
||||
if "trigger" in data.keys():
|
||||
@ -163,7 +246,16 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
)
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
mask = self.controller.server_perms.get_lowest_api_perm_mask(
|
||||
self.controller.server_perms.get_user_permissions_mask(
|
||||
auth_data[4]["user_id"], server_id
|
||||
@ -173,7 +265,16 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
server_permissions = self.controller.server_perms.get_permissions(mask)
|
||||
if EnumPermissionsServer.CONFIG not in server_permissions:
|
||||
# if the user doesn't have Schedule permission, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
webhook = self.controller.management.get_webhook_by_id(webhook_id)
|
||||
try:
|
||||
webhook_provider = WebhookFactory.create_provider(webhook["webhook_type"])
|
||||
@ -188,6 +289,8 @@ class ApiServersServerWebhooksManagementIndexHandler(BaseApiHandler):
|
||||
bot_name="Crafty Webhooks Tester",
|
||||
)
|
||||
except Exception as e:
|
||||
self.finish_json(500, {"status": "error", "error": str(e)})
|
||||
self.finish_json(
|
||||
500, {"status": "error", "error": "WEBHOOK ERROR", "error_data": str(e)}
|
||||
)
|
||||
|
||||
self.finish_json(200, {"status": "ok"})
|
||||
|
@ -77,7 +77,16 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
||||
) = auth_data
|
||||
|
||||
if EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions:
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
data = json.loads(self.request.body)
|
||||
@ -88,12 +97,15 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
||||
|
||||
try:
|
||||
validate(data, new_user_schema)
|
||||
except ValidationError as e:
|
||||
err = self.translator.translate(
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
e.schema["error"],
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
@ -125,11 +137,23 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
||||
|
||||
if username.lower() in ["system", ""]:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_USERNAME"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_USERNAME",
|
||||
"error_data": "INVALID USERNAME",
|
||||
},
|
||||
)
|
||||
|
||||
if self.controller.users.get_id_by_name(username) is not None:
|
||||
return self.finish_json(400, {"status": "error", "error": "USER_EXISTS"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "USER_EXISTS",
|
||||
"error_data": "UNIQUE VALUE ERROR",
|
||||
},
|
||||
)
|
||||
|
||||
if roles is None:
|
||||
roles = set()
|
||||
@ -155,7 +179,14 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
||||
|
||||
if new_superuser and not superuser:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_SUPERUSER_CREATE"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_SUPERUSER_CREATE",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
for role in roles:
|
||||
@ -166,7 +197,14 @@ class ApiUsersIndexHandler(BaseApiHandler):
|
||||
and not superuser
|
||||
):
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_ROLES_CREATE"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_ROLES_CREATE",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
# TODO: do this in the most efficient way
|
||||
|
@ -134,13 +134,21 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
||||
)
|
||||
try:
|
||||
validate(data, user_patch_schema)
|
||||
except ValidationError as e:
|
||||
except ValidationError as why:
|
||||
offending_key = ""
|
||||
if why.schema.get("fill", None):
|
||||
offending_key = why.path[0] if why.path else None
|
||||
err = f"""{offending_key} {self.translator.translate(
|
||||
"validators",
|
||||
why.schema.get("error"),
|
||||
self.controller.users.get_user_lang_by_id(auth_data[4]["user_id"]),
|
||||
)} {why.schema.get("enum", "")}"""
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_JSON_SCHEMA",
|
||||
"error_data": str(e),
|
||||
"error_data": f"{str(err)}",
|
||||
},
|
||||
)
|
||||
if user_id == "@me":
|
||||
@ -161,7 +169,12 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
||||
if "username" in data:
|
||||
if data["username"].lower() in ["system", ""]:
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_USERNAME"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_USERNAME",
|
||||
"error_data": "INVALID USERNAME",
|
||||
},
|
||||
)
|
||||
if self.controller.users.get_id_by_name(
|
||||
data["username"]
|
||||
@ -171,7 +184,12 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
||||
user_id
|
||||
):
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "USER_EXISTS"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "USER_EXISTS",
|
||||
"error_data": "UNIQUE CONSTAINT FAILED",
|
||||
},
|
||||
)
|
||||
|
||||
if "superuser" in data:
|
||||
@ -179,7 +197,14 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
||||
# Checks if user is trying to change super user status
|
||||
# of self without superuser. We don't want that.
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_SUPERUSER_MODIFY"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_SUPERUSER_MODIFY",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
if not superuser:
|
||||
# The user is not superuser so they can't change the superuser status
|
||||
@ -190,13 +215,27 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
||||
# Checks if user is trying to change permissions
|
||||
# of self without superuser. We don't want that.
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_PERMISSIONS_MODIFY"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_PERMISSIONS_MODIFY",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
if EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions:
|
||||
# Checks if user is trying to change permissions of someone
|
||||
# else without User Config permission. We don't want that.
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_PERMISSIONS_MODIFY"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_PERMISSIONS_MODIFY",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
if "roles" in data:
|
||||
@ -204,13 +243,27 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
||||
# Checks if user is trying to change roles of
|
||||
# self without superuser. We don't want that.
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_ROLES_MODIFY"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_ROLES_MODIFY",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
if EnumPermissionsCrafty.USER_CONFIG not in exec_user_crafty_permissions:
|
||||
# Checks if user is trying to change roles of someone
|
||||
# else without User Config permission. We don't want that.
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_ROLES_MODIFY"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_ROLES_MODIFY",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
user_modify = self.controller.users.get_user_roles_id(user_id)
|
||||
|
||||
@ -229,7 +282,14 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
||||
for item in user_modify:
|
||||
print(type(role), type(item))
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_ROLES_MODIFY"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_ROLES_MODIFY",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"error", "no-file", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
user_obj = HelperUsers.get_user_model(user_id)
|
||||
@ -237,7 +297,14 @@ class ApiUsersUserIndexHandler(BaseApiHandler):
|
||||
if str(user["user_id"]) != str(user_obj.manager) and not user["superuser"]:
|
||||
# TODO: edit your own password
|
||||
return self.finish_json(
|
||||
400, {"status": "error", "error": "INVALID_PASSWORD_MODIFY"}
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "INVALID_PASSWORD_MODIFY",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
if "roles" in data:
|
||||
|
@ -13,7 +13,16 @@ class ApiOpenMetricsCraftyHandler(BaseMetricsHandler):
|
||||
|
||||
if not auth_data[3]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.get_registry()
|
||||
|
||||
|
@ -14,13 +14,29 @@ class ApiOpenMetricsServersHandler(BaseMetricsHandler):
|
||||
|
||||
if server_id not in [str(x["server_id"]) for x in auth_data[0]]:
|
||||
# if the user doesn't have access to the server, return an error
|
||||
return self.finish_json(400, {"status": "error", "error": "NOT_AUTHORIZED"})
|
||||
return self.finish_json(
|
||||
400,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "NOT_AUTHORIZED",
|
||||
"error_data": self.helper.translation.translate(
|
||||
"validators", "insufficientPerms", auth_data[4]["lang"]
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
self.get_registry(server_id)
|
||||
|
||||
def get_registry(self, server_id=None) -> None:
|
||||
if server_id is None:
|
||||
return self.finish_json(500, {"status": "error", "error": "UNKNOWN_SERVER"})
|
||||
return self.finish_json(
|
||||
500,
|
||||
{
|
||||
"status": "error",
|
||||
"error": "UNKNOWN_SERVER",
|
||||
"error_data": "UNKNOWN SERVER",
|
||||
},
|
||||
)
|
||||
|
||||
# Prepare parameters
|
||||
registry = (
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"major": 4,
|
||||
"minor": 4,
|
||||
"sub": 4
|
||||
"sub": 5
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ async function getTreeView(path, unzip = false, upload = false) {
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -325,8 +325,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
})
|
||||
@ -349,8 +349,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
})
|
||||
|
@ -617,8 +617,8 @@
|
||||
setTimeout(function(){
|
||||
$('.modal').modal('hide');
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}, 2000)
|
||||
}
|
||||
@ -1024,8 +1024,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -372,8 +372,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -410,8 +410,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -451,8 +451,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -122,7 +122,7 @@ data['lang']) }}{% end %}
|
||||
name="lang" form="user_form">
|
||||
{% for lang in data['languages'] %}
|
||||
{% if not 'incomplete' in lang %}
|
||||
<option value="{{lang}}" >{{translate('language', lang, 'humanized_index')}}</option>
|
||||
<option value="{{lang}}" >{{translate('language', lang, 'humanized_index', False)}}</option>
|
||||
{% else %}
|
||||
<option value="{{lang}}" disabled>{{lang}}</option>
|
||||
{% end %}
|
||||
@ -547,7 +547,7 @@ data['lang']) }}{% end %}
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.error,
|
||||
message: responseData.error
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -266,8 +266,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
return;
|
||||
@ -485,8 +485,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -342,8 +342,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
return;
|
||||
@ -676,8 +676,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -429,8 +429,8 @@
|
||||
else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -605,8 +605,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -627,8 +627,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -650,8 +650,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -672,8 +672,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -695,8 +695,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -717,8 +717,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -841,8 +841,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -212,8 +212,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -318,8 +318,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -189,8 +189,8 @@
|
||||
console.log("Command received successfully")
|
||||
} else {
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -256,8 +256,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -218,8 +218,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -259,8 +259,8 @@
|
||||
} else {
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -359,8 +359,8 @@
|
||||
} else {
|
||||
console.log(responseData);
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -379,8 +379,8 @@
|
||||
window.location.reload();
|
||||
} else {
|
||||
bootbox.alert({
|
||||
title: responseData.status,
|
||||
message: responseData.error
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -498,24 +498,19 @@
|
||||
<script src="../../static/assets/js/shared/upload.js"></script>
|
||||
<script>
|
||||
document.getElementById("root_upload_button").addEventListener("click", function (event) {
|
||||
if (file) {
|
||||
upload = true;
|
||||
if (document.getElementById('root_upload_button').classList.contains('clicked')) {
|
||||
document.getElementById('main-tree-div-upload').innerHTML = '<input type="radio" class="root-input" id="main-tree-input-upload" name="root_path" value="" checked><span id="main-tree-upload" class="files-tree-title tree-caret-down root-dir"><i class="far fa-folder"></i><i class="far fa-folder-open"></i>{{ translate("serverFiles", "files", data["lang"]) }}</span></input>'
|
||||
show_file_tree();
|
||||
return;
|
||||
} else {
|
||||
document.getElementById('root_upload_button').classList.add('clicked')
|
||||
}
|
||||
const token = getCookie("_xsrf");
|
||||
var dialog = bootbox.dialog({
|
||||
bootbox.dialog({
|
||||
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Please wait while we gather your files...</p>',
|
||||
closeButton: false
|
||||
});
|
||||
setTimeout(function () {
|
||||
getDirView();
|
||||
}, 2000);
|
||||
} else {
|
||||
bootbox.alert("You must input a path before selecting this button");
|
||||
}
|
||||
});
|
||||
|
||||
function eula_confirm() {
|
||||
@ -624,7 +619,9 @@
|
||||
if (responseData.status === "ok") {
|
||||
window.location.href = '/panel/dashboard';
|
||||
} else {
|
||||
|
||||
// Close the "be patient..." dialogue box
|
||||
$('.bootbox-close-button').click();
|
||||
// Alert the user that there was an issue.
|
||||
bootbox.alert({
|
||||
title: responseData.error,
|
||||
message: responseData.error_data
|
||||
|
@ -1099,7 +1099,7 @@
|
||||
|
||||
bootbox.alert({
|
||||
title: responseData.error,
|
||||
message: responseData.error
|
||||
message: responseData.error_data
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import os
|
||||
import json
|
||||
import datetime
|
||||
import uuid
|
||||
import peewee
|
||||
@ -13,9 +14,9 @@ from app.classes.shared.file_helpers import FileHelpers
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def is_valid_backup(backup, all_servers):
|
||||
def is_valid_entry(entry, all_servers):
|
||||
try:
|
||||
return str(backup.server_id) in all_servers
|
||||
return str(entry.server_id) in all_servers
|
||||
except (TypeError, peewee.DoesNotExist):
|
||||
return False
|
||||
|
||||
@ -24,6 +25,8 @@ def migrate(migrator: Migrator, database, **kwargs):
|
||||
"""
|
||||
Write your migrations here.
|
||||
"""
|
||||
backup_migration_status = True
|
||||
schedule_migration_status = True
|
||||
db = database
|
||||
Console.info("Starting Backups migrations")
|
||||
Console.info(
|
||||
@ -161,10 +164,20 @@ def migrate(migrator: Migrator, database, **kwargs):
|
||||
row.server_id for row in Servers.select(Servers.server_id).distinct()
|
||||
]
|
||||
all_backups = Backups.select()
|
||||
all_schedules = Schedules.select()
|
||||
Console.info("Cleaning up orphan backups for all servers")
|
||||
valid_backups = [
|
||||
backup for backup in all_backups if is_valid_backup(backup, all_servers)
|
||||
backup for backup in all_backups if is_valid_entry(backup, all_servers)
|
||||
]
|
||||
if len(valid_backups) < len(all_backups):
|
||||
backup_migration_status = False
|
||||
print("Orphan backup found")
|
||||
Console.info("Cleaning up orphan schedules for all servers")
|
||||
valid_schedules = [
|
||||
schedule for schedule in all_schedules if is_valid_entry(schedule, all_servers)
|
||||
]
|
||||
if len(valid_schedules) < len(all_schedules):
|
||||
schedule_migration_status = False
|
||||
# Copy data from the existing backups table to the new one
|
||||
for backup in valid_backups:
|
||||
Console.info(f"Trying to get server for backup migration {backup.server_id}")
|
||||
@ -221,13 +234,20 @@ def migrate(migrator: Migrator, database, **kwargs):
|
||||
Console.debug("Migrations: Dropping backup_path from servers table")
|
||||
migrator.drop_columns("servers", ["backup_path"])
|
||||
|
||||
for schedule in Schedules.select():
|
||||
for schedule in valid_schedules:
|
||||
action_id = None
|
||||
if schedule.command == "backup_server":
|
||||
Console.info(
|
||||
f"Migrations: Adding backup ID to task with name {schedule.name}"
|
||||
)
|
||||
try:
|
||||
backup = NewBackups.get(NewBackups.server_id == schedule.server_id)
|
||||
except:
|
||||
schedule_migration_status = False
|
||||
Console.error(
|
||||
"Could not find backup with selected server ID. Omitting from register."
|
||||
)
|
||||
continue
|
||||
action_id = backup.backup_id
|
||||
NewSchedules.create(
|
||||
schedule_id=schedule.schedule_id,
|
||||
@ -255,6 +275,34 @@ def migrate(migrator: Migrator, database, **kwargs):
|
||||
# Rename the new table to backups
|
||||
migrator.rename_table("new_schedules", "schedules")
|
||||
|
||||
with open(
|
||||
os.path.join(
|
||||
os.path.abspath(os.path.curdir),
|
||||
"app",
|
||||
"migrations",
|
||||
"status",
|
||||
"20240308_multi-backup.json",
|
||||
),
|
||||
"w",
|
||||
encoding="utf-8",
|
||||
) as file:
|
||||
file.write(
|
||||
json.dumps(
|
||||
{
|
||||
"backup_migration": {
|
||||
"type": "backup",
|
||||
"status": backup_migration_status,
|
||||
"pid": str(uuid.uuid4()),
|
||||
},
|
||||
"schedule_migration": {
|
||||
"type": "schedule",
|
||||
"status": schedule_migration_status,
|
||||
"pid": str(uuid.uuid4()),
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def rollback(migrator: Migrator, database, **kwargs):
|
||||
"""
|
||||
|
@ -29,7 +29,6 @@
|
||||
"permName": "Název oprávnění",
|
||||
"perms": "Oprávnění",
|
||||
"server": "Server: ",
|
||||
"superUser": "Super uživatel",
|
||||
"yes": "Ano"
|
||||
},
|
||||
"base": {
|
||||
@ -130,9 +129,6 @@
|
||||
"copyKeys": "Stisknutím kláves Ctrl nebo u2318 + C zkopírujete data tabulky do systémové schránky.<br><br>Chcete-li tuto zprávu zrušit, klikněte na ni nebo stiskněte klávesu ESC.",
|
||||
"copySuccess": {
|
||||
"1": "Zkopírován 1 řádek do schránky",
|
||||
"2": "Zkopírovány 2 řádky do schránky",
|
||||
"3": "Zkopírovány 3 řádky do schránky",
|
||||
"4": "Zkopírovány 4 řádky do schránky",
|
||||
"_": "Zkopírováno %d řádků do schránky"
|
||||
},
|
||||
"copyTitle": "Zkopírovat do schránky",
|
||||
@ -141,20 +137,17 @@
|
||||
"pageLength": {
|
||||
"-1": "Zobrazit všechny řádky",
|
||||
"1": "Zobrazit 1 řádek",
|
||||
"2": "Zobrazit 2 řádky",
|
||||
"3": "Zobrazit 3 řádky",
|
||||
"4": "Zobrazit 4 řádky",
|
||||
"_": "Zobrazit %d řádků"
|
||||
},
|
||||
"pdf": "PDF",
|
||||
"print": "Tisk"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "V tabulce nejsou k dispozici žádné údaje",
|
||||
"info": "Zobrazeno _START_ až _END_ z _TOTAL_ záznamů",
|
||||
"infoEmpty": "Zobrazeno 0 až 0 z 0 záznamů",
|
||||
"infoFiltered": "(filtrováno z _MAX_ celkových záznamů)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Zobrazit položky _MENU_",
|
||||
"loadingRecords": "Načítání...",
|
||||
"paginate": {
|
||||
@ -169,25 +162,16 @@
|
||||
"cells": {
|
||||
"0": "Kliknutím na buňku ji vyberete",
|
||||
"1": "Vybraná %d buňka",
|
||||
"2": "Vybrané %d buňky",
|
||||
"3": "Vybrané %d buňky",
|
||||
"4": "Vybrané %d buňky",
|
||||
"_": "Vybráno %d buněk"
|
||||
},
|
||||
"columns": {
|
||||
"0": "Kliknutím na sloupec jej vyberete",
|
||||
"1": "Vybraný %d sloupec",
|
||||
"2": "Vybrané %d sloupce",
|
||||
"3": "Vybrané %d sloupce",
|
||||
"4": "Vybrané %d sloupce",
|
||||
"_": "Vybráno %d sloupců"
|
||||
},
|
||||
"rows": {
|
||||
"0": "Kliknutím na řádek jej vyberete",
|
||||
"1": "Vybraný %d řádek",
|
||||
"2": "Vybrané %d řádky",
|
||||
"3": "Vybrané %d řádky",
|
||||
"4": "Vybrané %d řádky",
|
||||
"_": "Vybráno %d řádků"
|
||||
}
|
||||
},
|
||||
@ -224,8 +208,6 @@
|
||||
"privMsg": "a ",
|
||||
"return": "vrátit se na hlavní stránku",
|
||||
"selfHost": "Pokud Hostujete sami toto uložiště prosím zkontrolujte adresu nebo si přečtěte náš průvodce odstraňováním problémů.",
|
||||
"serverJars1": "Server JAR api je nepřístupná. Prosím zkontrolujte",
|
||||
"serverJars2": "pro aktualní informace.",
|
||||
"start-error": "Server {} se nepodařilo spustit s kódem chyby: {}",
|
||||
"superError": "Pro dokončení této akce musíte být super uživatel.",
|
||||
"terribleFailure": "Jaké strašné selhání!"
|
||||
@ -253,7 +235,8 @@
|
||||
"finishedPreparing": "Dokončili jsme přípravu protokolů podpory. Klikněte na tlačítko Stáhnout pro stažení",
|
||||
"logout": "Odhlásit se",
|
||||
"preparingLogs": " Počkejte prosím, než připravíme vaše protokoly... Až budou připraveny, pošleme vám oznámení. U rozsáhlých zavádění to může chvíli trvat.",
|
||||
"supportLogs": "Protokoly podpory"
|
||||
"supportLogs": "Protokoly podpory",
|
||||
"backup_desc": ""
|
||||
},
|
||||
"offline": {
|
||||
"offline": "Offline",
|
||||
@ -264,7 +247,6 @@
|
||||
"allowedServers": "Povolené servery",
|
||||
"apply": "Použít",
|
||||
"assignedRoles": "Přidělené role",
|
||||
"backgroundUpload": "Nahrání pozadí",
|
||||
"cancel": "Zrušit",
|
||||
"clearComms": "Vymazat nevykonané příkazy",
|
||||
"custom": "Upravit Crafty",
|
||||
@ -275,20 +257,16 @@
|
||||
"globalExplain": "Kde má Crafty ukládat všechny soubory serverů. (Cestu doplníme o /server/[uuid serveru])",
|
||||
"globalServer": "Globalní cesta k serverům",
|
||||
"json": "Config.json",
|
||||
"loginBackground": "Přihlašovací obrázek na pozadí",
|
||||
"loginImage": "Nahrajte obrázek na pozadí přihlašovací obrazovky.",
|
||||
"match": "Hesla musí být stejná",
|
||||
"newRole": "Přidat novou roli",
|
||||
"newUser": "Přidat nového uživatele",
|
||||
"noMounts": "Ukazatel zaplněnosti disků na hlavní stránce",
|
||||
"pageTitle": "Nastavení panelu",
|
||||
"preview": "Náhled",
|
||||
"role": "Role",
|
||||
"roleUsers": "Uživatelé s rolí",
|
||||
"roles": "Role",
|
||||
"save": "Uložit",
|
||||
"select": "Vyberte",
|
||||
"selectImage": "Vyberte obrázek",
|
||||
"superConfirm": "Postupujte pouze v případě, že chcete, aby měl tento uživatel přístup ke VŠEM (ke všem uživatelským účtům, serverům, nastavení panelu atd.). Může vám dokonce odebrat práva superuživatele.",
|
||||
"superConfirmTitle": "Povolit superuživatele? Jste si jisti?",
|
||||
"title": "Crafty Konfigurace",
|
||||
|
@ -29,7 +29,6 @@
|
||||
"permName": "Berechtigungs Name",
|
||||
"perms": "Berechtigungen",
|
||||
"server": "Server: ",
|
||||
"superUser": "Super Benutzer",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Drucken"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Keine Daten in der Tabelle verfügbar",
|
||||
"info": "Zeige _START_ bis _END_ von insges. _TOTAL_ Einträge(n)",
|
||||
"infoEmpty": "Zeige 0 bis 0 von insges. 0 Einträgen",
|
||||
"infoFiltered": "(gefiltert von _MAX_ maximalen Einträgen)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Zeige _MENU_ Einträge",
|
||||
"loadingRecords": "Laden...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "und der/die/das ",
|
||||
"return": "Zurück zum Dashboard",
|
||||
"selfHost": "Wenn Sie dieses Repo selbst hosten, überprüfen Sie bitte Ihre Adresse oder konsultieren Sie unsere Anleitung zur Fehlerbehebung.",
|
||||
"serverJars1": "Server-JAR-API nicht erreichbar. Bitte überprüfen Sie ",
|
||||
"serverJars2": "um die aktuellsten Informationen zu erhalten.",
|
||||
"start-error": "Der Server {} konnte wegen dem Fehlercode: {} nicht gestartet werden",
|
||||
"superError": "Sie müssen ein Administrator sein, um diese Aktion abzuschließen.",
|
||||
"terribleFailure": "Was für ein furchtbarer Fehler!"
|
||||
@ -222,7 +219,7 @@
|
||||
},
|
||||
"login": {
|
||||
"defaultPath": "Der eingegebene Text ist der Pfad zum Passwort, nicht das Passwort selbst. Das Standartpasswort kann unter diesen Pfad eingesehen werden.",
|
||||
"disabled": "Account gesperrt. Für weitere Informationen den Serveradministrator kontaktieren",
|
||||
"disabled": "Account gesperrt. Für weitere Informationen den Serveradministrator kontaktieren.",
|
||||
"forgotPassword": "Passwort vergessen",
|
||||
"incorrect": "Benutzername oder Passwort falsch",
|
||||
"login": "Einloggen",
|
||||
@ -238,11 +235,15 @@
|
||||
"finishedPreparing": "Wir haben die Bereitstellung der Supportprotokolle abgeschlossen. Bitte klicke 'Herunterladen' um diese herunterzuladen",
|
||||
"logout": "Abmelden",
|
||||
"preparingLogs": " Bitte warten, während wir die Protokolle vorbereiten... Wir schicken eine Benachrichtigung, wenn sie fertig sind. Dies kann bei großen Projekten eine Weile dauern.",
|
||||
"supportLogs": "Supportprotokolle"
|
||||
"supportLogs": "Supportprotokolle",
|
||||
"backup_desc": "Wir haben fesgestellt, dass die Migration des Backups teilweise oder vollständig fehlgeschlagen ist. Bitte Backups im Backup Menü überprüfen.",
|
||||
"schedule_desc": "Wir haben festgestellt, dass geplante Aufgaben während des Upgrades nicht erfolgreich übertragen wurden. Bitte die geplanten Aufgaben im Zeitplan überprüfen.",
|
||||
"backup_title": "Backup Migrations Warnung",
|
||||
"schedule_title": "Zeitplan Migrations Warnung"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "Offline",
|
||||
"pleaseConnect": "Bitte stellen sie eine Internetverbindung her, um Crafty nutzen zu können"
|
||||
"pleaseConnect": "Bitte stellen sie eine Internetverbindung her, um Crafty nutzen zu können."
|
||||
},
|
||||
"panelConfig": {
|
||||
"adminControls": "Administrations-Werkzeuge",
|
||||
@ -554,7 +555,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Geben Sie Ihren Befehl ein",
|
||||
"delay-explained": "Der Dienst wurde kürzlich gestartet und verzögert den Start der Minecraft-Serverinstanz",
|
||||
"downloading": "Lädt herunter...",
|
||||
"importing": "Importieren...",
|
||||
"installing": "Installation läuft...",
|
||||
"restart": "Neustart",
|
||||
@ -672,7 +672,26 @@
|
||||
"uses": "Anzahl der erlaubten Verwendungen (-1==Keine Begrenzung)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "Passwort zu kurz. Mindestlänge: 8"
|
||||
"passLength": "Passwort zu kurz. Mindestlänge: 8",
|
||||
"typeInteger": "muss eine Zahl sein.",
|
||||
"typeList": "muss eine Liste (array) sein ",
|
||||
"roleManager": "Rollenmanager muss vom Typ Ganzzahl (Manager ID) oder ohne Wert sein",
|
||||
"typeIntMinVal0": "muss eine ganze Zahl und mindestens 0 sein.",
|
||||
"backupName": "Der Name des Backups muss eine Zeichenkette mit mindestens drei Zeichen sein.",
|
||||
"serverCreateName": "Server Name muss eine Zeichenkette mit der Mindestlänge 1 sein und darf die folgenden Zeichen nicht beinhalten: \\ / # ",
|
||||
"userName": " muss vom Typ Zeichenkette, in kleinbuchstaben und zwischen 4 und 20 Zeichen lang sein",
|
||||
"enumErr": "Validierung fehlgeschlagen. Erfolgreiche Prüfung der folgenden Daten: ",
|
||||
"filesPageLen": "Länge der Eigenschaft muss größer als 1 sein",
|
||||
"roleName": "Rollenmanager muss eine Zeichenkette Länger als 1 sein und darf folgende Symbole nicht enthalten: [], ",
|
||||
"roleServerId": "Server ID muss eine Zeichenkette mit der Mindestlänge 1 sein",
|
||||
"roleServerPerms": "Serverberechtigung muss eine 8 Bit Zeichenkette sein",
|
||||
"serverLogPath": "Server log Pfad muss eine Zeichenkette mit einer Mindestlänge von 1 sein",
|
||||
"taskIntervalType": "Aufgaben Intervall muss einer der folgenden sein: ",
|
||||
"typeBool": "muss wahr oder falsch sein (typ boolean)",
|
||||
"typeEmail": "muss eine Email sein.",
|
||||
"insufficientPerms": "Berechtigungsfehler: Fehlende Berechtigungen für diese Ressource",
|
||||
"serverExeCommand": "Server Ausführungbefehl muss eine Zeichenkette mit der Mindestlänge 1 sein.",
|
||||
"typeString": "muss vom Typ Zeichenkette sein."
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "Sind Sie sicher, dass Sie diesen Webhook löschen möchten?",
|
||||
|
@ -142,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Print"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "No data available in table",
|
||||
"info": "Showing _START_ to _END_ of _TOTAL_ entries",
|
||||
"infoEmpty": "Showing 0 to 0 of 0 entries",
|
||||
"infoFiltered": "(filtered from _MAX_ total entries)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"loadingRecords": "Loading...",
|
||||
"paginate": {
|
||||
@ -231,10 +231,14 @@
|
||||
"activityLog": "Activity Logs",
|
||||
"backupComplete": "Backup completed successfully for server {}",
|
||||
"backupStarted": "Backup started for server {}",
|
||||
"backup_desc": "We detected the backup migration may have partially or fully failed. Please confirm your backups records on the backups tab.",
|
||||
"backup_title": "Backup Migration Warning",
|
||||
"downloadLogs": "Download Support Logs?",
|
||||
"finishedPreparing": "We've finished preparing your support logs. Please click download to download",
|
||||
"logout": "Logout",
|
||||
"preparingLogs": " Please wait while we prepare your logs... We`ll send a notification when they`re ready. This may take a while for large deployments.",
|
||||
"schedule_desc": "We detected some or all of your scheduled tasks were not successfully transfered during the upgrade. Please confirm your schedules in the schedules tab.",
|
||||
"schedule_title": "Schedules Migration Warning",
|
||||
"supportLogs": "Support Logs"
|
||||
},
|
||||
"offline": {
|
||||
@ -668,7 +672,26 @@
|
||||
"uses": "Number of uses allowed (-1==No Limit)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "Password Too Short. Minimum Length: 8"
|
||||
"backupName": "Backup name must be a string and a minimum length of 3.",
|
||||
"enumErr": "failed validating. Acceptable data includes: ",
|
||||
"filesPageLen": "length must be greater than 1 for property",
|
||||
"insufficientPerms": "Permission Error: Missing permissions for this resource",
|
||||
"passLength": "Password Too Short. Minimum Length: 8",
|
||||
"roleManager": "Role manager must be of type integer (manager ID) or None",
|
||||
"roleName": "Role name must be a string that is greater than 1 character. It must not include any of the following symbols: [ ] , ",
|
||||
"roleServerId": "Server ID property must be a string with a minimum length of 1",
|
||||
"roleServerPerms": "Server permissions must be an 8-bit string",
|
||||
"serverCreateName": "Server name must be a string with a minimum length of 2 and must not include: \\ / or # ",
|
||||
"serverExeCommand": "Server execution command must be a string with a minimum length of 1.",
|
||||
"serverLogPath": "Server log path must be a string with a minimum length of 1",
|
||||
"taskIntervalType": "Task Interval Type must be one of the following: ",
|
||||
"typeBool": "must be true or false (type boolean)",
|
||||
"typeEmail": "must be of type email.",
|
||||
"typeIntMinVal0": "must be an integer with a minimum value of 0.",
|
||||
"typeInteger": "must be a number.",
|
||||
"typeList": "must be of type list/array ",
|
||||
"typeString": "must be of type string.",
|
||||
"userName": " must be of type string, all LOWERCASE, a minimum of 4 characters and a max of 20 characters"
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "Are you sure you want to delete this webhook?",
|
||||
|
@ -29,7 +29,6 @@
|
||||
"permName": "Nombre del Permiso",
|
||||
"perms": "Permisos",
|
||||
"server": "Servidor: ",
|
||||
"superUser": "Super Usuario",
|
||||
"yes": "Si"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Imprimir"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "No hay datos disponibles en la tabla",
|
||||
"info": "Mostrando _START_ hasta _END_ de _TOTAL_ entradas",
|
||||
"infoEmpty": "Mostrando 0 de 0 entradas",
|
||||
"infoFiltered": "(filtrado de _MAX_ entradas totales)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Mostrar entradas de _MENU_",
|
||||
"loadingRecords": "Cargando...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "y el ",
|
||||
"return": "Volver al panel de control",
|
||||
"selfHost": "Si estás autoalojando este repositorio, revisa tu dirección o consulta nuestra guía de solución de problemas.",
|
||||
"serverJars1": "API de Servidor JAR no disponible. por favor, compruebe",
|
||||
"serverJars2": "para la información más actualizada.",
|
||||
"start-error": "Servidor {} fallo al iniciar con código de error: {}",
|
||||
"superError": "Debes ser un super usuario para completar esta acción.",
|
||||
"terribleFailure": "¡Un terrible error!"
|
||||
@ -554,7 +551,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Introducir tu comando",
|
||||
"delay-explained": "El agente/servicio se inicio recientemente y está retrasando iniciar la instancia del servidor de Minecraft.",
|
||||
"downloading": "Descargando...",
|
||||
"importing": "Importando...",
|
||||
"installing": "Instalando...",
|
||||
"restart": "Reiniciar",
|
||||
|
@ -28,7 +28,6 @@
|
||||
"permName": "Käyttoikeuden nimi",
|
||||
"perms": "Käyttoikeudet",
|
||||
"server": "Palvelin: ",
|
||||
"superUser": "Järjestelmänvalvoja",
|
||||
"yes": "Kyllä"
|
||||
},
|
||||
"base": {
|
||||
@ -127,12 +126,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Tulosta"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Tietoja ei löytynyt",
|
||||
"info": "Näytetään rivit _START_ - _END_ (yhteensä _TOTAL_ )",
|
||||
"infoEmpty": "Näytetään 0 - 0 (yhteensä 0)",
|
||||
"infoFiltered": "(suodatettu _MAX_ tuloksen joukosta)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Näytä kerralla _MENU_ riviä",
|
||||
"loadingRecords": "Ladataan...",
|
||||
"paginate": {
|
||||
@ -147,40 +146,16 @@
|
||||
"cells": {
|
||||
"0": "Klikkaa solua valitaksesi sen",
|
||||
"1": "Yksi solu valittuna",
|
||||
"2": "Kaksi solua valittuna",
|
||||
"3": "Kolme solua valittuna",
|
||||
"4": "Neljä solua valittuna",
|
||||
"5": "Viisi solua valittuna",
|
||||
"6": "Kuusi solua valittuna",
|
||||
"7": "Seitsemän solua valittuna",
|
||||
"8": "Kahdeksan solua valittuna",
|
||||
"9": "Yhdeksän solua valittuna",
|
||||
"_": "%d solua valittuna"
|
||||
},
|
||||
"columns": {
|
||||
"0": "Klikkaa saraketta valitaksesi sen",
|
||||
"1": "Yksi sarake valittuna",
|
||||
"2": "Kaksi saraketta valittuna",
|
||||
"3": "Kolme saraketta valittuna",
|
||||
"4": "Neljä saraketta valittuna",
|
||||
"5": "Viisi saraketta valittuna",
|
||||
"6": "Kuusi saraketta valittuna",
|
||||
"7": "Seitsemän saraketta valittuna",
|
||||
"8": "Kahdeksan saraketta valittuna",
|
||||
"9": "Yhdeksän saraketta valittuna",
|
||||
"_": "%d saraketta valittuna"
|
||||
},
|
||||
"rows": {
|
||||
"0": "Klikkaa riviä valitaksesi sen",
|
||||
"1": "Yksi rivi valittuna",
|
||||
"2": "Kaksi riviä valittuna",
|
||||
"3": "Kolme riviä valittuna",
|
||||
"4": "Neljä riviä valittuna",
|
||||
"5": "Viisi riviä valittuna",
|
||||
"6": "Kuusi riviä valittuna",
|
||||
"7": "Seitsemän riviä valittuna",
|
||||
"8": "Kahdeksan riviä valittuna",
|
||||
"9": "Yhdeksän riviä valittuna",
|
||||
"_": "%d riviä valittuna"
|
||||
}
|
||||
},
|
||||
@ -468,7 +443,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Kirjoita komento",
|
||||
"delay-explained": "Palvelu/agentti on äskettäin aloittanut ja viivästyttää minecraft -palvelimen ilmentymän alkua",
|
||||
"downloading": "Ladataan...",
|
||||
"restart": "Uudelleen­käynnistä",
|
||||
"sendCommand": "Lähetä komento",
|
||||
"start": "Käynnistä",
|
@ -29,7 +29,6 @@
|
||||
"permName": "Nom de la Permission",
|
||||
"perms": "Permissions",
|
||||
"server": "Serveur: ",
|
||||
"superUser": "Super Utilisateur",
|
||||
"yes": "Oui"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Imprimer"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Aucune donnée disponible dans le table",
|
||||
"info": "Affichage de _START_ to _END_ entrées sur _TOTAL_",
|
||||
"infoEmpty": "Affichage des entrées 0 à 0 sur 0 entrées",
|
||||
"infoFiltered": "(filtré sur un total de _MAX_ entrées)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Afficher _MENU_ entrées",
|
||||
"loadingRecords": "Chargement ...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "et le ",
|
||||
"return": "Revenir au Tableau de Bord",
|
||||
"selfHost": "Si vous hébergez vous-même ce repo, veuillez vérifier votre adresse et votre guide de dépannage.",
|
||||
"serverJars1": "l'API Server JARs est inaccessible. Merci de vérifier",
|
||||
"serverJars2": "pour les informations les plus à jour.",
|
||||
"start-error": "Le serveur {} n'a pas pu démarrer avec le code d'erreur : {}",
|
||||
"superError": "Tu dois être un super utilisateur pour effectuer cette action.",
|
||||
"terribleFailure": "C'est une Terrible Erreur !"
|
||||
@ -554,7 +551,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Entre ta commande",
|
||||
"delay-explained": "Le service/agent a récemment démarré et retarde le démarrage de l'instance du serveur minecraft",
|
||||
"downloading": "Téléchargement ...",
|
||||
"importing": "Importation ...",
|
||||
"installing": "Installation ...",
|
||||
"restart": "Redémarrer",
|
||||
|
@ -28,7 +28,6 @@
|
||||
"permName": "Namme fan tastimming",
|
||||
"perms": "Tastimmingen",
|
||||
"server": "Server: ",
|
||||
"superUser": "Superbrûker",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"base": {
|
||||
@ -126,12 +125,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Ôfdrukke"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Gjin gegevens beskikber yn tabel",
|
||||
"info": "Toant _START_ oant _END_ fan _TOTAL_ ynstjoerings",
|
||||
"infoEmpty": "Toant 0 oan 0 fan 0 ynstjoerings",
|
||||
"infoFiltered": "(filtrearre út _MAX_ totaal ynstjoerings)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Lit _MENU_ ynstjoerings sjen",
|
||||
"loadingRecords": "Laden...",
|
||||
"paginate": {
|
||||
@ -437,7 +436,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Fier jo kommando yn",
|
||||
"delay-explained": "De tsjinst / agint is koartlyn begon en fertraget it begjin fan 'e Minecraft-server",
|
||||
"downloading": "Ynladen...",
|
||||
"restart": "Opnij starte",
|
||||
"sendCommand": "Kommando stjoere",
|
||||
"start": "Starte",
|
@ -29,7 +29,6 @@
|
||||
"permName": "שם הגישה",
|
||||
"perms": "גישות",
|
||||
"server": "שרת: ",
|
||||
"superUser": "משתמש על",
|
||||
"yes": "כן"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "הדפסה"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "אין נתונים זמינים בטבלה",
|
||||
"info": "רשומות _TOTAL_ מ _END_ עד _START_ מראה",
|
||||
"infoEmpty": "מציג 0 עד 0 מתוך 0 ערכים",
|
||||
"infoFiltered": "(רשומות _MAX_ מסונן מתוך)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "רשומות _MENU_ הצגת",
|
||||
"loadingRecords": "...טוען",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "וה",
|
||||
"return": "חזרה לפאנל",
|
||||
"selfHost": "אם אתה מארח בעצמך את הריפו הזה, אנא בדוק את הכתובת שלך או התייעץ עם מדריך פתרון הבעיות שלנו.",
|
||||
"serverJars1": "API של צנצנות השרת אינו נגיש. אנא בדוק",
|
||||
"serverJars2": "למידע מעודכן ביותר.",
|
||||
"start-error": "השרת {} לא הצליח להתחיל עם קוד שגיאה: {}",
|
||||
"superError": "חובה להיות משתמש על כדי לבצע פעולה זו.",
|
||||
"terribleFailure": "איזה כישלון נורא!"
|
||||
@ -554,7 +551,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "הקלידו את הפקודה שלכם",
|
||||
"delay-explained": "השירות/סוכן התחיל לאחרונה והוא מעכב את הדלקת שרת המיינקראפט",
|
||||
"downloading": "...מוריד",
|
||||
"importing": "מייבא...",
|
||||
"installing": "מתקין...",
|
||||
"restart": "הפעלה מחדש",
|
||||
|
@ -28,7 +28,6 @@
|
||||
"permName": "Naziv dopuštenja",
|
||||
"perms": "Dopuštenja",
|
||||
"server": "Poslužitelj: ",
|
||||
"superUser": "Superkorisnik",
|
||||
"yes": "Da"
|
||||
},
|
||||
"base": {
|
||||
@ -126,12 +125,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Isprintaj"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Nema dostupnih podataka u tablici",
|
||||
"info": "Prikazuje se _START_ do _END_ od _TOTAL_ unosa",
|
||||
"infoEmpty": "Prikazuje se 0 do 0 od 0 unosa",
|
||||
"infoFiltered": "(filtrirano od ukupno _MAX_ unosa)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Prikaži _MENU_ unose",
|
||||
"loadingRecords": "Učitavanje...",
|
||||
"paginate": {
|
||||
@ -437,7 +436,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Unesi naredbu",
|
||||
"delay-explained": "Usluga je nedavno započeta i odgađa pokretanje instance poslužitelja Minecrafta",
|
||||
"downloading": "Preuzimanje...",
|
||||
"restart": "Ponovno pokreni",
|
||||
"sendCommand": "Pošalji naredbu",
|
||||
"start": "Pokreni",
|
@ -28,7 +28,6 @@
|
||||
"permName": "Nama Izin",
|
||||
"perms": "Izin",
|
||||
"server": "Server: ",
|
||||
"superUser": "Super User",
|
||||
"yes": "Iya"
|
||||
},
|
||||
"base": {
|
||||
@ -127,12 +126,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Print"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Tidak Ada Data Yang Ada Di Meja",
|
||||
"info": "Showing _START_ to _END_ of _TOTAL_ entries",
|
||||
"infoEmpty": "Showing 0 to 0 of 0 entries",
|
||||
"infoFiltered": "(filtered from _MAX_ total entries)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"loadingRecords": "Loading...",
|
||||
"paginate": {
|
||||
@ -444,7 +443,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Masukan Perintah Anda",
|
||||
"delay-explained": "Layanan / agen baru-baru ini dimulai dan menunda dimulainya instans server minecraft",
|
||||
"downloading": "Mengunduh...",
|
||||
"restart": "Mulai Ulang",
|
||||
"sendCommand": "Kirim Perintah",
|
||||
"start": "Mulai",
|
@ -29,7 +29,6 @@
|
||||
"permName": "Nome Permesso",
|
||||
"perms": "Permessi",
|
||||
"server": "Server: ",
|
||||
"superUser": "Super User",
|
||||
"yes": "Sì"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Stampa"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Nessun dato disponibile nella tabella",
|
||||
"info": "Mostro da _START_ a _END_ di _TOTAL_ record",
|
||||
"infoEmpty": "Mostro da 0 a 0 di 0 record",
|
||||
"infoFiltered": "(filtrato da _MAX_ record totali)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Mostra _MENU_ record",
|
||||
"loadingRecords": "Carico...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "e il ",
|
||||
"return": "Torna alla pagina iniziale",
|
||||
"selfHost": "se stai ospitando te questo repo, controlla il tuo indirizzo o consulta la nostra guida di risoluzione dei problemi.",
|
||||
"serverJars1": "API JAR del server non raggiungibile. Si prega di controllare",
|
||||
"serverJars2": "per informazioni più aggiornate.",
|
||||
"start-error": "Server {} failed to start with error code: {}",
|
||||
"superError": "Devi essere un super utente per eseguire questa azione.",
|
||||
"terribleFailure": "What a Terrible Failure!"
|
||||
@ -238,7 +235,9 @@
|
||||
"finishedPreparing": "Abbiamo finito di preparare i tuoi registri di supporto.Per favore clicca Scarica per scaricarli",
|
||||
"logout": "Disconnessione",
|
||||
"preparingLogs": "Per favore aspetta mentre prepariamo i tuoi registri... Ti invieremo una notifica quando saranno pronti. Potrebbe volerci un po' per installazioni grosse.",
|
||||
"supportLogs": "Registri di supporto"
|
||||
"supportLogs": "Registri di supporto",
|
||||
"backup_desc": "Abbiamo rilevato che la migrazione del backup potrebbe essere parzialmente o completamente fallita. Controlla i backup effettuati nella scheda Backup.",
|
||||
"backup_title": "Avviso migrazione di backup"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "Disconnesso",
|
||||
@ -554,7 +553,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Inserisci il comando",
|
||||
"delay-explained": "Il servizio/agente è stato avviato di recente e sta ritardando l'avvio del server di Minecraft",
|
||||
"downloading": "Scaricando...",
|
||||
"importing": "Importazione...",
|
||||
"installing": "Installazione...",
|
||||
"restart": "Riavvia",
|
||||
@ -672,7 +670,10 @@
|
||||
"uses": "Numero di usi permessi (-1==Nessun limite)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "La password è troppo corta. Lunghezza minima: 8"
|
||||
"passLength": "La password è troppo corta. Lunghezza minima: 8",
|
||||
"enumErr": "Validazione fallita. Valori accettabili includono: ",
|
||||
"serverExeCommand": "Il comando di esecuzione del server dev’essere una stringa con lunghezza minima di 1.",
|
||||
"serverLogPath": "Il percorso del registro del server dev’essere una stringa con lunghezza minima di 1"
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "Sei sicuro di voler eliminare questo webhook?",
|
||||
|
721
app/translations/ja_JP.json
Normal file
721
app/translations/ja_JP.json
Normal file
@ -0,0 +1,721 @@
|
||||
{
|
||||
"error": {
|
||||
"cancel": "キャンセル",
|
||||
"agree": "同意",
|
||||
"bedrockError": "Bedrockダウンロードは利用できませんでした。確認してください",
|
||||
"bigBucket1": "Big Bucketヘルスチェックは失敗しました。確認してください",
|
||||
"bigBucket2": "最新の情報を確認してください。",
|
||||
"contact": "DiscordでCraftyサポートに連絡",
|
||||
"craftyStatus": "Crafty ステータスページ",
|
||||
"cronFormat": "無効な Cronフォーマットを検知",
|
||||
"embarassing": "いやあ、これは恥ずかしいですなあ。",
|
||||
"error": "エラー!",
|
||||
"eulaAgree": "同意しますか?",
|
||||
"eulaMsg": "同意する必要があります: ",
|
||||
"eulaTitle": "EULAに同意",
|
||||
"fileError": "ファイルの種類は画像である必要があります。",
|
||||
"fileTooLarge": "アップロードに失敗しました。ファイルが大きすぎます。アップロードしたい場合は、システム管理者に連絡してください。",
|
||||
"hereIsTheError": "エラーが発生しました",
|
||||
"installerJava": "インストール失敗 {} : ForgeサーバーのインストールにはJavaが必要です。 Javaがインストールされていないことを検知しました。Javaをインストールした後に、サーバーをインストールしてください。",
|
||||
"internet": "Craftyが実行中のサーバーが、インターネットに接続されていないことを検知しました。クライアントのサーバーへの接続が制限されるかもしれません。",
|
||||
"migration": "Craftyのメインサーバーのストレージが新しいサーバーへ移行中です。そのため全てのサーバーの起動が遅延されています。この移行が終わるまでお待ちください",
|
||||
"no-file": "要求されたファイルを移動することができないようです。パスを再確認して、Craftyに適切な権限があるかを確認してください。",
|
||||
"noInternet": "インターネットへの接続に問題があります。 サーバーの作成は無効になっています。インターネットへの接続を確認し、ページを更新してください。",
|
||||
"noJava": "サーバー {} は起動に失敗しました。エラーコード: Javaがインストールされていないことを検知しました。Javaをインストールした後に、サーバーをインストールしてください。",
|
||||
"not-downloaded": "実行ファイルが見つかりません。実行ファイルのダウンロードが終了しているか、実行権限があるかを確認してください。",
|
||||
"portReminder": "今回が {} のはじめての起動であることを検知しました。インターネットからリモートアクセスできるように、ルータ・ファイヤーウォールでポート{}を転送してください。",
|
||||
"privMsg": "と ",
|
||||
"return": "ダッシュボードに戻る",
|
||||
"selfHost": "このリポジトリをセルフホストしている場合は、アドレスを確認し、トラブルシューティングを参照してください。",
|
||||
"start-error": "サーバー {} は起動に失敗しました。エラーコード: {}",
|
||||
"superError": "この動作を実行するには管理者である必要があります。",
|
||||
"terribleFailure": "深刻なエラーが発生しました!"
|
||||
},
|
||||
"serverDetails": {
|
||||
"terminal": "ターミナル",
|
||||
"backup": "バックパップ",
|
||||
"config": "設定",
|
||||
"files": "ファイル",
|
||||
"filter": "フィルターされたログ",
|
||||
"filterList": "フィルターする単語",
|
||||
"logs": "ログ",
|
||||
"metrics": "メトリクス",
|
||||
"playerControls": "プレイヤー管理",
|
||||
"reset": "スクロールをリセット",
|
||||
"schedule": "スケジュール",
|
||||
"serverDetails": "サーバー情報"
|
||||
},
|
||||
"webhooks": {
|
||||
"name": "名前",
|
||||
"new": "新しいウェブフック",
|
||||
"newWebhook": "新しいウェブフック",
|
||||
"no-webhook": "このサーバーには現在ウェブフックがありません。クリックして作成してください",
|
||||
"run": "ウェブフックをテストする",
|
||||
"send_command": "サーバーがコマンドを受け取りました",
|
||||
"start_server": "サーバーが起動しました",
|
||||
"stop_server": "サーバーが停止しました",
|
||||
"trigger": "トリガー",
|
||||
"type": "ウェブフックの種類",
|
||||
"url": "ウェブフックのURL",
|
||||
"areYouSureDel": "このウェブフックを削除しますか?",
|
||||
"areYouSureRun": "このウェブフックをテストしますか?",
|
||||
"backup_server": "サーバーのバックアップが完了しました",
|
||||
"bot_name": "ボットの名前",
|
||||
"color": "アクセント色を選択",
|
||||
"crash_detected": "サーバーがクラッシュしました",
|
||||
"edit": "編集",
|
||||
"enabled": "有効化",
|
||||
"jar_update": "サーバーの実行ファイルがアップデートされました",
|
||||
"kill": "サーバーが終了しました",
|
||||
"webhook_body": "ウェブフックの本文",
|
||||
"webhooks": "すべてのウェブフック"
|
||||
},
|
||||
"404": {
|
||||
"contact": "DiscordでCraftyサポートに連絡",
|
||||
"notFound": "ページが見つかりませんでした",
|
||||
"unableToFind": "お探しのページが見つかりませんでした。再度お試しいただくか、元のページに戻りページを更新してください。"
|
||||
},
|
||||
"accessDenied": {
|
||||
"accessDenied": "アクセス拒否",
|
||||
"contact": "DiscordでCraftyサポートに連絡",
|
||||
"contactAdmin": "このページにアクセスするにはサーバー管理者に連絡してください。アクセスできるはずなのにページにアクセスできない場合は、サポートに連絡してください。",
|
||||
"noAccess": "このページにアクセスすることができませんでした"
|
||||
},
|
||||
"apiKeys": {
|
||||
"apiKeys": "APIキー",
|
||||
"auth": "認証されていますか? ",
|
||||
"buttons": "ボタン",
|
||||
"config": "設定",
|
||||
"crafty": "Crafty: ",
|
||||
"createNew": "新しいAPIトークンを作成",
|
||||
"created": "作成済み",
|
||||
"deleteKeyConfirmation": "このAPIキーを削除してもよろしいですか。この操作は元に戻せません。",
|
||||
"deleteKeyConfirmationTitle": "APIキー:${keyId} を削除してもよろしいですか?",
|
||||
"fullAccess": "フルアクセス",
|
||||
"getToken": "APIトークンを取得",
|
||||
"name": "名前",
|
||||
"nameDesc": "このAPIトークンをどのように呼びますか。 ",
|
||||
"no": "いいえ",
|
||||
"pageTitle": "ユーザーのAPIキーを編集",
|
||||
"permName": "権限名",
|
||||
"perms": "権限",
|
||||
"server": "サーバー: ",
|
||||
"yes": "はい"
|
||||
},
|
||||
"base": {
|
||||
"doesNotWorkWithoutJavascript": "<strong>警告: </strong>JavaScriptが無効の状態では、Craftyは正常に動作しない恐れがあります!"
|
||||
},
|
||||
"credits": {
|
||||
"developmentTeam": "開発チーム",
|
||||
"hugeDesc": "多大なる",
|
||||
"pageDescription": "この方々のご支援がなくては、Craftyは存在しません",
|
||||
"pageTitle": "クレジット",
|
||||
"patreonDesc": "私たちの Patreon / Ko-fi の支援者たちに!",
|
||||
"patreonOther": "その他",
|
||||
"patreonSupporter": "Patreon / Ko-fi でのご支援者",
|
||||
"patreonUpdate": "最終更新日時:",
|
||||
"retiredStaff": "引退したスタッフ",
|
||||
"subscriberName": "お名前",
|
||||
"subscriptionLevel": "レベル",
|
||||
"supportTeam": "サポート・ドキュメントチーム",
|
||||
"thankYou": "ありがとう",
|
||||
"translationDesc": "私たちのコミュニティを翻訳している方たちです! [ 活動中 = 🟢 休止中・引退済み = ⚪ ]",
|
||||
"translationName": "言語名",
|
||||
"translationTitle": "多言語への翻訳",
|
||||
"translator": "翻訳者"
|
||||
},
|
||||
"customLogin": {
|
||||
"apply": "適用",
|
||||
"backgroundUpload": "背景アップロード",
|
||||
"customLoginPage": "ログインページをカスタマイズ",
|
||||
"delete": "削除",
|
||||
"labelLoginImage": "ログインページの背景を選択してください",
|
||||
"loginBackground": "ログインページの背景画像",
|
||||
"loginImage": "ログイン画面に表示する背景画像をアップロードしてください。",
|
||||
"loginOpacity": "ログインフォームの透明度を選択",
|
||||
"pageTitle": "ログインページをカスタマイズ",
|
||||
"preview": "プレビュー",
|
||||
"select": "選択",
|
||||
"selectImage": "画像を選択"
|
||||
},
|
||||
"dashboard": {
|
||||
"actions": "操作",
|
||||
"allServers": "サーバー一覧",
|
||||
"avg": "平均",
|
||||
"backups": "バックアップ",
|
||||
"bePatientClone": "サーバーを複製している間、しばらくお待ちください。<br /> この画面はしばらくした後に更新されます",
|
||||
"bePatientRestart": "サーバーを再起動している間、しばらくお待ちください。<br /> この画面はしばらくした後に更新されます",
|
||||
"bePatientStart": "サーバーを起動している間、しばらくお待ちください。<br /> この画面はしばらくした後に更新されます",
|
||||
"bePatientStop": "サーバーを停止している間、しばらくお待ちください。<br /> この画面はしばらくした後に更新されます",
|
||||
"cannotSee": "すべて表示されていますか?",
|
||||
"cannotSeeOnMobile": "モバイルですべて表示されていませんか?",
|
||||
"cannotSeeOnMobile2": "左右に表をスクロールしてみてください。",
|
||||
"clone": "複製",
|
||||
"cloneConfirm": "このサーバーを複製しますか。この処理には時間を要します。",
|
||||
"cpuCores": "CPU コア数",
|
||||
"cpuCurFreq": "CPU クロック周波数",
|
||||
"cpuMaxFreq": "CPU 最大クロック周波数",
|
||||
"cpuUsage": "CPU 使用率",
|
||||
"crashed": "クラッシュ",
|
||||
"dashboard": "ダッシュボード",
|
||||
"delay-explained": "サービス・エージェントが先ほど起動したため、マインクラフトサーバーインスタンスの起動を遅らせています",
|
||||
"host": "ホスト",
|
||||
"installing": "インストール中...",
|
||||
"kill": "プロセスを終了",
|
||||
"killing": "プロセスを終了中...",
|
||||
"lastBackup": "最終:",
|
||||
"max": "最大",
|
||||
"memUsage": "メモリ使用率",
|
||||
"motd": "MOTD (サーバー説明文)",
|
||||
"newServer": "新しいサーバーを作成",
|
||||
"nextBackup": "次回:",
|
||||
"no-servers": "サーバーがありません。ボタンをクリックして開始してください",
|
||||
"offline": "オフライン",
|
||||
"online": "オンライン",
|
||||
"players": "プレイヤー数",
|
||||
"restart": "再起動",
|
||||
"sendingCommand": "コマンドを送信",
|
||||
"server": "サーバー",
|
||||
"servers": "サーバー数",
|
||||
"size": "サーバーディレクトリサイズServer Dir Size",
|
||||
"start": "起動",
|
||||
"starting": "遅延して起動",
|
||||
"status": "状態",
|
||||
"stop": "終了",
|
||||
"storage": "ストレージ",
|
||||
"version": "バージョン",
|
||||
"welcome": "Craftyコントローラーへようこそ"
|
||||
},
|
||||
"datatables": {
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": 行を昇順に並び替え中",
|
||||
"sortDescending": ": 行を降順に並び替え中"
|
||||
},
|
||||
"buttons": {
|
||||
"collection": "コレクション <span class='ui-button-icon-primary ui-icon ui-icon-triangle-1-s'/>",
|
||||
"colvis": "列を非表示にする",
|
||||
"colvisRestore": "列を再表示する",
|
||||
"copy": "コピー",
|
||||
"copyKeys": "ctrlキーか、 u2318 + C を教えて表のデータをクリップボードにコピーしてください。<br><br>取り消すためには、このメッセージをクリックするか、Escキーを教えてください。",
|
||||
"copySuccess": {
|
||||
"1": "1行をクリップボードにコピー",
|
||||
"_": "%d行をクリップボードにコピー"
|
||||
},
|
||||
"copyTitle": "クリップボードにコピー",
|
||||
"csv": "CSV",
|
||||
"excel": "Excel",
|
||||
"pageLength": {
|
||||
"-1": "すべての行を表示",
|
||||
"1": "1行を表示",
|
||||
"_": "%d行を表示"
|
||||
},
|
||||
"pdf": "PDF",
|
||||
"print": "印刷"
|
||||
},
|
||||
"emptyTable": "利用可能なデータがありません",
|
||||
"info": "_START_ 件目から _END_ 件目までの _TOTAL_ 件のデータを表示中",
|
||||
"infoEmpty": "0 件目から 0 件目までの 0 件のデータを表示中",
|
||||
"infoFiltered": "(filtered from _MAX_ total entries)",
|
||||
"lengthMenu": "_MENU_ 件のメニューを表示中",
|
||||
"loadingRecords": "読み込み中...",
|
||||
"paginate": {
|
||||
"first": "最初へ",
|
||||
"last": "最後へ",
|
||||
"next": "次へ",
|
||||
"previous": "前へ"
|
||||
},
|
||||
"processing": "処理中...",
|
||||
"search": "検索:",
|
||||
"select": {
|
||||
"cells": {
|
||||
"0": "セルを選択するにはクリックしてください",
|
||||
"1": "%d 個のセルが選択中",
|
||||
"_": "%d 個のセルが選択中"
|
||||
},
|
||||
"columns": {
|
||||
"0": "列を選択するにはクリックしてください",
|
||||
"1": "%d 列が選択中",
|
||||
"_": "%d 列が選択中"
|
||||
},
|
||||
"rows": {
|
||||
"0": "行を選択するにはクリックしてください",
|
||||
"1": "%d 行が選択中",
|
||||
"_": "%d 行が選択中"
|
||||
}
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "条件に当てはまるデータがありませんでした",
|
||||
"decimal": ".",
|
||||
"infoPostFix": "|"
|
||||
},
|
||||
"loadingRecords": "読み込み中..."
|
||||
},
|
||||
"footer": {
|
||||
"allRightsReserved": "無断複写・転載を禁じます",
|
||||
"copyright": "Copyright",
|
||||
"version": "バージョン"
|
||||
},
|
||||
"login": {
|
||||
"defaultPath": "入力されたパスワードは、デフォルト証明書のパスであり、パスワードではありません。そのパスからデフォルトパスワードを見つけて入力してください。",
|
||||
"disabled": "ユーザーアカウントは無効です。詳細な情報を得るにはシステム管理者に連絡してください。",
|
||||
"forgotPassword": "パスワードを忘れた場合",
|
||||
"incorrect": "ユーザー名・パスワードが正しくありません",
|
||||
"login": "ログイン",
|
||||
"password": "パスワード",
|
||||
"username": "ユーザー名",
|
||||
"viewStatus": "公開ステータスページを確認"
|
||||
},
|
||||
"notify": {
|
||||
"activityLog": "アクティブログ",
|
||||
"backupComplete": "サーバー {} のバックアップは正常に完了しました。",
|
||||
"backupStarted": "サーバー {} のバックアップが開始しました。",
|
||||
"downloadLogs": "サポートログをダウンロードしますか?",
|
||||
"finishedPreparing": "サポートログの準備が完了しました。クリックしてダウンロードしてください",
|
||||
"logout": "ログアウト",
|
||||
"preparingLogs": " ログを準備している間しばらくお待ちください... 準備が出来たら通知を送ります。大容量のファイルの展開には時間がかかることがあります。",
|
||||
"supportLogs": "サポートログ",
|
||||
"backup_desc": "バックアップの移行が失敗しました。バックアップタブからバックアップの記録を確認してください。",
|
||||
"backup_title": "バックアップの移行についての警告",
|
||||
"schedule_desc": "スケジュールタスクがアップグレード中に完全に移行できなかったことを検知しました。スケジュールタブからスケジュールを確認してください。",
|
||||
"schedule_title": "スケジュールの移行についての警告"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "オフライン",
|
||||
"pleaseConnect": "Craftyを使うにはインターネットに接続してください。"
|
||||
},
|
||||
"panelConfig": {
|
||||
"adminControls": "管理者コントロール",
|
||||
"allowedServers": "許可されたサーバー",
|
||||
"apply": "適用",
|
||||
"assignedRoles": "割り当てられたロール",
|
||||
"cancel": "キャンセル",
|
||||
"clearComms": "未実行のコマンドを削除",
|
||||
"custom": "Cratfyをカスタマイズ",
|
||||
"delete": "削除",
|
||||
"edit": "編集",
|
||||
"enableLang": "すべての言語を有効化",
|
||||
"enabled": "有効",
|
||||
"globalExplain": "Craftyがサーバーファイルを保存する場所です。 (Craftyは /servers/[uuid of server] 内に保存します。)",
|
||||
"globalServer": "グローバルサーバーディレクトリ",
|
||||
"json": "Config.json",
|
||||
"match": "パスワードが一致する必要があります",
|
||||
"newRole": "新しいロールを作成",
|
||||
"newUser": "新しいユーザーを作成",
|
||||
"noMounts": "ダッシュボードにマウントを表示しない",
|
||||
"pageTitle": "パネル設定",
|
||||
"role": "ロール",
|
||||
"roleUsers": "ユーザー",
|
||||
"roles": "すべてのロール",
|
||||
"save": "保存",
|
||||
"select": "選択",
|
||||
"superConfirm": "このユーザーにすべて(全ユーザーアカウント、サーバー、パネル設定など)の権限を付与したいときのみ実行してください。このユーザーはあなたのスーパーユーザー権限をはく奪することもできます。",
|
||||
"superConfirmTitle": "スーパーユーザーを有効化しますが、よろしいですか?",
|
||||
"title": "Craftyの設定",
|
||||
"user": "ユーザー",
|
||||
"users": "すべてのユーザー"
|
||||
},
|
||||
"rolesConfig": {
|
||||
"config": "ロール設定",
|
||||
"configDesc": "ここでロールの設定を変えることができます",
|
||||
"configUpdate": "最終更新: ",
|
||||
"created": "作成: ",
|
||||
"delRole": "削除済みのロール",
|
||||
"doesNotExist": "存在しないものを削除するととはできません",
|
||||
"pageTitle": "ロールを編集",
|
||||
"pageTitleNew": "新しいロールを作成",
|
||||
"permAccess": "アクセス?",
|
||||
"permName": "権限名",
|
||||
"permsServer": "一部のサーバーに対して、このロールが持つ権限",
|
||||
"roleConfigArea": "ロール編集画面",
|
||||
"roleDesc": "このロールをどのように呼びますか?",
|
||||
"roleName": "ロール名: ",
|
||||
"rolePerms": "ロールの権限",
|
||||
"roleServers": "許可のあるサーバー",
|
||||
"roleTitle": "ロールの設定",
|
||||
"roleUserName": "ユーザー名",
|
||||
"roleUsers": "ユーザー一覧: ",
|
||||
"selectManager": "このロールのマネージャーを選択",
|
||||
"serverAccess": "閲覧可能か",
|
||||
"serverName": "サーバー名",
|
||||
"serversDesc": "アクセスを許可するサーバーを選択してください"
|
||||
},
|
||||
"serverBackups": {
|
||||
"actions": "操作",
|
||||
"after": "バックアップ後にコマンドを実行",
|
||||
"backupAtMidnight": "真夜中に自動でバックパップを実行するか",
|
||||
"backupNow": "今すぐバックアップ!",
|
||||
"backupTask": "バックパップ処理が開始しました。",
|
||||
"backups": "サーバーのバックアップ",
|
||||
"before": "バックアップ前にコマンドを実行",
|
||||
"cancel": "キャンセル",
|
||||
"clickExclude": "除外するファイルを選択",
|
||||
"compress": "バックパップを圧縮",
|
||||
"confirm": "確認",
|
||||
"confirmDelete": "このバックアップを削除しますか。この操作は元に戻せません。",
|
||||
"confirmRestore": "このバックアップを復元しますか。現在のサーバーファイルはバックパップ時のものに変更され、復元することができません。",
|
||||
"currentBackups": "バックパップ一覧",
|
||||
"default": "デフォルトのバックアップ",
|
||||
"defaultExplain": "更新前にCraftyが使用するバックアップです。変更・削除することができません。",
|
||||
"delete": "削除",
|
||||
"destroyBackup": "\" + file_to_del + \"を削除しますか?",
|
||||
"download": "ダウンロード",
|
||||
"edit": "編集",
|
||||
"enabled": "有効化",
|
||||
"excludedBackups": "除外されるパス: ",
|
||||
"excludedChoose": "バックアップから除外するパスを選択してください",
|
||||
"exclusionsTitle": "バックアップの除外設定",
|
||||
"failed": "失敗",
|
||||
"maxBackups": "最大バックパップ数",
|
||||
"maxBackupsDesc": "Craftyは古いバックアップを削除することで、N個より多くのバックアップを保存しません。(0を入力するとすべてのバックアップを保存します。)",
|
||||
"myBackup": "新しいバックパップ",
|
||||
"name": "名前",
|
||||
"newBackup": "新しいバックパップを作成",
|
||||
"no-backup": "バックアップはありません。新しくバックアップの設定を作成するには、ボタンをクリックしてください",
|
||||
"options": "設定",
|
||||
"path": "パス",
|
||||
"restore": "復元",
|
||||
"restoring": "バックアップを復元しています。この処理には時間がかかることがあります。しばらくお待ちください。",
|
||||
"run": "バックアップを実行",
|
||||
"save": "保存",
|
||||
"shutdown": "バックアップ中はサーバーをシャットダウンする",
|
||||
"size": "サイズ",
|
||||
"standby": "待機中",
|
||||
"status": "ステータス",
|
||||
"storage": "バックアップ保存場所",
|
||||
"storageLocation": "保存場所",
|
||||
"storageLocationDesc": "バックアップを保存する場所を選択してください"
|
||||
},
|
||||
"serverConfig": {
|
||||
"bePatientDelete": "サーバーをCraftyパネルから削除する間、しばらくお待ちください。この画面はしばらくした後に閉じられます。",
|
||||
"bePatientDeleteFiles": "サーバーをCraftyパネルから削除し、すべてのファイルを削除する間、しばらくお待ちください。 この画面はしばらくした後に閉じられます。",
|
||||
"bePatientUpdate": "サーバーを更新している間、しばらくお待ちください。ダウンロードに要する時間はインターネット速度によって異なります。<br /> この画面はしばらくした後に更新されます",
|
||||
"cancel": "キャンセル",
|
||||
"countPlayers": "サーバーをプレイヤー数に含める",
|
||||
"crashTime": "クラッシュタイムアウト",
|
||||
"crashTimeDesc": "どのくらいの時間が経てばクラッシュしたとみなしますか?",
|
||||
"deleteFilesQuestion": "ホストからサーバーファイルを削除しますか?",
|
||||
"deleteFilesQuestionMessage": "ホストからサーバーファイルを削除しますか。<br><br><strong>サーバーのバックアップも含まれます。</strong>",
|
||||
"deleteServer": "サーバーを削除",
|
||||
"deleteServerQuestion": "サーバーを削除しますか?",
|
||||
"deleteServerQuestionMessage": "このサーバーを削除しますか。この処理の後にはなにも残りません...",
|
||||
"exeUpdateURL": "サーバー実行ファイルのアップデートURL",
|
||||
"exeUpdateURLDesc": "アップデートをURLから直接ダウンロードします。",
|
||||
"ignoredExits": "無視する終了コード",
|
||||
"ignoredExitsExplain": "Craftyがクラッシュを検知するときに通常終了だと考える終了コード (コンマで区切ってください。)",
|
||||
"javaNoChange": "上書きしない",
|
||||
"javaVersion": "現在のJavaのバージョンを上書き",
|
||||
"javaVersionDesc": "Javaを上書きしようとする場合、「サーバー実行コマンド」にJavaのパスが引用符で囲まれていることを確認してください。(デフォルトの'java'は除外)",
|
||||
"noDelete": "いいえ、元に戻る",
|
||||
"noDeleteFiles": "いいえ、ただパネルから削除する",
|
||||
"removeOldLogsAfter": "古いログを削除する日数",
|
||||
"removeOldLogsAfterDesc": "何日後にログを削除するかを入力してください。(0にすると無効になります。)",
|
||||
"save": "保存",
|
||||
"sendingDelete": "サーバーを削除中",
|
||||
"sendingRequest": "リクエストを送信中...",
|
||||
"serverAutoStart": "サーバーを自動で起動する",
|
||||
"serverAutostartDelay": "サーバーの起動を遅延させる秒数",
|
||||
"serverAutostartDelayDesc": "自動で起動するまでの秒数(有効になっている場合)",
|
||||
"serverCrashDetection": "サーバーのクラッシュを検知する",
|
||||
"serverExecutable": "サーバーの実行ファイル",
|
||||
"serverExecutableDesc": "サーバーの実行ファイル",
|
||||
"serverExecutionCommand": "サーバー実行コマンド",
|
||||
"serverExecutionCommandDesc": "サーバー起動時にターミナルで実行されるコマンド",
|
||||
"serverIP": "サーバーのIPアドレス",
|
||||
"serverIPDesc": "Craftyが統計情報を取得するIPアドレス (問題が生じた場合は、本当のIPアドレスの代わりに 127.0.0.1 を試してください。)",
|
||||
"serverLogLocation": "サーバーログの保存場所",
|
||||
"serverLogLocationDesc": "ログファイルを保存する場所",
|
||||
"serverName": "サーバー名",
|
||||
"serverNameDesc": "このサーバーをどのように呼びますか",
|
||||
"serverPath": "サーバーのディレクトリ",
|
||||
"serverPathDesc": "絶対パスで指定してください。(実行ファイルを含まないでください。)",
|
||||
"serverPort": "サーバーのポート",
|
||||
"serverPortDesc": "Craftyが統計情報を取得するポート",
|
||||
"serverStopCommand": "サーバーの停止コマンド",
|
||||
"serverStopCommandDesc": "サーバーを停止させるときに送信するコマンド",
|
||||
"showStatus": "公開ステータスページにサーバーの状態を表示する",
|
||||
"shutdownTimeout": "シャットダウンするまで秒数",
|
||||
"statsHint1": "サーバーが稼働しているポートをここに入力してください。統計情報を取得するためにCraftyが接続します。",
|
||||
"statsHint2": "これはサーバーのポートを変更するものではありません。ポートを変更するにはサーバーの設定ファイルを変更してください。",
|
||||
"stopBeforeDeleting": "削除する前にサーバーを停止してください",
|
||||
"timeoutExplain1": "サーバーを終了するコマンドを実行した後に、Craftyがプロセスを強制終了するまでに待機する時間",
|
||||
"update": "実行ファイルをアップデート",
|
||||
"yesDelete": "はい、削除してください",
|
||||
"yesDeleteFiles": "はい、ファイルを削除してください",
|
||||
"timeoutExplain2": "実行する前のコマンド"
|
||||
},
|
||||
"serverConfigHelp": {
|
||||
"desc": "ここではサーバーの設定を帰ることができます",
|
||||
"perms": [
|
||||
"Craftyによって管理されている<code>パスを変更しない</code>ことが推奨されています。",
|
||||
"パスを変更することは、特にファイルの権限がより厳密に管理されているLinuxにおいては、<code>システムを損傷させる恐れがあります</code>。",
|
||||
"<br /><br/>",
|
||||
"サーバーの位置を変更する必要がある場合、\"crafty\" ユーザーにサーバーのパスの読み取り・書き込み権限を付与してください。",
|
||||
"<br />",
|
||||
"<br />",
|
||||
"Linuxでは、以下のコマンドを実行することが最善です。<br />",
|
||||
"<code>",
|
||||
" sudo chown crafty:crafty /path/to/your/server -R<br />",
|
||||
" sudo chmod 2775 /path/to/your/server -R<br />",
|
||||
"</code>"
|
||||
],
|
||||
"title": "サーバー設定"
|
||||
},
|
||||
"serverFiles": {
|
||||
"clickUpload": "ここをクリックしてファイルを選択",
|
||||
"close": "閉じる",
|
||||
"createDir": "新しいディレクトリを作成",
|
||||
"createDirQuestion": "新しいディレクトリの名前を入力してください。",
|
||||
"createFile": "新しいファイルを作成",
|
||||
"createFileQuestion": "新しいファイルの名前を入力してください。",
|
||||
"default": "デフォルト",
|
||||
"delete": "削除",
|
||||
"deleteItemQuestion": "\" + name + \"を削除しますか?",
|
||||
"deleteItemQuestionMessage": "\\\"\" + path + \"\\\"を削除しようとしています。!<br/><br/>この操作は復元できず、完全に削除されます!",
|
||||
"download": "ダウンロード",
|
||||
"editingFile": "ファイルを編集",
|
||||
"error": "ファイル取得エラー",
|
||||
"fileReadError": "ファイル読み込みエラー",
|
||||
"files": "ファイル",
|
||||
"keybindings": "キーバインド設定",
|
||||
"loadingRecords": "ファイル読み込み中...",
|
||||
"noDelete": "いいえ",
|
||||
"noscript": "ファイルマネージャーはJavaScriptなしでは正常に動作しません",
|
||||
"rename": "名前を変更",
|
||||
"renameItemQuestion": "変更後の名前を入力してください?",
|
||||
"save": "保存",
|
||||
"size": "エディターの大きさを変更",
|
||||
"stayHere": "このページから移動しないでください!",
|
||||
"unsupportedLanguage": "警告: サポートされていないファイルの種類です",
|
||||
"unzip": "解凍",
|
||||
"upload": "アップロード",
|
||||
"uploadTitle": "アップロード先: ",
|
||||
"waitUpload": "ファイルをアップロードしています。しばらくお待ちください。この処理には時間がかかることがあります。",
|
||||
"yesDelete": "はい、この状況を理解しています"
|
||||
},
|
||||
"serverMetrics": {
|
||||
"resetZoom": "ズームをリセット",
|
||||
"zoomHint1": "グラフをズームするには、シフトキーを押しながらスクロールしてください。",
|
||||
"zoomHint2": "または、シフトキーを押しながら、拡大したい範囲をドラックして選択してください。"
|
||||
},
|
||||
"serverPlayerManagement": {
|
||||
"bannedPlayers": "アクセスが禁止されたプレイヤー",
|
||||
"loadingBannedPlayers": "アクセスが禁止されたプレイヤーを表示中",
|
||||
"players": "プレイヤー"
|
||||
},
|
||||
"serverScheduleConfig": {
|
||||
"backup": "サーバーをバックアップ",
|
||||
"basic": "ベーシック",
|
||||
"children": "関連付けられた子タスク: ",
|
||||
"command": "コマンド",
|
||||
"command-explain": "実行するコマンドを入力してください。'/'を含まないでください。",
|
||||
"cron": "Cron",
|
||||
"cron-explain": "cronの設定を入力してください。-- 注意: 0 = 最後のオプションの月曜日",
|
||||
"custom": "カスタムコマンド",
|
||||
"days": "日ごと",
|
||||
"enabled": "有効化",
|
||||
"hours": "時間ごと",
|
||||
"interval": "実行間隔",
|
||||
"interval-explain": "どの頻度でこのスケジュールを実行しますか?",
|
||||
"minutes": "分ごと",
|
||||
"offset": "遅延オフセット",
|
||||
"offset-explain": "最初のタスクを実行してから、どのくらいの時間待機してからこのコマンドを実行しますか。(秒数)",
|
||||
"one-time": "実行後にこのスケジュールを削除",
|
||||
"parent": "親スケジュールを選択",
|
||||
"parent-explain": "どのスケジュールがこのスケジュール実行されるかを選択してください。",
|
||||
"reaction": "Reaction",
|
||||
"restart": "サーバーを再起動",
|
||||
"select": "Basic / Cron / Chain Reaction を選択",
|
||||
"start": "サーバーを起動",
|
||||
"stop": "サーバーを停止",
|
||||
"time": "実行時刻",
|
||||
"time-explain": "何時何分にスケジュールを実行しますか?"
|
||||
},
|
||||
"serverSchedules": {
|
||||
"action": "操作",
|
||||
"actionId": "子スケジュールを選択",
|
||||
"areYouSure": "スケジュールされたタスクを削除しますか?",
|
||||
"cancel": "キャンセル",
|
||||
"cannotSee": "すべて表示されていますか?",
|
||||
"cannotSeeOnMobile": "詳細を表示するためにはスケジュールされたタスクをクリックしてください。",
|
||||
"child": "子スケジュールのID ",
|
||||
"close": "閉じる",
|
||||
"command": "コマンド",
|
||||
"confirm": "確認",
|
||||
"confirmDelete": "このスケジュールされたタスクを削除しますか。この操作は元に戻せません。",
|
||||
"create": "スケジュールを新しく作成",
|
||||
"cron": "Cron 文字列",
|
||||
"delete": "削除",
|
||||
"details": "スケジュールの詳細",
|
||||
"edit": "編集",
|
||||
"enabled": "有効化",
|
||||
"every": "毎日",
|
||||
"interval": "間隔",
|
||||
"name": "名前",
|
||||
"newSchedule": "新しいスケジュール",
|
||||
"nextRun": "次回実行時",
|
||||
"no": "いいえ",
|
||||
"no-schedule": "このサーバーには現在スケジュールがありません。クリックして作成してください",
|
||||
"scheduledTasks": "スケジュールされたタスク",
|
||||
"yes": "はい"
|
||||
},
|
||||
"serverStats": {
|
||||
"cpuUsage": "CPU使用率",
|
||||
"description": "説明文",
|
||||
"errorCalculatingUptime": "稼働時間計算エラー",
|
||||
"loadingMotd": "MOTD(サーバー説明文)を読み込み中",
|
||||
"memUsage": "メモリ使用率",
|
||||
"offline": "オフライン",
|
||||
"online": "オンライン",
|
||||
"players": "プレイヤー数",
|
||||
"serverStarted": "サーバー最終起動日時",
|
||||
"serverStatus": "サーバーの状態",
|
||||
"serverTime": "UTC時間",
|
||||
"serverTimeZone": "サーバーのタイムゾーン",
|
||||
"serverUptime": "サーバー稼働時間",
|
||||
"starting": "遅延起動",
|
||||
"unableToConnect": "接続不可",
|
||||
"version": "バージョン"
|
||||
},
|
||||
"serverTerm": {
|
||||
"commandInput": "コマンドを送信",
|
||||
"delay-explained": "サービス・エージェントが起動し、マインクラフトサーバーインスタンスの起動を遅らせています",
|
||||
"importing": "インポート中...",
|
||||
"installing": "インストール中...",
|
||||
"restart": "再起動",
|
||||
"sendCommand": "コマンドを送信",
|
||||
"start": "起動",
|
||||
"starting": "遅延起動",
|
||||
"stop": "停止",
|
||||
"stopScroll": "自動スクロールを停止",
|
||||
"updating": "更新中..."
|
||||
},
|
||||
"serverWizard": {
|
||||
"absoluteServerPath": "サーバーファイルの絶対パス",
|
||||
"absoluteZipPath": "サーバーファイルの絶対パス",
|
||||
"addRole": "既存のロールにサーバーを追加する",
|
||||
"autoCreate": "何も選択しない場合、Craftyは新しいロールを作成します!",
|
||||
"bePatient": "必要なファイルを' + (importing ? 'インポート' : 'ダウンロード') + 'している間、しばらくお待ちください",
|
||||
"buildServer": "サーバーを作成",
|
||||
"clickRoot": "ルートディレクトリを選択",
|
||||
"close": "閉じる",
|
||||
"defaultPort": "デフォルトは25565番ポートです",
|
||||
"downloading": "サーバーをダウンロード中...",
|
||||
"explainRoot": "下のボタンをクリックして、アーカイブ内のサーバーのルートディレクトリを選択してください",
|
||||
"importServer": "既存のサーバーをインポート",
|
||||
"importServerButton": "サーバーをインポート",
|
||||
"importZip": "zipファイルからサーバーをインポート",
|
||||
"importing": "サーバーをインポート中...",
|
||||
"labelZipFile": "zipファイルをインポート",
|
||||
"maxMem": "最大メモリ使用量",
|
||||
"minMem": "最小メモリ使用量",
|
||||
"myNewServer": "新しいサーバー",
|
||||
"newServer": "新規でサーバーを作成",
|
||||
"noRole": "検索パラメータにあてはまるロールはありません",
|
||||
"noneRoles": "ロールが選択されていません",
|
||||
"quickSettings": "クイック設定",
|
||||
"quickSettingsDescription": "これらの値は後から変更できます",
|
||||
"resetForm": "リセット",
|
||||
"save": "保存",
|
||||
"selectRole": "ロールを選択",
|
||||
"selectRoot": "アーカイブのルートディレクトリを選択",
|
||||
"selectServer": "サーバーを選択",
|
||||
"selectType": "サーバーの種類を選択 (Vanilla, Servers, Moddedなど)",
|
||||
"selectVersion": "バージョンを選択",
|
||||
"selectZipDir": "ファイルを解凍したいアーカイブのディレクトリを選択",
|
||||
"serverJar": "サーバーの実行ファイルを選択",
|
||||
"serverName": "サーバー名",
|
||||
"serverPath": "サーバーパス",
|
||||
"serverPort": "サーバーポート",
|
||||
"serverSelect": "サーバーを選択",
|
||||
"serverType": "サーバーの種類",
|
||||
"serverUpload": "圧縮されたサーバーファイルをアップロード",
|
||||
"serverVersion": "サーバーバージョン",
|
||||
"sizeInGB": "ファイルサイズ(GB)",
|
||||
"unsupported": "バージョン1.8未満のマインクラフトはCraftyでサポートされていません。インストールした場合、正常に動作しないかもしれません。",
|
||||
"uploadButton": "アップロード",
|
||||
"uploadZip": "サーバーをインポートするためにzipファイルをアップロード",
|
||||
"zipPath": "サーバーファイルのパス"
|
||||
},
|
||||
"sidebar": {
|
||||
"contribute": "貢献",
|
||||
"credits": "クレジット",
|
||||
"dashboard": "ダッシュボート",
|
||||
"documentation": "ドキュメント",
|
||||
"inApp": "アプリ内ドキュメント",
|
||||
"newServer": "新しいサーバーを作成",
|
||||
"servers": "サーバー"
|
||||
},
|
||||
"startup": {
|
||||
"almost": "もうすぐ完了します。",
|
||||
"cache": "Big Bucketのキャッシュファイルを更新中です",
|
||||
"internals": "Craftyの内部コンポーネントを設定・起動中です",
|
||||
"internet": "インターネット接続を確認中",
|
||||
"server": "初期化中 ",
|
||||
"serverInit": "サーバーを初期化中",
|
||||
"starting": "Craftyは起動中です...",
|
||||
"tasks": "タスクスケジュラーを起動中"
|
||||
},
|
||||
"userConfig": {
|
||||
"apiKey": "APIキー",
|
||||
"auth": "認証されているか ",
|
||||
"config": "設定",
|
||||
"configArea": "ユーザー設定",
|
||||
"configAreaDesc": "ここではユーザー設定をすべて変えることができます",
|
||||
"confirmDelete": "本当にユーザーを削除しますか。この操作は元に戻せません。",
|
||||
"craftyPermDesc": "ユーザーのCraftyにおける権限 ",
|
||||
"craftyPerms": "Craftyにおける権限 ",
|
||||
"created": "作成日時: ",
|
||||
"delSuper": "スーパーユーザーを削除することはできません",
|
||||
"deleteUser": "ユーザーを削除: ",
|
||||
"deleteUserB": "ユーザーを削除",
|
||||
"enabled": "有効化",
|
||||
"gravDesc": "このメールアドレスはGravatar™を使用するために用いられます。Craftyはどのような状況でも、あなたのGravatar™プロフィールを見つける以外の目的には使用しません。",
|
||||
"gravEmail": "Gravatar™ メールアドレス",
|
||||
"lastIP": "最終アクセス IPアドレス: ",
|
||||
"lastLogin": "最終ログイン: ",
|
||||
"lastUpdate": "最終更新: ",
|
||||
"leaveBlank": "パスワードを変更せずにユーザーを編集するためには、空欄にしてください。",
|
||||
"manager": "マネージャー",
|
||||
"member": "メンバーか",
|
||||
"notExist": "存在しないものを削除することはできません!",
|
||||
"pageTitle": "ユーザーを変種",
|
||||
"pageTitleNew": "ユーザーを作成",
|
||||
"password": "新しいパスワード",
|
||||
"permName": "権限名",
|
||||
"repeat": "パスワードを変更",
|
||||
"roleName": "ロール名",
|
||||
"selectManager": "ユーザーのマネージャーを選択",
|
||||
"super": "スーパーユーザー",
|
||||
"userLang": "ユーザーの使用する言語",
|
||||
"userName": "ユーザー名",
|
||||
"userNameDesc": "このユーザーをどのように呼びますか?",
|
||||
"userRoles": "ユーザーのロール",
|
||||
"userRolesDesc": "ユーザーの属しているロール",
|
||||
"userSettings": "ユーザー設定",
|
||||
"userTheme": "UIテーマ",
|
||||
"uses": "許可されている使用回数 (-1で無制限)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "パスワードが短すぎます。最小文字数は8文字です。",
|
||||
"backupName": "バックアップ名は3文字以上の文字列である必要があります。",
|
||||
"enumErr": "データの検証に失敗しました。次を含む必要があります: ",
|
||||
"filesPageLen": "1文字以上である必要があります",
|
||||
"insufficientPerms": "権限エラー: このリソースにアクセスする権限がありません",
|
||||
"roleManager": "ロールのマネージャーは数値(マネージャーID)か空欄である必要があります",
|
||||
"roleName": "ロール名は1文字以上である必要があります。次の文字列を含んではいけません: [ ] , ",
|
||||
"roleServerId": "サーバ-IDは1文字以上の文字列である必要があります",
|
||||
"roleServerPerms": "サーバー権限は8-bitの文字列である必要があります",
|
||||
"serverCreateName": "サーバ名は2文字以上の文字列で次の文字列を含んではいけません: \\ / # ",
|
||||
"serverExeCommand": "サーバー実行コマンドは1文字以上の文字列である必要があります。",
|
||||
"serverLogPath": "サーバログは1文字以上の文字列である必要があります",
|
||||
"taskIntervalType": "タスクの実行間隔は次のうちのどれかである必要があります。: ",
|
||||
"typeBool": "真か偽である必要があります",
|
||||
"typeEmail": "メールアドレスである必要があります。",
|
||||
"typeIntMinVal0": "1以上の数値である必要があります。",
|
||||
"typeInteger": "数値である必要があります。",
|
||||
"typeList": "リストか配列である必要があります ",
|
||||
"typeString": "文字列である必要があります。",
|
||||
"userName": " すべて小文字の文字列で、4文字以上20文字以下の文字列である必要があります"
|
||||
}
|
||||
}
|
721
app/translations/ko_KR.json
Normal file
721
app/translations/ko_KR.json
Normal file
@ -0,0 +1,721 @@
|
||||
{
|
||||
"serverWizard": {
|
||||
"serverVersion": "서버 버전",
|
||||
"sizeInGB": "크기(GB 단위)",
|
||||
"unsupported": "1.8 미만의 Minecraft 버전은 Crafty에서 지원되지 않습니다. 여전히 설치할 수 있지만, 결과는 다를 수 있습니다.",
|
||||
"uploadButton": "업로드",
|
||||
"uploadZip": "서버 가져오기를 위한 Zip 파일 업로드",
|
||||
"zipPath": "서버 경로",
|
||||
"absoluteServerPath": "서버의 절대 경로",
|
||||
"absoluteZipPath": "서버의 절대 경로",
|
||||
"addRole": "기존 역할에 서버 추가",
|
||||
"autoCreate": "선택된 항목이 없으면 Crafty가 하나를 자동으로 만듭니다!",
|
||||
"bePatient": "서버를 ' + (importing ? '가져오고 있습니다' : '다운로드하고 있습니다') + ' 조금만 기다려 주세요",
|
||||
"buildServer": "서버 빌드!",
|
||||
"clickRoot": "여기를 클릭하여 루트 디렉터리를 선택하세요",
|
||||
"close": "닫기",
|
||||
"defaultPort": "25565가 기본포트입니다",
|
||||
"downloading": "서버를 다운로드 중입니다...",
|
||||
"explainRoot": "아카이브 내에서 서버의 루트 디렉터리를 선택하려면 아래 버튼을 클릭하세요",
|
||||
"importServer": "기존 서버 가져오기",
|
||||
"importServerButton": "서버 가져오기",
|
||||
"importZip": "ZIP 파일에서 가져오기",
|
||||
"importing": "서버 가져오는 중...",
|
||||
"labelZipFile": "ZIP 파일을 선택하세요",
|
||||
"maxMem": "최대 메모리",
|
||||
"minMem": "최소 메모리",
|
||||
"myNewServer": "새로운 서버 생성",
|
||||
"newServer": "새 서버 생성",
|
||||
"noRole": "현재 검색 매개변수로 찾은 역할이 없습니다",
|
||||
"noneRoles": "선택된 역할이 없습니다",
|
||||
"quickSettings": "빠른 설정",
|
||||
"quickSettingsDescription": "걱정하지 마세요, 나중에 변경할 수 있습니다",
|
||||
"resetForm": "폼 초기화",
|
||||
"save": "저장",
|
||||
"selectRole": "역할 선택",
|
||||
"selectRoot": "아카이브 루트 디렉터리 선택",
|
||||
"selectServer": "서버 선택",
|
||||
"selectType": "서버 유형 (원본, 서버, 모드 등)",
|
||||
"selectVersion": "버전 선택",
|
||||
"selectZipDir": "파일을 압축 해제할 아카이브 내 디렉터리를 선택하세요",
|
||||
"serverJar": "서버 실행 파일",
|
||||
"serverName": "서버 이름",
|
||||
"serverPath": "서버 경로",
|
||||
"serverPort": "서버 포트",
|
||||
"serverSelect": "서버 선택",
|
||||
"serverType": "서버 타입",
|
||||
"serverUpload": "ZIP으로 압축된 서버파일 업로드"
|
||||
},
|
||||
"sidebar": {
|
||||
"contribute": "기여자",
|
||||
"credits": "크래딧",
|
||||
"dashboard": "대시보드",
|
||||
"documentation": "문서",
|
||||
"inApp": "앱 내 문서",
|
||||
"newServer": "새 서버 만들기",
|
||||
"servers": "서버"
|
||||
},
|
||||
"startup": {
|
||||
"almost": "마무리 중입니다. 잠시만 기다려 주세요...",
|
||||
"cache": "Big 버킷 캐시 파일 새로 고침",
|
||||
"internals": "Crafty의 내부 구성 요소를 설정하고 시작하는 중",
|
||||
"internet": "인터넷 연결 확인 중",
|
||||
"server": "초기화 중 ",
|
||||
"serverInit": "서버 초기화 중",
|
||||
"starting": "Crafty가 시작 중입니다...",
|
||||
"tasks": "작업 스케줄러 시작 중"
|
||||
},
|
||||
"userConfig": {
|
||||
"apiKey": "API 키",
|
||||
"auth": "인증됨? ",
|
||||
"config": "설정",
|
||||
"configArea": "사용자 구성 영역",
|
||||
"configAreaDesc": "여기에서 모든 사용자 설정을 변경할 수 있습니다",
|
||||
"confirmDelete": "이 사용자를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
|
||||
"craftyPermDesc": "이 사용자가 가진 ",
|
||||
"craftyPerms": "Crafty 권한: ",
|
||||
"created": "생성됨: ",
|
||||
"delSuper": "슈퍼 사용자를 삭제할 수 없습니다",
|
||||
"deleteUser": "사용자 삭제: ",
|
||||
"deleteUserB": "사용자 삭제",
|
||||
"enabled": "활성화됨",
|
||||
"gravDesc": "이 이메일은 Gravatar™와 함께 사용하기 위해서만 필요합니다. Crafty는 어떤 경우에도 이 이메일을 귀하의 Gravatar™를 조회하는 것 이외의 다른 용도로 사용하지 않습니다",
|
||||
"gravEmail": "Gravatar™ 이메일",
|
||||
"lastIP": "마지막 IP: ",
|
||||
"lastLogin": "마지막 로그인: ",
|
||||
"lastUpdate": "마지막 업데이트: ",
|
||||
"leaveBlank": "비밀번호를 변경하지 않고 사용자를 편집하려면 비워두세요.",
|
||||
"manager": "관리자",
|
||||
"member": "멤버?",
|
||||
"notExist": "존재하지 않는 항목은 삭제할 수 없습니다!",
|
||||
"pageTitle": "사용자 편집",
|
||||
"pageTitleNew": "사용자 생성",
|
||||
"password": "새 비밀번호",
|
||||
"permName": "권한 이름",
|
||||
"repeat": "비밀번호 확인",
|
||||
"roleName": "역할 이름",
|
||||
"selectManager": "사용자를 위한 관리자 선택",
|
||||
"super": "슈퍼 사용자",
|
||||
"userLang": "사용자 언어",
|
||||
"userName": "사용자 이름",
|
||||
"userNameDesc": "이 사용자의 이름을 무엇으로 설정하시겠습니까?",
|
||||
"userRoles": "사용자 역할",
|
||||
"userRolesDesc": "이 사용자가 속한 역할.",
|
||||
"userSettings": "사용자 설정",
|
||||
"userTheme": "UI 테마",
|
||||
"uses": "허용되는 사용 횟수 (-1은 제한 없음)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "비밀번호가 너무 짧아요! (최소 길이: 8)",
|
||||
"taskIntervalType": "작업 반복 유형은 다음 중 하나여야 합니다: ",
|
||||
"typeBool": "'true' 또는 'false' 여야 합니다 (boolean 타입)",
|
||||
"backupName": "백업 이름은 문자여야 하며 최소 3자 이상이어야 합니다.",
|
||||
"enumErr": "검증에 실패했습니다. 허용되는 데이터는 다음과 같습니다: ",
|
||||
"filesPageLen": "속성 값은 1자 이상이여야 합니다",
|
||||
"insufficientPerms": "권한 오류: 이 리소스에 대한 권한이 없습니다",
|
||||
"roleManager": "역할관리자는 Type integer(manager ID) 또는 None이어야 합니다",
|
||||
"roleName": "역할 이름은 1자보다 큰 문자열이어야 합니다. 다음 기호를 포함할 수 없습니다: [ ] , ",
|
||||
"roleServerPerms": "서버 권한은 8 비트 문자열이어야 합니다",
|
||||
"roleServerId": "서버 ID 속성은 최소 길이가 1인 문자열이어야 합니다",
|
||||
"serverCreateName": "서버 이름에는 문자열이어야 하고, 최소 2자 이상이어야 하고, 그리고 다음이 포함 되지 않아야합니다: \\/ 또는 #. ",
|
||||
"serverExeCommand": "서버 명령어를 실행하려면, 문자열이 최소 1자 이상 이어야 합니다.",
|
||||
"serverLogPath": "서버 로그 경로는 문자열 이어야 하며, 최소 1자 이상이어야 합니다",
|
||||
"typeEmail": "이메일 유형이어야 합니다.",
|
||||
"typeIntMinVal0": "최소값이 0인 정수여야 합니다.",
|
||||
"typeInteger": "숫자여야 합니다.",
|
||||
"typeList": "목럭/배열 타입이어여합니다. ",
|
||||
"typeString": "문자열 이어야합니다.",
|
||||
"userName": " 문자열이어야 하며, 모두 소문자로 입력해야 하고, 최소 4자에서 최대 20자까지 입력할 수 있습니다"
|
||||
},
|
||||
"webhooks": {
|
||||
"trigger": "트리거",
|
||||
"type": "웹후크 유형",
|
||||
"url": "웹후크 URL",
|
||||
"webhook_body": "웹후크 본문",
|
||||
"webhooks": "웹후크",
|
||||
"areYouSureDel": "이 웹후크를 삭제하시겠습니까?",
|
||||
"areYouSureRun": "이 웹후크를 테스트하시겠습니까?",
|
||||
"backup_server": "서버 백업이 완료되었습니다",
|
||||
"bot_name": "봇 이름",
|
||||
"color": "색상 강조를 선택하세요",
|
||||
"crash_detected": "서버가 크래시되었습니다",
|
||||
"edit": "수정",
|
||||
"enabled": "활성화",
|
||||
"jar_update": "서버 실행 파일이 업데이트되었습니다",
|
||||
"kill": "서버가 종료되었습니다",
|
||||
"name": "이름",
|
||||
"new": "새 웹후크",
|
||||
"newWebhook": "새 웹후크",
|
||||
"no-webhook": "현재 이 서버에는 웹후크가 없습니다. 시작하려면 클릭하세요",
|
||||
"run": "웹후크 테스트 실행",
|
||||
"send_command": "서버 명령이 수신되었습니다",
|
||||
"start_server": "서버가 시작되었습니다",
|
||||
"stop_server": "서버가 정지되었습니다"
|
||||
},
|
||||
"404": {
|
||||
"contact": "디스코드를 통해 Crafty Control 지원팀에 문의하세요",
|
||||
"notFound": "페이지를 찾을 수 없습니다",
|
||||
"unableToFind": "찾고 계시는 페이지를 찾을 수 없습니다. 다시 시도하거나 뒤로가서 새로고침을 해주세요."
|
||||
},
|
||||
"accessDenied": {
|
||||
"accessDenied": "접근 불가능",
|
||||
"contact": "디스코드를 통해 Crafty Controll 지원팀애 문의하세요",
|
||||
"contactAdmin": "해당 리소스에 접근하기 위해서는 서버 관리자에게 문의하시거나, 접근 권한이 있다고 생각되시면 지원팀에 문의해 주세요.",
|
||||
"noAccess": "당신은 해당 리소스에 대한 권한이 없습니다"
|
||||
},
|
||||
"apiKeys": {
|
||||
"apiKeys": "API 키",
|
||||
"auth": "인증이 필요한가요? ",
|
||||
"buttons": "버튼",
|
||||
"config": "설정",
|
||||
"crafty": "Crafty: ",
|
||||
"createNew": "새 Crafty API 토큰 생성",
|
||||
"created": "생성 됨",
|
||||
"deleteKeyConfirmation": "이 API 키를 삭제할건가요? 이 작업은 취소할 수 없어요.",
|
||||
"deleteKeyConfirmationTitle": "API 키 '${keyId}'를 제거하겠습니까?",
|
||||
"fullAccess": "전체 액세스",
|
||||
"getToken": "토큰 가져오기",
|
||||
"name": "이름",
|
||||
"nameDesc": "이 API 토큰을 무엇이라고 부를건가요? ",
|
||||
"no": "아니요",
|
||||
"pageTitle": "사용자 API 키 편집",
|
||||
"permName": "권한 이름",
|
||||
"perms": "권한",
|
||||
"server": "서버: ",
|
||||
"yes": "예"
|
||||
},
|
||||
"base": {
|
||||
"doesNotWorkWithoutJavascript": "<strong>경고: </strong>Crafty는 JavaScript가 활성화되지 않으면 제대로 작동하지 않습니다!"
|
||||
},
|
||||
"credits": {
|
||||
"developmentTeam": "개발자 팀",
|
||||
"hugeDesc": "진심으로",
|
||||
"pageDescription": "이 사람들이 없었다면 Crafty가 없었을 겁니다",
|
||||
"pageTitle": "크래딧",
|
||||
"patreonDesc": "Patreon/Ko-fi 후원자 여러분!",
|
||||
"patreonOther": "다른",
|
||||
"patreonSupporter": "Patreon / Ko-fi 후원자",
|
||||
"patreonUpdate": "마지막 업데이트:",
|
||||
"retiredStaff": "퇴직한 직원",
|
||||
"subscriberName": "이름",
|
||||
"subscriptionLevel": "레벨",
|
||||
"supportTeam": "지원 및 문서 팀",
|
||||
"thankYou": "감사합니다",
|
||||
"translationDesc": "번역해 주시는 우리 커뮤니티 여러분께! [ 활성 = 🟢 비활성/퇴직 = ⚪ ]",
|
||||
"translationName": "이름",
|
||||
"translationTitle": "언어 번역",
|
||||
"translator": "번역가들"
|
||||
},
|
||||
"customLogin": {
|
||||
"apply": "적용",
|
||||
"backgroundUpload": "배경 업로드",
|
||||
"customLoginPage": "로그인 페이지 사용자 지정",
|
||||
"delete": "삭제",
|
||||
"labelLoginImage": "로그인 배경 선택",
|
||||
"loginBackground": "로그인 배경 이미지",
|
||||
"loginImage": "로그인 화면의 배경 이미지를 업로드합니다.",
|
||||
"loginOpacity": "로그인 화면 불투명도 선택",
|
||||
"pageTitle": "로그인 페이지 사용자 지정",
|
||||
"preview": "미리보기",
|
||||
"select": "선택",
|
||||
"selectImage": "이미지 선택"
|
||||
},
|
||||
"dashboard": {
|
||||
"actions": "동작",
|
||||
"allServers": "모든 서버",
|
||||
"avg": "평균",
|
||||
"backups": "백업",
|
||||
"bePatientClone": "서버를 복사하는 동안 잠시 기달려주세요.<br /> 이 화면은 자동으로 새로고침됩니다",
|
||||
"bePatientRestart": "서버를 재시작하는 동안 잠시만 기다려 주세요.<br /> 이 화면은 자동으로 새로고침됩니다",
|
||||
"bePatientStart": "서버를 시작하는 동안 잠시만 기다려 주세요.<br /> 이 화면은 자동으로 새로고침됩니다",
|
||||
"bePatientStop": "서버를 정지하는 동안 잠시만 기달려주세요<br /> 이 화면은 자동으로 새로고침됩니다",
|
||||
"cannotSee": "아무것도 보이지 않나요?",
|
||||
"cannotSeeOnMobile": "모바일에서 아무것도 볼 수 없나요?",
|
||||
"cannotSeeOnMobile2": "테이블을 옆으로 스크롤해 보세요.",
|
||||
"clone": "복사",
|
||||
"cloneConfirm": "이 서버를 복제하시겠습니까? 이 프로세스는 시간이 걸릴 수 있습니다.",
|
||||
"cpuCores": "CPU 코어",
|
||||
"cpuCurFreq": "CPU 현재 클럭",
|
||||
"cpuMaxFreq": "CPU 최대 클럭",
|
||||
"cpuUsage": "CPU 사용량",
|
||||
"crashed": "충돌",
|
||||
"dashboard": "대시보드",
|
||||
"delay-explained": "서비스/에이전트가 최근에 시작되어 마인크래프트 서버 인스턴스의 시작을 지연하고있어요",
|
||||
"host": "호스트",
|
||||
"installing": "설치중...",
|
||||
"kill": "프로세스 종료",
|
||||
"killing": "프로세스를 종료 중...",
|
||||
"lastBackup": "마지막:",
|
||||
"max": "최대",
|
||||
"memUsage": "메모리 사용량",
|
||||
"motd": "MOTD",
|
||||
"newServer": "새로운 서버 만들기",
|
||||
"nextBackup": "다음:",
|
||||
"no-servers": "현재 서버가 없습니다. 시작하려면 다음을 클릭해주세요",
|
||||
"offline": "오프라인",
|
||||
"online": "온라인",
|
||||
"players": "플레이어",
|
||||
"restart": "재시작",
|
||||
"sendingCommand": "명령어 전송",
|
||||
"server": "서버",
|
||||
"servers": "서버",
|
||||
"size": "서버 폴더 크기",
|
||||
"start": "시작",
|
||||
"starting": "시작 지연",
|
||||
"status": "상태",
|
||||
"stop": "정지",
|
||||
"storage": "저장공간",
|
||||
"version": "버전",
|
||||
"welcome": "Crafty Controller에 오신걸 환영합니다!"
|
||||
},
|
||||
"datatables": {
|
||||
"i18n": {
|
||||
"aria": {
|
||||
"sortAscending": ": 활성화하여 오름차순 정렬",
|
||||
"sortDescending": ": 활성화하여 내림차순 정렬"
|
||||
},
|
||||
"buttons": {
|
||||
"collection": "컬렉션 <span class='ui-button-icon-primary ui-icon ui-icon-triangle-1-s'/>",
|
||||
"colvis": "열 표시 설정",
|
||||
"colvisRestore": "가시성 복원",
|
||||
"copy": "복사",
|
||||
"copyKeys": "테이블데이터를 클립보드에 복사하려면 Ctrl 또는 ⌘ + C를 누르세요.<br><br>취소하려면 이 메시지를 클릭하거나 Esc 키를 누르세요.",
|
||||
"copySuccess": {
|
||||
"1": "1행이 클립보드에 복사되었습니다",
|
||||
"_": "%d행이 클립보드에 복사되었습니다"
|
||||
},
|
||||
"copyTitle": "클립보드로 복사",
|
||||
"csv": "CSV",
|
||||
"excel": "엑셀",
|
||||
"pageLength": {
|
||||
"-1": "모든 행 표시",
|
||||
"1": "1행 표시",
|
||||
"_": "%d행 표시"
|
||||
},
|
||||
"pdf": "PDF",
|
||||
"print": "프린트"
|
||||
},
|
||||
"emptyTable": "테이블에 데이터가 없습니다",
|
||||
"info": "_START_부터 _END_까지 총 _TOTAL_개의 항목 표시",
|
||||
"infoEmpty": "0부터 0까지 총 0개의 항목 표시",
|
||||
"infoFiltered": "(총 _MAX_개의 항목 필터링됨)",
|
||||
"lengthMenu": "_MENU_ 항목 표시",
|
||||
"loadingRecords": "로딩 중...",
|
||||
"paginate": {
|
||||
"first": "첫번째",
|
||||
"last": "마지막",
|
||||
"next": "다음",
|
||||
"previous": "이전"
|
||||
},
|
||||
"processing": "처리중...",
|
||||
"search": "검색:",
|
||||
"select": {
|
||||
"cells": {
|
||||
"0": "셀을 클릭하여 선택합니다",
|
||||
"1": "%d 셀을 선택했습니다",
|
||||
"_": "%d 셀을 선택했습니다"
|
||||
},
|
||||
"columns": {
|
||||
"0": "열을 클릭하여 선택합니다",
|
||||
"1": "%d 열을 선택했습니다",
|
||||
"_": "%d 열을 선택했습니다"
|
||||
},
|
||||
"rows": {
|
||||
"0": "Row을 클릭하여 선택합니다",
|
||||
"1": "%d Row를 선택했습니다",
|
||||
"_": "%d Rows를 선택했습니다"
|
||||
}
|
||||
},
|
||||
"thousands": ",",
|
||||
"zeroRecords": "레코드를 찾을 수 없습니다",
|
||||
"decimal": ".",
|
||||
"infoPostFix": "|"
|
||||
},
|
||||
"loadingRecords": "로딩 중..."
|
||||
},
|
||||
"error": {
|
||||
"agree": "동의",
|
||||
"bedrockError": "베드락 서버를 다운로드를 사용할 수 없습니다. 확인해 주세요",
|
||||
"bigBucket1": "Big Bucket 상태 확인을 실패했습니다. 확인해주세요",
|
||||
"bigBucket2": "최신 정보를 확인할 수 있습니다.",
|
||||
"cancel": "취소",
|
||||
"contact": "디스코드로 Crafty Controll을 지원받으세요",
|
||||
"craftyStatus": "Crafty의 상태 페이지",
|
||||
"cronFormat": "잘못된 Cron 형식이 감지됨",
|
||||
"embarassing": "이런, 당황스럽네요.",
|
||||
"error": "오류!",
|
||||
"eulaAgree": "동의를 할건가요?",
|
||||
"eulaMsg": "다음에 동의해야 합니다 ",
|
||||
"eulaTitle": "EULA 동의",
|
||||
"fileError": "파일 유형은 이미지여야 합니다.",
|
||||
"fileTooLarge": "업로드 실패. 파일 크기가 너무 큽니다. 시스템 관리자에게 도움을 요청하세요.",
|
||||
"hereIsTheError": "여기 오류가 있습니다",
|
||||
"installerJava": "{} 설치에 실패했습니다: Forge 서버 설치에는 Java가 필요합니다. Java가 설치되지 않은 것을 확인했습니다. Java를 설치한 후 서버를 설치하세요.",
|
||||
"internet": "Crafty가 실행 중인 머신이 인터넷에 연결되어 있지 않은 것을 확인했습니다. 클라이언트의 서버 연결이 제한될 수 있습니다.",
|
||||
"migration": "Crafty의 주요 서버 저장소가 새로운 위치로 이동되고 있습니다. 이 기간 동안 모든 서버 시작이 중단되었습니다. 마이그레이션이 완료될 때까지 기다려 주세요",
|
||||
"no-file": "파일을 찾을 수 없습니다! 경로를 다시 확인해주세요. Crafty에 적절한 권한이 있나요?",
|
||||
"noInternet": "Crafty가 인터넷에 접근하는 데 문제가 있습니다. 서버 생성이 비활성화되었습니다. 인터넷 연결을 확인하고 이 페이지를 새로고침하세요.",
|
||||
"noJava": "서버 {} 시작에 실패했습니다. 오류 코드: Java가 설치되지 않은 것을 확인했습니다. Java를 설치한 후 서버를 시작하세요.",
|
||||
"not-downloaded": "실행 파일을 찾을 수 없습니다. 다운로드가 완료되었나요? 실행 권한이 설정되어 있나요?",
|
||||
"portReminder": "{}가 처음 실행된 것을 확인했습니다. 이 프로그램에 원격으로 접근할 수 있도록 라우터/방화벽에서 포트 {}를 포워딩해야 합니다.",
|
||||
"privMsg": "그리고 ",
|
||||
"return": "대시보드로 돌아가기",
|
||||
"selfHost": "이 저장소를 호스팅하고 계신 경우, 주소를 확인하거나 문제 해결 가이드를 참조하세요.",
|
||||
"start-error": "서버 {} 시작에 실패했습니다. 오류 코드: {}",
|
||||
"superError": "이 작업을 수행할려면 'Super User' 이어야 합니다.",
|
||||
"terribleFailure": "끔직한 실패에요!"
|
||||
},
|
||||
"footer": {
|
||||
"allRightsReserved": "All rights reserved",
|
||||
"copyright": "Copyright",
|
||||
"version": "Version"
|
||||
},
|
||||
"login": {
|
||||
"defaultPath": "입력한 비밀번호는 비밀번호가 아닌 기본 자격 증명 경로입니다. 해당 위치에서 기본 비밀번호를 찾아주세요.",
|
||||
"disabled": "사용자 계정이 비활성화되었습니다. 자세한 내용은 시스템 관리자에게 문의하세요.",
|
||||
"forgotPassword": "비밀번호 찾기",
|
||||
"incorrect": "잘못된 아이디 또는 비밀번호",
|
||||
"login": "로그인",
|
||||
"password": "비밀번호",
|
||||
"username": "아이디",
|
||||
"viewStatus": "공개 상태 페이지 보기"
|
||||
},
|
||||
"notify": {
|
||||
"activityLog": "활동 로그",
|
||||
"backupComplete": "서버 {} 에 대한 백업이 성공적으로 완료되었습니다!",
|
||||
"backupStarted": "서버 {} 에 대한 백업이 시작되었습니다!",
|
||||
"backup_desc": "백업 마이그레이션이 부분적으로 또는 완전히 실패했을 수 있음을 감지했습니다. 백업 탭에서 백업 기록을 확인하십시오.",
|
||||
"backup_title": "백업 마이그레이션 경고",
|
||||
"downloadLogs": "지원 로그 다운로드?",
|
||||
"finishedPreparing": "지원 로그 준비를 완료했습니다. 다운로드를 클릭하여 다운로드하세요",
|
||||
"logout": "로그아웃",
|
||||
"preparingLogs": " 로그를 준비하는 동안 잠시만 기다려주세요... 로그가 준비되면 알림을 보내드리겠습니다. 대규모 배포의 경우 시간이 걸릴 수 있습니다.",
|
||||
"schedule_desc": "업그레이드 중에 예약된 작업의 일부 또는 전부가 성공적으로 전송되지 않은 것을 발견했습니다. 일정 탭에서 일정을 확인하세요.",
|
||||
"schedule_title": "스케줄 마이그레이션 경고",
|
||||
"supportLogs": "지원 로그"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "오프라인",
|
||||
"pleaseConnect": "Crafty를 사용하려면 인터넷에 연결하세요."
|
||||
},
|
||||
"panelConfig": {
|
||||
"adminControls": "관리 컨트롤",
|
||||
"allowedServers": "허용된 서버",
|
||||
"apply": "적용",
|
||||
"assignedRoles": "할당된 역할",
|
||||
"cancel": "취소",
|
||||
"clearComms": "실행되지 않은 명령 지우기",
|
||||
"custom": "Crafty 사용자 지정",
|
||||
"delete": "삭제",
|
||||
"edit": "수정",
|
||||
"enableLang": "모든 언어 활성화",
|
||||
"enabled": "활성화",
|
||||
"globalExplain": "Crafty는 모든 서버 파일을 저장합니다. ( /servers/[서버의 uuid]로 경로를 추가합니다.)",
|
||||
"globalServer": "글로벌 서버 디렉토리",
|
||||
"json": "Config.json",
|
||||
"match": "비밀번호는 일치해야 합니다",
|
||||
"newRole": "새 역할 추가",
|
||||
"newUser": "새 사용자 추가",
|
||||
"noMounts": "대시보드에 마운트 표시 안 함",
|
||||
"pageTitle": "패널 설정",
|
||||
"role": "역할",
|
||||
"roleUsers": "사용자 역할",
|
||||
"roles": "역할",
|
||||
"save": "저장",
|
||||
"select": "선택",
|
||||
"superConfirm": "이 사용자가 모든 것(모든 사용자 계정, 서버, 패널 설정 등)에 접근하도록 하려면 진행하세요. 이 사용자는 심지어 당신의 슈퍼유저 권한을 박탈할 수 있습니다.",
|
||||
"superConfirmTitle": "슈퍼유저를 활성화하시겠습니까? 확실합니까?",
|
||||
"title": "Crafty 설정",
|
||||
"user": "사용자",
|
||||
"users": "사용자"
|
||||
},
|
||||
"rolesConfig": {
|
||||
"config": "역할 설정",
|
||||
"configDesc": "여기에서 역할의 구성을 변경할 수 있습니다",
|
||||
"configUpdate": "마지막 업데이트: ",
|
||||
"created": "생성됨: ",
|
||||
"delRole": "역할 제거",
|
||||
"doesNotExist": "아직 존재하지 않는 것을 삭제할 수 없습니다.",
|
||||
"pageTitle": "역할 수정",
|
||||
"pageTitleNew": "새 역할",
|
||||
"permAccess": "액세스 가능?",
|
||||
"permName": "권한 이름",
|
||||
"permsServer": "이 역할이 지정된 서버에 대한 권한",
|
||||
"roleConfigArea": "역할 구성 영역",
|
||||
"roleDesc": "이 역할에 어떤 이름을 설정하고 싶으신가요?",
|
||||
"roleName": "역할 이름: ",
|
||||
"rolePerms": "역할 권한",
|
||||
"roleServers": "허용된 서버",
|
||||
"roleTitle": "역할 설정",
|
||||
"roleUserName": "사용자 이름",
|
||||
"roleUsers": "사용자 역할: ",
|
||||
"selectManager": "이 역할의 관리자를 선택하세요",
|
||||
"serverAccess": "액세스?",
|
||||
"serverName": "서버 이름",
|
||||
"serversDesc": "이 역할이 접근할 수 있는 서버"
|
||||
},
|
||||
"serverBackups": {
|
||||
"actions": "동작",
|
||||
"after": "백업 후 명령어를 실행합니다",
|
||||
"backupAtMidnight": "자정에 자동 백업을 수행할까요?",
|
||||
"backupNow": "지금 백업하기!",
|
||||
"backupTask": "백업 작업이 시작되었습니다.",
|
||||
"backups": "서버 백업",
|
||||
"before": "백업 전 명령어를 실행합니다",
|
||||
"cancel": "취소",
|
||||
"clickExclude": "클릭하여 제외를 선택합니다",
|
||||
"compress": "백업 파일을 압축하기",
|
||||
"confirm": "확인",
|
||||
"confirmDelete": "이 백업을 삭제하시겠습니까? 이 백업은 되돌릴 수 없습니다.",
|
||||
"confirmRestore": "이 백업에서 복원하시겠습니까? 현재 서버 파일이 모두 백업 상태로 변경되어 복구할 수 없습니다.",
|
||||
"currentBackups": "현재 백업",
|
||||
"default": "기본 백업",
|
||||
"defaultExplain": "Crafty가 업데이트하기 전에 사용할 백업입니다. 이 백업은 변경하거나 삭제할 수 없습니다.",
|
||||
"delete": "삭제",
|
||||
"destroyBackup": "백업 \" + file_to_del + \"을(를) 삭제하시겠습니까?",
|
||||
"download": "다운로드",
|
||||
"edit": "수정",
|
||||
"enabled": "활성화",
|
||||
"excludedBackups": "제외된 경로: ",
|
||||
"excludedChoose": "백업에서 제외할 경로를 선택하세요",
|
||||
"exclusionsTitle": "백업 제외 항목",
|
||||
"failed": "실패",
|
||||
"maxBackups": "최대 백업 수",
|
||||
"maxBackupsDesc": "Crafty는 N개의 백업 이상을 저장하지 않으며, 가장 오래된 백업을 삭제합니다 (모든 백업을 유지하려면 0을 입력하세요)",
|
||||
"myBackup": "새로운 백업",
|
||||
"name": "이름",
|
||||
"newBackup": "새로운 백업 만들기",
|
||||
"no-backup": "백업이 없습니다. 새로운 백업 구성을 만들려면 '새로운 백업'을 클릭하세요",
|
||||
"options": "옵션",
|
||||
"path": "경로",
|
||||
"restore": "복원",
|
||||
"restoring": "백업을 복원하는 중입니다. 시간이 좀 걸릴 수 있습니다. 잠시만 기다려 주세요.",
|
||||
"run": "백업 실행",
|
||||
"save": "저장",
|
||||
"shutdown": "백업하는 동안 서버를 종료합니다",
|
||||
"size": "크기",
|
||||
"standby": "대기중",
|
||||
"status": "상태",
|
||||
"storage": "저장 위치",
|
||||
"storageLocation": "저장 위치",
|
||||
"storageLocationDesc": "백업을 어디에 저장하시겠습니까?"
|
||||
},
|
||||
"serverConfig": {
|
||||
"bePatientDelete": "Crafty 패널에서 서버를 제거하는 동안 잠시만 기다려 주세요. 이 화면은 잠시 후 닫힙니다.",
|
||||
"bePatientDeleteFiles": "Crafty 패널에서 서버를 제거하고 모든 파일을 삭제하는 동안 잠시만 기다려 주세요. 이 화면은 잠시 후 닫힙니다.",
|
||||
"bePatientUpdate": "서버를 업데이트하는 동안 잠시만 기다려 주세요. 다운로드 시간은 인터넷 속도에 따라 달라질 수 있습니다.<br /> 이 화면은 잠시 후 새로고침됩니다",
|
||||
"cancel": "취소",
|
||||
"countPlayers": "서버의 총 플레이어 수",
|
||||
"crashTime": "충돌 시간초과",
|
||||
"crashTimeDesc": "서버가 충돌한 것으로 간주하려면 얼마나 기다려야 하나요?",
|
||||
"deleteFilesQuestion": "서버파일을 서버에서 삭제할까요?",
|
||||
"deleteFilesQuestionMessage": "Crafty가 호스트 머신에서 모든 서버 파일을 삭제하도록 하시겠습니까?<br><br><strong>여기에는 서버 백업도 포함됩니다.</strong>",
|
||||
"deleteServer": "서버 삭제",
|
||||
"deleteServerQuestion": "서버를 제거할까요?",
|
||||
"deleteServerQuestionMessage": "정말로 이 서버를 삭제하시겠습니까? 삭제 후에는 「복구」할 수 없어요.",
|
||||
"exeUpdateURL": "서버 실행 파일 업데이트 URL",
|
||||
"exeUpdateURLDesc": "업데이트를 하기위한 다이렉트 다운로드 URL을 입력해주세요.",
|
||||
"ignoredExits": "충돌 코드 무시",
|
||||
"ignoredExitsExplain": "종료 코드 Crafty의 충돌 감지는 일반적인 '정지'로 무시해야 합니다(콤마로 구분)",
|
||||
"javaNoChange": "덮어쓰지 않기",
|
||||
"javaVersion": "현재 버전 덮어쓰기",
|
||||
"javaVersionDesc": "Java를 덮어쓸 경우, '실행 명령'에서 현재 Java 경로가 따옴표로 감싸져 있는지 확인하세요 (기본 'java' 변수 제외)",
|
||||
"noDelete": "돌아가지 않기",
|
||||
"noDeleteFiles": "아니요, 패널에서만 제거해 주세요",
|
||||
"removeOldLogsAfter": "오래된 로그 삭제 후",
|
||||
"removeOldLogsAfterDesc": "로그 파일이 삭제되기 위해 얼마나 많은 시간이 지나야 하나요? (0은 비활성화)",
|
||||
"save": "저장",
|
||||
"sendingDelete": "서버 삭제 중",
|
||||
"sendingRequest": "요청을 전송하는 중...",
|
||||
"serverAutoStart": "서버 자동시작",
|
||||
"serverAutostartDelay": "서버 자동시작 지연",
|
||||
"serverAutostartDelayDesc": "자동 시작 지연(아래에서 활성화된 경우)",
|
||||
"serverCrashDetection": "서버 충돌 감지",
|
||||
"serverExecutable": "서버 실행 파일",
|
||||
"serverExecutableDesc": "서버의 실행 파일",
|
||||
"serverExecutionCommand": "서버 실행 명령",
|
||||
"serverExecutionCommandDesc": "숨겨진 터미널에서 실행될 내용",
|
||||
"serverIP": "서버 IP",
|
||||
"serverIPDesc": "통계를 위해 Crafty가 연결할 IP(문제가 있는 경우 127.0.0.1 대신 실제 IP를 사용해 보세요)",
|
||||
"serverLogLocation": "서버 로그 위치",
|
||||
"serverLogLocationDesc": "로그 파일 경로",
|
||||
"serverName": "서버 이름",
|
||||
"serverNameDesc": "이 서버의 이름을 지정하세요",
|
||||
"serverPath": "서버가 작동할 폴더",
|
||||
"serverPathDesc": "실행 파일을 제외한 절대경로",
|
||||
"serverPort": "서버 포트",
|
||||
"serverPortDesc": "Crafty가 통계를 보려면 연결해야 할 포트",
|
||||
"serverStopCommand": "서버 중지 명령어",
|
||||
"serverStopCommandDesc": "프로그램을 중지시키기 위한 명령",
|
||||
"showStatus": "공개 상태 페이지에 표시",
|
||||
"shutdownTimeout": "종료 대기 시간",
|
||||
"statsHint1": "서버가 실행할 포트는 여기 입력해야 합니다. 이는 Crafty가 통계를 위해 서버에 연결을 여는 방법입니다.",
|
||||
"statsHint2": "이 설정은 서버의 포트를 변경하지 않습니다. 서버 구성 파일에서 포트를 변경해야 합니다.",
|
||||
"stopBeforeDeleting": "서버를 삭제하기 전에 반드시 중지해 주세요",
|
||||
"timeoutExplain1": "Cratfy가 명령 실행 후 서버가 종료될 때까지 기다리는 시간입니다",
|
||||
"timeoutExplain2": "이 시간이 지나면 프로세스를 강제로 종료합니다.",
|
||||
"update": "실행 파일 업데이트",
|
||||
"yesDelete": "삭제합니다",
|
||||
"yesDeleteFiles": "모든 파일을 삭제합니다"
|
||||
},
|
||||
"serverConfigHelp": {
|
||||
"desc": "여기에서 서버의 설정을 변경할 수 있습니다",
|
||||
"perms": [
|
||||
"Crafty가 관리하는 서버의 경로는 <code>변경하지 않는 것</code>을 권장합니다.",
|
||||
"경로를 변경하면 시스템에 <code>문제가 발생할 수 있으며</code>, 특히 파일 권한이 더 제한적인 리눅스 계열 운영 체제에서 발생할 가능성이 높습니다.",
|
||||
"<br /><br/>",
|
||||
"서버 위치를 변경해야 한다고 생각하시면, \"crafty\" 사용자에게 서버 경로에 대한 읽기/쓰기 권한을 부여하는 한 변경할 수 있습니다.",
|
||||
"<br />",
|
||||
"<br />",
|
||||
"리눅스에서는 다음 명령을 실행하여 권한을 변경하는 것이 가장 좋습니다:<br />",
|
||||
"<code>",
|
||||
" sudo chown crafty:crafty path/to/your/server -R<br />",
|
||||
" sudo chmod 2775 /path/to/your/server -R<br />",
|
||||
"</code>"
|
||||
],
|
||||
"title": "서버 구성 영역"
|
||||
},
|
||||
"serverDetails": {
|
||||
"backup": "백업",
|
||||
"config": "설정",
|
||||
"files": "파일",
|
||||
"filter": "로그 필터",
|
||||
"filterList": "필터링된 단어",
|
||||
"logs": "로그",
|
||||
"metrics": "모니터링",
|
||||
"playerControls": "플레이어 관리",
|
||||
"reset": "스크롤 초기화",
|
||||
"schedule": "스케줄",
|
||||
"serverDetails": "서버 상세정보",
|
||||
"terminal": "터미널"
|
||||
},
|
||||
"serverFiles": {
|
||||
"clickUpload": "파일을 선택하려면 여기를 클릭하세요",
|
||||
"close": "닫기",
|
||||
"createDir": "디렉토리 만들기",
|
||||
"createDirQuestion": "새 디렉토리의 이름은 무엇으로 하시겠습니까?",
|
||||
"createFile": "파일 만들기",
|
||||
"createFileQuestion": "새 파일의 이름은 무엇으로 하시겠습니까?",
|
||||
"default": "기본값",
|
||||
"delete": "삭제",
|
||||
"deleteItemQuestion": "\" + name + \"을(를) 삭제하시겠습니까?",
|
||||
"deleteItemQuestionMessage": "\\\"\" + path + \"\\\"를 삭제합니다!<br/><br/>이 작업은 되돌릴 수 없으며 영원히 사라집니다!",
|
||||
"download": "다운로드",
|
||||
"editingFile": "파일 편집 중",
|
||||
"error": "파일을 가져오는 중 오류 발생",
|
||||
"fileReadError": "파일 읽기 오류",
|
||||
"files": "파일",
|
||||
"keybindings": "키 바인딩",
|
||||
"loadingRecords": "파일 로딩 중...",
|
||||
"noDelete": "아니요",
|
||||
"noscript": "JavaScript가 없으면 파일 관리자가 작동하지 않습니다",
|
||||
"rename": "이름 변경",
|
||||
"renameItemQuestion": "새 이름은 무엇으로 하시겠습니까?",
|
||||
"save": "저장",
|
||||
"size": "편집기 크기 전환",
|
||||
"stayHere": "이 페이지를 떠나지 마세요!",
|
||||
"unsupportedLanguage": "경고: 지원되지 않는 파일 유형입니다",
|
||||
"unzip": "압축 풀기",
|
||||
"upload": "업로드",
|
||||
"uploadTitle": "파일 업로드: ",
|
||||
"waitUpload": "파일을 업로드하는 동안 잠시 기다려 주세요... 시간이 걸릴 수 있습니다.",
|
||||
"yesDelete": "네, 결과를 이해했습니다"
|
||||
},
|
||||
"serverMetrics": {
|
||||
"resetZoom": "확대 초기화",
|
||||
"zoomHint1": "그래프에서 확대하려면 Shift 키를 누른 채로 스크롤 휠을 사용하세요.",
|
||||
"zoomHint2": "또는 Shift 키를 누른 채로 확대할 영역을 클릭하고 드래그하세요."
|
||||
},
|
||||
"serverPlayerManagement": {
|
||||
"bannedPlayers": "차단된 플레이어",
|
||||
"loadingBannedPlayers": "차단된 플레이어를 불러오는 중",
|
||||
"players": "플레이어"
|
||||
},
|
||||
"serverScheduleConfig": {
|
||||
"backup": "서버 백업",
|
||||
"basic": "기본",
|
||||
"children": "연결된 하위 작업: ",
|
||||
"command": "명령어",
|
||||
"command-explain": "어떤 명령을 실행할까요? '/'를 포함하지 마세요",
|
||||
"cron": "크론",
|
||||
"cron-explain": "크론 문자열을 입력하세요 -- 주의: 0은 마지막 옵션에서 월요일을 의미합니다.",
|
||||
"custom": "커스텀 명령어",
|
||||
"days": "일",
|
||||
"enabled": "활성화",
|
||||
"hours": "시간",
|
||||
"interval": "주기",
|
||||
"interval-explain": "이 스케줄을 얼마나 자주 실행하길 원하나요?",
|
||||
"minutes": "분",
|
||||
"offset": "오프셋 지연",
|
||||
"offset-explain": "첫 번째 작업 실행 후 이 작업을 시작하기 위해 얼마나 기다려야 합니까? (초)",
|
||||
"one-time": "실행 후 삭제",
|
||||
"parent": "상위 일정을 선택하세요",
|
||||
"parent-explain": "이 일정을 트리거할 일정은 무엇인가요?",
|
||||
"reaction": "반응",
|
||||
"restart": "서버 재시작",
|
||||
"select": "기본 / 크론 / 체인 반응선택",
|
||||
"start": "서버 시작",
|
||||
"stop": "서버 종료",
|
||||
"time": "시간",
|
||||
"time-explain": "스케줄을 실행할 시간을 언제로 하시겠습니까?"
|
||||
},
|
||||
"serverSchedules": {
|
||||
"action": "작업",
|
||||
"actionId": "하위 작업 선택",
|
||||
"areYouSure": "스케줄 작업을 삭제할까요?",
|
||||
"cancel": "취소",
|
||||
"cannotSee": "모든 항목이 보이지 않나요?",
|
||||
"cannotSeeOnMobile": "전체 세부정보를 보려면 예약된 작업을 클릭해 보세요.",
|
||||
"child": "ID가 있는 하위 작업 ",
|
||||
"close": "닫기",
|
||||
"command": "명령어",
|
||||
"confirm": "확인",
|
||||
"confirmDelete": "이 스케줄 작업을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
|
||||
"create": "새 스케줄 만들기",
|
||||
"cron": "크론 문자열",
|
||||
"delete": "삭제",
|
||||
"details": "스케줄 상세정보",
|
||||
"edit": "수정",
|
||||
"enabled": "활성화",
|
||||
"every": "매",
|
||||
"interval": "주기",
|
||||
"name": "이름",
|
||||
"newSchedule": "새 스케줄",
|
||||
"nextRun": "다음 실행",
|
||||
"no": "아니요",
|
||||
"no-schedule": "현재 서버에 대한 예약이 없습니다. 시작하려면 다음을 클릭합니다",
|
||||
"scheduledTasks": "스케줄 작업",
|
||||
"yes": "예"
|
||||
},
|
||||
"serverStats": {
|
||||
"cpuUsage": "CPU 사용량",
|
||||
"description": "설명",
|
||||
"errorCalculatingUptime": "업타임 계산 오류",
|
||||
"loadingMotd": "MOTD 로드 중",
|
||||
"memUsage": "메모리 사용량",
|
||||
"offline": "오프라인",
|
||||
"online": "온라인",
|
||||
"players": "플레이어",
|
||||
"serverStarted": "서버 시작됨",
|
||||
"serverStatus": "서버 상태",
|
||||
"serverTime": "UTC 시간",
|
||||
"serverTimeZone": "서버 시간대",
|
||||
"serverUptime": "서버 업타임",
|
||||
"starting": "시작 지연",
|
||||
"unableToConnect": "연결할 수 없음",
|
||||
"version": "버전"
|
||||
},
|
||||
"serverTerm": {
|
||||
"commandInput": "명령어 입력",
|
||||
"delay-explained": "서비스/에이전트가 최근에 시작되어 마인크래프트 서버 인스턴스의 시작을 지연하고 있습니다",
|
||||
"importing": "가져오는 중...",
|
||||
"installing": "설치 중...",
|
||||
"restart": "재시작",
|
||||
"sendCommand": "명령어 보내기",
|
||||
"start": "시작",
|
||||
"starting": "시작 지연",
|
||||
"stop": "정지",
|
||||
"stopScroll": "자동 스크롤 중지",
|
||||
"updating": "업데이트 중..."
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
"accessDenied": {
|
||||
"accessDenied": "ACCES DENID",
|
||||
"contact": "CONTACK CWAFTY CONTROLLR SUPORT ON DA DWISCORDZ",
|
||||
"contactAdmin": "PLZ TALKZ TO UR SERVR HOOMAN FOR DIS, OR IF U FINKZ U SHUD GET IN, ASK SUPORT",
|
||||
"contactAdmin": "PLZ TALKZ TO UR SERVR HOOMAN FOR DIS, OR IF U FINKZ U SHUD GET IN, ASK SUPORT.",
|
||||
"noAccess": "U DO NOT HAZ ACCES 2 DIS LITTERBOX"
|
||||
},
|
||||
"apiKeys": {
|
||||
@ -29,7 +29,6 @@
|
||||
"permName": "PERMISSION NAME",
|
||||
"perms": "PERMISSIONS",
|
||||
"server": "SERVER: ",
|
||||
"superUser": "SUPA DOOPA USR",
|
||||
"yes": "YESH!"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Print"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "No data available in table",
|
||||
"info": "Showing _START_ to _END_ of _TOTAL_ entries",
|
||||
"infoEmpty": "Showing 0 to 0 of 0 entries",
|
||||
"infoFiltered": "(filtered from _MAX_ total entries)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"loadingRecords": "Loading...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "AND THEEZ ",
|
||||
"return": "Go Bak to Dashbored",
|
||||
"selfHost": "If u iz self-hostin' dis repo, check ur addy or peep our fix-it guide.",
|
||||
"serverJars1": "CAN'T TALK TO SERVER JARS API. CHECKZ",
|
||||
"serverJars2": "TO SEE NEWZ STUFFZ.",
|
||||
"start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}",
|
||||
"superError": "U MUST BE A BIG CAT TO DO DIS.",
|
||||
"terribleFailure": "SUMTIN DUN BWOKE"
|
||||
@ -238,7 +235,11 @@
|
||||
"finishedPreparing": "I HAS FINISHD PREPARIN UR FISH. PLZ CLICK DOWNLOAD 2 DOWNLOAD",
|
||||
"logout": "GO BYE BYE",
|
||||
"preparingLogs": " PLZ WAIT WHILE I GATHR UR FISHZ... ILL MAK NOIZE WHEN THEY`RE READY. DIS CUD TAEK WHILE IF UR HOUZ IZ HOOJ.",
|
||||
"supportLogs": "SUPPORT FISHIEZ"
|
||||
"supportLogs": "SUPPORT FISHIEZ",
|
||||
"schedule_desc": "WE NOTICED SOME OR ALL UR SCHEDULED FISH DIDN’T MOVE RIGHT DURING DA UPGRADE. PLS CONFIRM ALL UR FISH IN DA SCHEDULES TAB.",
|
||||
"backup_desc": "WE NOTICED DA BACKUP MIGRASHUN MIGHTA GONE BOOM. PLS CHECK UR BACKUP RECORDZ ON DA BACKUP TAB.",
|
||||
"backup_title": "BACKUP MIGRASHUN OOPSIE",
|
||||
"schedule_title": "SCHEDULES MIGRASHUN OOPSIE"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "NOT HEREZ",
|
||||
@ -554,7 +555,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "ENTR YOUR COMARNED",
|
||||
"delay-explained": "TEH SERVICE/AGENT HUS RESENTLY STARTD AN IZ DELAYIN TEH STARTD OV TEH SERVR",
|
||||
"downloading": "WAIT PLZ!?!?!",
|
||||
"importing": "BRINGINGZ IN...",
|
||||
"installing": "PUTTINGZ TOGETHER...",
|
||||
"restart": "COPYZ",
|
||||
@ -672,7 +672,26 @@
|
||||
"uses": "NUMBER OV USES ALLOWED (-1==NO LIMIT)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "PASSWRD TOO SMOL. NEEDZ 8 CATZ PLZ"
|
||||
"passLength": "PASSWRD TOO SMOL. NEEDZ 8 CATZ PLZ",
|
||||
"backupName": "BACKUP NAME GOTTA BE WURDZ, AT LEAST 3 FISH.",
|
||||
"enumErr": "OOFS IN VALIDATING. GOOD STUFF INCLUDES: ",
|
||||
"serverExeCommand": "SERVER EXECUTION COMMAND GOTTA BE WURDZ, AT LEAST 1 FISH LONG.",
|
||||
"filesPageLen": "LENGTH GOTTA BE MORE THAN 1 FOR DIS PROPERTY",
|
||||
"insufficientPerms": "PERMISSION ERROR: U NEED MORE PERMISSIONZ FOR DIS RESOURCE",
|
||||
"roleManager": "ROLE MANAGER GOTTA BE NUMBERS (MANAGER ID) OR NUFFIN",
|
||||
"roleServerId": "SERVER ID GOTTA BE WURDZ, AT LEAST 1 FISH LONG",
|
||||
"roleServerPerms": "SERVER PERMISSIONS GOTTA BE AN 8-BIT WURDZ",
|
||||
"serverCreateName": "SERVER NAME GOTTA BE WURDZ, AT LEAST 2 FISH LONG AND CAN’T HAVE: \\\\ / or # ",
|
||||
"taskIntervalType": "TASK INTERVAL TYPE GOTTA BE ONE OF: ",
|
||||
"typeBool": "GOTTA BE MEOW OR NEOW (TYPE BOOLEAN)",
|
||||
"typeEmail": "GOTTA BE EMAIL TYPE.",
|
||||
"typeIntMinVal0": "GOTTA BE A WHOLE FISH AT LEAST... 0.",
|
||||
"typeInteger": "GOTTA BE A NUMBR.",
|
||||
"typeList": "GOTTA BE A ARAY ",
|
||||
"typeString": "GOTTA BE STRINGY THINGY.",
|
||||
"roleName": "ROLE NAME GOTTA BE WURDZ, MORE THAN 1 FISH. CAN’T HAVE THESE: [ ] , ",
|
||||
"serverLogPath": "SERVER LOG PATH GOTTA BE WURDZ, AT LEAST 1 FISH LONG",
|
||||
"userName": " GOTTA BE STRINGY THINGY, ALL LOW, AT LEAST 4 FISH, MAX 20 FISHIES"
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "U SURE U WANTZ TO EATZ DIS WEBHOOK?",
|
||||
|
@ -29,7 +29,6 @@
|
||||
"permName": "Atļaujas Nosaukums",
|
||||
"perms": "Atļaujas",
|
||||
"server": "Serveris: ",
|
||||
"superUser": "Super Lietotājs",
|
||||
"yes": "Jā"
|
||||
},
|
||||
"base": {
|
||||
@ -59,7 +58,6 @@
|
||||
"backgroundUpload": "Fona attēla augšupielāde",
|
||||
"customLoginPage": "Pielāgo Pieteikšanās Lapa",
|
||||
"delete": "Dzēst",
|
||||
"installing": "Uztāda...",
|
||||
"labelLoginImage": "Izvēlies savu Pieteikšanās Lapas Fonu",
|
||||
"loginBackground": "Pieteikšanās Fona Attēls",
|
||||
"loginImage": "Augšupielādē fona attēlu priekš pieteikšanās ekrāna.",
|
||||
@ -144,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Drukāt"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Tabulā nav pieejami dati",
|
||||
"info": "Attēlo _START_ līdz _END_ no _TOTAL_ ierakstiem",
|
||||
"infoEmpty": "Attēlo 0 līdz 0 no 0 ierakstiem",
|
||||
"infoFiltered": "(filtrēts no _MAX_ kopējiem ierkstiem)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Attēlo _MENU_ ierakstus",
|
||||
"loadingRecords": "Ielādē...",
|
||||
"paginate": {
|
||||
@ -210,8 +208,6 @@
|
||||
"privMsg": "un ",
|
||||
"return": "Atgriezties uz pārskatu",
|
||||
"selfHost": "Ja jūs paši uzturat šo repozitoriju, pārbaudiet savu adresi vai apskatiet mūsu kļūdu novēršanas dokumentāciju.",
|
||||
"serverJars1": "Serveru JAR API nav sasniedzams. Lūdzu pārbaudiet",
|
||||
"serverJars2": "priekš jaunākās informācijas.",
|
||||
"start-error": "Serveris {} neveiskmīgi startējās ar kļūdas kodu: {}",
|
||||
"superError": "Jums ir jābūt super lietotājam lai veiktu šo darbību.",
|
||||
"terribleFailure": "Kas par neveiksmi!"
|
||||
@ -235,10 +231,14 @@
|
||||
"activityLog": "Aktivitātes Logi",
|
||||
"backupComplete": "Dublējums veiksmīgi pabeigts priekš servera ",
|
||||
"backupStarted": "Dublējums startēts priekš servera ",
|
||||
"backup_desc": "Mēs noteicām ka dublējuma migrācija daļēji vai pilnīgi neizdevās. Lūdzu pārskatiet savus dublējumus dublējumu cilnē.",
|
||||
"backup_title": "Dublējuma Migrācijas Brīdinājums",
|
||||
"downloadLogs": "Lejupielādēt Atbalsta Log Failus?",
|
||||
"finishedPreparing": "Mēs esam pabeiguši sagatavot jūsu atbalsta log datnes. Lūdzu nospiediet lejupielādet lai lejupielādētu",
|
||||
"logout": "Iziet",
|
||||
"preparingLogs": " Lūdzu uzgaidiet kamēr mēs sagatavojam jūsu log datnes... Mēs jums nosūtīsim paziņojumu kad tās būs gatavas. Tas var aizņemt kādu laiku priekš lielām instalācijām.",
|
||||
"schedule_desc": "Mēs noteicām ka daži vai visi no jūsu darbību grafikiem nebija veiksmīgi pārnesti atjauninājuma laikā. Lūdzu pārskatiet savus grafikus grafiku cilnē.",
|
||||
"schedule_title": "Grafiku Migrācijas Brīdinājums",
|
||||
"supportLogs": "Atbalsta Logi"
|
||||
},
|
||||
"offline": {
|
||||
@ -555,7 +555,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Ievadi savu komandu",
|
||||
"delay-explained": "Serviss/aģents tika nesen startēts, un aizkavē Minecraft servera instances startu",
|
||||
"downloading": "Lejupielādē...",
|
||||
"importing": "Importē...",
|
||||
"installing": "Uzstāda...",
|
||||
"restart": "Restartēt",
|
||||
@ -673,7 +672,26 @@
|
||||
"uses": "Dauzums, cik reizes lietot (-1==Bez Limita)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "Parole pārāk īsa. Minimālais Garums: 8"
|
||||
"passLength": "Parole pārāk īsa. Minimālais Garums: 8",
|
||||
"backupName": "Dublējuma nosaukumam jābūt tekstam (string) ar minimālo garumu 3.",
|
||||
"enumErr": "pārbaude neizdevās. Pieņemamie dati ietver: ",
|
||||
"filesPageLen": "garumam jābūt lielākam par 1 priekš vienības",
|
||||
"insufficientPerms": "Piekļuves Kļūda: Nepietiekama atļauja priekš šī resursa",
|
||||
"roleManager": "Lomas pārvaldniekam jābūt skaitlim (pārvaldnieka ID) vai Nekam (None)",
|
||||
"roleName": "Lomas nosaukumam jābūt tekstam (string) kas ir garāks par 1 rakstzīmi. Tas nevar iekļaut sekojošos simbolus: [ ] , ",
|
||||
"roleServerId": "Servera ID vienībai jābūt tekstam (string) ar minimālo garumu 1",
|
||||
"roleServerPerms": "Servera atļaujām jābūt 8-bitu tekstam (string)",
|
||||
"serverCreateName": "Servera nosaukumam jābūt tekstam (string) ar minimumālo garumu 2 un tas nevar saturēt: \\ / vai # ",
|
||||
"serverExeCommand": "Servera izpildes komandai jābūt tekstam (string) ar minimālo garumu 1.",
|
||||
"serverLogPath": "Servera log datņu ceļam ir jābūt tekstam (string) ar minimālo garumu 1",
|
||||
"taskIntervalType": "Notikumu Intervala Tipam jābūt vienam no sekojošiem: ",
|
||||
"typeBool": "jābūt patiesam vai nepatiesam (true vai false, boolean tips)",
|
||||
"typeEmail": "jābūt tipam e-pasts.",
|
||||
"typeInteger": "jābūt skaitlim.",
|
||||
"typeIntMinVal0": "jābūt skaitlim (integer) ar minimālo vērtību 0.",
|
||||
"typeList": "jābūt tipam saraksts/masīvs (list/array) ",
|
||||
"typeString": "jābūt tipam teksts (string).",
|
||||
"userName": " jābūt tipam teksts (string), tikai ar MAZAJIEM BURTIEM, ar 4 rakstzīmju minimālo un 20 rakstzīmju maksimālo garumu"
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "Vai tiešām vēlies noņemt šo webhook?",
|
||||
|
@ -29,7 +29,6 @@
|
||||
"permName": "Machtigingsnaam",
|
||||
"perms": "Machtigingen",
|
||||
"server": "Server: ",
|
||||
"superUser": "Supergebruiker",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Afdrukken"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Geen data beschikbaar in de tabel",
|
||||
"info": "_START_ tot _END_ van _TOTAL_ inzendingen weergeven",
|
||||
"infoEmpty": "0 tot 0 van 0 items weergeven",
|
||||
"infoFiltered": "(gefilterd uit _MAX_ totale inzendingen)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Toon _MENU_ items",
|
||||
"loadingRecords": "Bezig met laden...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "en de ",
|
||||
"return": "Terug naar Dashboard",
|
||||
"selfHost": "Als u deze repository zelf host, controleer dan uw adres of raadpleeg onze handleiding voor probleemoplossing.",
|
||||
"serverJars1": "Server JARs API niet bereikbaar. Controleer alstublieft",
|
||||
"serverJars2": "voor de meest recente informatie.",
|
||||
"start-error": "Server {} kan niet starten met foutcode: {}",
|
||||
"superError": "U moet een supergebruiker zijn om deze actie te voltooien.",
|
||||
"terribleFailure": "Wat een verschrikkelijke mislukking!"
|
||||
@ -234,10 +231,14 @@
|
||||
"activityLog": "Activiteitslogboeken",
|
||||
"backupComplete": "Back-up succesvol voltooid voor server {}",
|
||||
"backupStarted": "Backup gestart voor server {}",
|
||||
"backup_desc": "We hebben gedetecteerd dat de back-upmigratie mogelijk gedeeltelijk of volledig is mislukt. Controleer uw back-uprecords op het tabblad Backups.",
|
||||
"backup_title": "Waarschuwing voor back-upmigratie",
|
||||
"downloadLogs": "Ondersteuningslogboeken downloaden?",
|
||||
"finishedPreparing": "We zijn klaar met het voorbereiden van uw ondersteuningslogboeken. Klik op download om te downloaden",
|
||||
"logout": "Uitloggen",
|
||||
"preparingLogs": " Een ogenblik geduld alstublieft terwijl wij uw logboeken voorbereiden... We sturen een bericht als ze klaar zijn. Dit kan een tijdje duren voor grote implementaties.",
|
||||
"schedule_desc": "We hebben gedetecteerd dat sommige of alle geplande taken niet succesvol zijn overgedragen tijdens de upgrade. Controleer uw schema's op het tabblad Schema's.",
|
||||
"schedule_title": "Waarschuwing voor schemamigratie",
|
||||
"supportLogs": "Ondersteuningslogboeken"
|
||||
},
|
||||
"offline": {
|
||||
@ -554,7 +555,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Voer uw opdracht in",
|
||||
"delay-explained": "De service/agent is onlangs gestart en vertraagt de start van de minecraft-serverinstantie",
|
||||
"downloading": "Aan het downloaden...",
|
||||
"importing": "Importeren...",
|
||||
"installing": "Installeren...",
|
||||
"restart": "Herstarten",
|
||||
@ -672,7 +672,26 @@
|
||||
"uses": "Aantal toegestane gebruiken (-1==Geen Limiet)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "Wachtwoord te kort. Minimumlengte: 8 tekens"
|
||||
"passLength": "Wachtwoord te kort. Minimumlengte: 8 tekens",
|
||||
"backupName": "De naam van de back-up moet een string zijn en een minimale lengte van 3 hebben.",
|
||||
"enumErr": "validatie mislukt. Accepteerbare gegevens zijn: ",
|
||||
"filesPageLen": "De lengte moet groter zijn dan 1 voor eigenschap",
|
||||
"insufficientPerms": "Machtigingsfout: Ontbrekende machtigingen voor deze resource",
|
||||
"roleManager": "Rollenbeheerder moet van het type integer (manager-ID) of None zijn",
|
||||
"roleName": "De rolnaam moet een string zijn die groter is dan 1 teken. Deze mag geen van de volgende symbolen bevatten: [ ] , ",
|
||||
"roleServerId": "De eigenschap Server ID moet een string zijn met een minimale lengte van 1",
|
||||
"roleServerPerms": "Servermachtigingen moeten een 8-bits string zijn",
|
||||
"serverCreateName": "De servernaam moet een string zijn met een minimale lengte van 2 en mag niet bevatten: \\ / of # ",
|
||||
"serverExeCommand": "Het serveruitvoeringscommando moet een string zijn met een minimale lengte van 1.",
|
||||
"serverLogPath": "Het pad naar het serverlogboek moet een string zijn met een minimale lengte van 1",
|
||||
"taskIntervalType": "Het type taakinterval moet een van de volgende zijn: ",
|
||||
"typeBool": "moet true of false zijn (type boolean)",
|
||||
"typeEmail": "moet van het type e-mail zijn.",
|
||||
"typeInteger": "moet een getal zijn.",
|
||||
"typeIntMinVal0": "moet een geheel getal zijn met een minimale waarde van 0.",
|
||||
"typeList": "moet van het type lijst/array zijn ",
|
||||
"typeString": "moet van het type string zijn.",
|
||||
"userName": " moet van het type string zijn, volledig in KLEINE LETTERS, minimaal 4 tekens en maximaal 20 tekens"
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "Weet u zeker dat u deze webhook wilt verwijderen?",
|
||||
|
@ -28,7 +28,6 @@
|
||||
"permName": "Toestemming naam",
|
||||
"perms": "Toestemmingen",
|
||||
"server": "Server: ",
|
||||
"superUser": "Super Gebruiker",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"base": {
|
||||
@ -131,7 +130,7 @@
|
||||
"info": "_START_ tot _END_ van _TOTAL_ entries",
|
||||
"infoEmpty": "0 tot 0 van 0 entries",
|
||||
"infoFiltered": "(Gefilterd van _MAX_ totale entries)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "_MENU_ entries laten zien",
|
||||
"loadingRecords": "Laden...",
|
||||
"paginate": {
|
||||
@ -437,7 +436,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Commando invoeren",
|
||||
"delay-explained": "De service/agent is recentelijk gestart en stelt de start uit van de Minecraft-serverinstantie",
|
||||
"downloading": "Aan het downloaden...",
|
||||
"restart": "Restarten",
|
||||
"sendCommand": "Commando versturen",
|
||||
"start": "Starten",
|
@ -29,7 +29,6 @@
|
||||
"permName": "Nazwa permisji",
|
||||
"perms": "Permisje",
|
||||
"server": "Serwer: ",
|
||||
"superUser": "Super użytkownik",
|
||||
"yes": "Tak"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Wydrukuj"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Brak danych w tej tabeli danych",
|
||||
"info": "Pokazywanie od _START_ do _END_ z _TOTAL_ wszystkich wejść",
|
||||
"infoEmpty": "Pokazywanie 0 do 0 z 0 wejść",
|
||||
"infoFiltered": "(Pokazuje z _MAX_ wejść)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Pokazuj _MENU_ wejść",
|
||||
"loadingRecords": "Wczytywanie...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "i także ",
|
||||
"return": "Powrót do panelu",
|
||||
"selfHost": "Jeśli zarządasz tą repozytorią upewnij się że adres hest poprawny, w innym przypadku odwiedź strone rozwiązywania problemów.",
|
||||
"serverJars1": "API Server Jars jest niedostępne. Proszę sprawdź",
|
||||
"serverJars2": "dla najnowzsych informacji.",
|
||||
"start-error": "Serwer {} nie mógł się odpalić z powodu: {}",
|
||||
"superError": "Potrzebujesz uprawnienie Adminitsratora aby zakończyć tę akcję.",
|
||||
"terribleFailure": "Okropny błąd!"
|
||||
|
@ -28,7 +28,6 @@
|
||||
"permName": "Nome da Permissão",
|
||||
"perms": "Permissões",
|
||||
"server": "Servidor: ",
|
||||
"superUser": "Super Usuário",
|
||||
"yes": "Sim"
|
||||
},
|
||||
"base": {
|
||||
@ -127,12 +126,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Imprimir"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Nenhum dado disponível na tabela",
|
||||
"info": "Exibindo de _START_ a _END_ de _TOTAL_ entradas",
|
||||
"infoEmpty": "Exibindo de 0 a 0 de 0 entradas",
|
||||
"infoFiltered": "(filtrado de _MAX_ entradas totais)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Exibir _MENU_ entradas",
|
||||
"loadingRecords": "Carregando...",
|
||||
"paginate": {
|
||||
@ -445,7 +444,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "Insira seu comando",
|
||||
"delay-explained": "O serviço/agente iniciou recentemente e está atrasando o início da instância do servidor de minecraft",
|
||||
"downloading": "Baixando...",
|
||||
"restart": "Reiniciar",
|
||||
"sendCommand": "Enviar comando",
|
||||
"start": "Iniciar",
|
@ -56,13 +56,13 @@
|
||||
"customLogin": {
|
||||
"apply": "Применить",
|
||||
"backgroundUpload": "Загрузка фона",
|
||||
"customLoginPage": "Настройки страницы входа в систему",
|
||||
"customLoginPage": "Настройте страницу входа в систему",
|
||||
"delete": "Удалить",
|
||||
"labelLoginImage": "Выберите фон для входа в систему",
|
||||
"loginBackground": "Фоновое изображение входа в систему",
|
||||
"loginImage": "Загрузите фоновое изображение для экрана входа в систему.",
|
||||
"loginOpacity": "Выберите непрозрачность окна входа в систему",
|
||||
"pageTitle": "Настройки страницы входа в систему",
|
||||
"pageTitle": "Кастомизированная страница входа в систему",
|
||||
"preview": "Превью",
|
||||
"select": "Выбрать",
|
||||
"selectImage": "Выбрать изображение"
|
||||
@ -70,7 +70,7 @@
|
||||
"dashboard": {
|
||||
"actions": "Действия",
|
||||
"allServers": "Все серверы",
|
||||
"avg": "Avg",
|
||||
"avg": "Среднее значение",
|
||||
"backups": "Бэкапы",
|
||||
"bePatientClone": "Пожалуйста, наберитесь терпения, пока мы будем клонировать сервер.<br /> Этот экран обновится через мгновение",
|
||||
"bePatientRestart": "Пожалуйста, наберитесь терпения, пока мы перезапускаем сервер.<br /> Этот экран обновится через мгновение",
|
||||
@ -142,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Печать"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Данные в таблице отсутствуют",
|
||||
"info": "Отображение от _START_ до _END_ из _TOTAL_ записей",
|
||||
"infoEmpty": "Отображение от 0 до 0 из 0 записей",
|
||||
"infoFiltered": "(отфильтровано по _MAX_ количеству записей)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Показывать записи _MENU_",
|
||||
"loadingRecords": "Загрузка...",
|
||||
"paginate": {
|
||||
@ -192,7 +192,7 @@
|
||||
"embarassing": "О боже, ну что ж, это так неловко.",
|
||||
"error": "Ошибка!",
|
||||
"eulaAgree": "Вы согласны?",
|
||||
"eulaMsg": "Вы должны согласиться с",
|
||||
"eulaMsg": "Вы должны согласиться с ",
|
||||
"eulaTitle": "Согласитесь с EULA",
|
||||
"fileError": "Типом файла должно быть изображение.",
|
||||
"fileTooLarge": "Ошибка загрузки. Загружен слишком большой файл. Обратитесь за помощью к системному администратору.",
|
||||
@ -235,7 +235,11 @@
|
||||
"finishedPreparing": "Мы закончили подготовку ваших журналов поддержки. Пожалуйста, нажмите загрузить, чтобы загрузить",
|
||||
"logout": "Выход из системы",
|
||||
"preparingLogs": " Пожалуйста, подождите, пока мы подготовим ваши журналы... Мы отправим уведомление, когда они будут готовы. При больших объемах развертывания это может занять некоторое время.",
|
||||
"supportLogs": "Журналы поддержки"
|
||||
"supportLogs": "Журналы поддержки",
|
||||
"backup_desc": "Мы обнаружили, что перенос резервной копии, возможно, завершился частичным или полным сбоем. Пожалуйста, подтвердите свои записи в резервных копиях на вкладке резервные копии.",
|
||||
"schedule_desc": "Мы обнаружили, что некоторые или все запланированные вами задачи не были успешно перенесены во время обновления. Пожалуйста, подтвердите свои расписания на вкладке расписания.",
|
||||
"backup_title": "Предупреждение о переносе резервной копии",
|
||||
"schedule_title": "Предупреждение о переносе расписаний"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "Оффлайн",
|
||||
@ -313,7 +317,7 @@
|
||||
"confirmRestore": "Вы уверены, что хотите выполнить восстановление из этой резервной копии? Все текущие файлы сервера перейдут в состояние резервной копии и будут недоступны восстановлению.",
|
||||
"currentBackups": "Текущие резервные копии",
|
||||
"default": "Резервное копирование по умолчанию",
|
||||
"defaultExplain": "Резервная копия, которую Crafty будет использовать перед обновлением. Ее нельзя изменить или удалить.",
|
||||
"defaultExplain": "Резервная копия, которую Crafty будет создавать перед обновлением. Ее нельзя изменить или удалить.",
|
||||
"delete": "Удалить",
|
||||
"destroyBackup": "Уничтожить резервную копию \" + file_to_del + \"?",
|
||||
"download": "Скачать",
|
||||
@ -324,7 +328,7 @@
|
||||
"exclusionsTitle": "Исключения из резервного копирования",
|
||||
"failed": "Неудача",
|
||||
"maxBackups": "Максимально резервных копий",
|
||||
"maxBackupsDesc": "Crafty не будет хранить более N резервных копий, удаляя самые старые (введите 0, чтобы сохранить все).",
|
||||
"maxBackupsDesc": "Crafty не будет хранить более N резервных копий, удаляя самые старые (введите 0, чтобы сохранить все)",
|
||||
"myBackup": "Моя новая резервная копия",
|
||||
"name": "Имя",
|
||||
"newBackup": "Создать новую резервную копию",
|
||||
@ -358,8 +362,8 @@
|
||||
"deleteServerQuestionMessage": "Вы уверены, что хотите удалить этот сервер? После этого пути назад не будет...",
|
||||
"exeUpdateURL": "URL-адрес обновления исполняемого файла сервера",
|
||||
"exeUpdateURLDesc": "Прямой URL-адрес для загрузки обновлений.",
|
||||
"ignoredExits": "Игнорируемые коды аварийного выхода",
|
||||
"ignoredExitsExplain": "Коды выхода при обнаружении сбоя Crafty следует игнорировать как обычную 'остановку' (через запятую).",
|
||||
"ignoredExits": "Игнорируемые коды аварийной остановки",
|
||||
"ignoredExitsExplain": "Коды остановки сервера, при обнаружении которых Crafty будет их игнорировать, чтобы не воспринимать как сбой сервера (вводить через запятую)",
|
||||
"javaNoChange": "Не переопределять",
|
||||
"javaVersion": "Переопределить текущую версию Java",
|
||||
"javaVersionDesc": "Если вы собираетесь переопределить Java, убедитесь, что ваш текущий путь к Java указан в 'Команда выполнения сервера' и заключен в кавычки (по умолчанию 'java')",
|
||||
@ -397,7 +401,7 @@
|
||||
"stopBeforeDeleting": "Пожалуйста, остановите сервер перед его удалением",
|
||||
"timeoutExplain1": "Как долго Crafty будет ждать завершения работы вашего сервера после выполнения",
|
||||
"timeoutExplain2": "выполните команду до того, как она остановит процесс.",
|
||||
"update": "Исполняемый файл обновления",
|
||||
"update": "Обновить исполняемый файл",
|
||||
"yesDelete": "Да, удалить",
|
||||
"yesDeleteFiles": "Да, удалить файлы"
|
||||
},
|
||||
@ -614,7 +618,6 @@
|
||||
"dashboard": "Приборная панель",
|
||||
"documentation": "Документация",
|
||||
"inApp": "Документация в приложении",
|
||||
"navigation": "Навигация",
|
||||
"newServer": "Создать новый сервер",
|
||||
"servers": "Серверы"
|
||||
},
|
||||
@ -642,7 +645,7 @@
|
||||
"deleteUser": "Удалить пользователя: ",
|
||||
"deleteUserB": "Удалить пользователя",
|
||||
"enabled": "Включён",
|
||||
"gravDesc": "Это электронное письмо предназначено исключительно для использования с Gravatar™. Crafty ни при каких обстоятельствах не будет использовать это электронное письмо для чего-либо, кроме поиска вашего Gravatar™",
|
||||
"gravDesc": "Эта электронная почта предназначена исключительно для использования с Gravatar™. Crafty ни при каких обстоятельствах не будет использовать эту электронную почту для чего-либо, кроме поиска вашего Gravatar™",
|
||||
"gravEmail": "Gravatar™ Email",
|
||||
"lastIP": "Последний IP: ",
|
||||
"lastLogin": "Последний вход в систему: ",
|
||||
@ -669,7 +672,26 @@
|
||||
"uses": "Количество использований (-1==без ограничений)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "Пароль слишком короткий. Минимальная длина: 8"
|
||||
"passLength": "Пароль слишком короткий. Минимальная длина: 8",
|
||||
"roleManager": "Роль менеджера должна быть типа integer (ID менеджера) или None",
|
||||
"filesPageLen": "длина свойства должна быть больше 1",
|
||||
"serverCreateName": "Имя сервера должно быть строкой длиной не менее 2-х символов и не должно содержать: \\ / или # ",
|
||||
"typeString": "должен быть типа string.",
|
||||
"backupName": "Имя резервной копии должно быть строкой и иметь длину не менее 3-х символов.",
|
||||
"roleServerId": "Свойство «ID сервера» должно быть строкой с минимальной длиной 1",
|
||||
"userName": " должно быть типа string, все в НИЖНЕМ регистре, минимум из 4 символов и максимум из 20 символов",
|
||||
"taskIntervalType": "Тип интервала выполнения задачи должен быть одним из следующих: ",
|
||||
"typeIntMinVal0": "должно быть целым числом с минимальным значением 0.",
|
||||
"enumErr": "не удалось выполнить проверку. Допустимые данные включают: ",
|
||||
"insufficientPerms": "Ошибка разрешения: Отсутствуют разрешения для этого ресурса",
|
||||
"roleName": "Имя роли должно быть строкой длиной более 1 символа. Оно не должно содержать ни одного из следующих символов: [ ] , ",
|
||||
"roleServerPerms": "Разрешения сервера должны быть 8-разрядной строкой",
|
||||
"serverExeCommand": "Команда выполнения сервера должна представлять собой строку минимальной длины, равной 1 символ.",
|
||||
"serverLogPath": "Путь к журналу сервера должен быть строкой длиной не менее 1 символ",
|
||||
"typeBool": "должно быть true или false (тип boolean)",
|
||||
"typeEmail": "должен быть тип email.",
|
||||
"typeInteger": "должно быть типа - число.",
|
||||
"typeList": "должен быть типа list/array "
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "Вы уверены, что хотите удалить этот вебхук?",
|
||||
|
@ -29,7 +29,6 @@
|
||||
"permName": "ชื่อการอนุญาต",
|
||||
"perms": "สิทธิ์อนุญาต",
|
||||
"server": "เซิร์ฟเวอร์: ",
|
||||
"superUser": "Super User",
|
||||
"yes": "ใช่"
|
||||
},
|
||||
"base": {
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Print"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "ไม่มีข้อมูลในตาราง",
|
||||
"info": "แสดงรายการ _START_ ถึง _END_ จากทั้งหมด _TOTAL_ รายการ",
|
||||
"infoEmpty": "แสดงรายการ 0 ถึง 0 จากทั้งหมด 0 รายการ",
|
||||
"infoFiltered": "(กรองจากรายการทั้งหมด _MAX_ รายการ)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "แสดง _MENU_ รายการ",
|
||||
"loadingRecords": "กำลังโหลด...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "และ ",
|
||||
"return": "ย้อนกลับไปยังแผงควบคุม",
|
||||
"selfHost": "หากคุณโฮสต์ repo นี้ด้วยตนเอง โปรดตรวจสอบที่อยู่ของคุณ หรือศึกษาคู่มือแก้ปัญหาของเรา",
|
||||
"serverJars1": "ไม่สามารถเข้าถึงเซิร์ฟเวอร์ JARs API กรุณาตรวจสอบ",
|
||||
"serverJars2": "เพื่อข้อมูลที่ทันสมัยที่สุด",
|
||||
"start-error": "เซิร์ฟเวอร์ {} ไม่สามารถเริ่มต้นได้เนื่องจากรหัสข้อผิดพลาด: {}",
|
||||
"superError": "คุณต้องเป็น Super User จึงจะดำเนินการนี้ได้",
|
||||
"terribleFailure": "นี่มันเป็นความล้มเหลวครั้งยิ่งใหญ่!"
|
||||
@ -238,7 +235,11 @@
|
||||
"finishedPreparing": "เราได้เตรียมบันทึกการสนับสนุนของคุณเสร็จแล้ว กรุณาคลิกดาวน์โหลดเพื่อดาวน์โหลด",
|
||||
"logout": "ออกจากระบบ",
|
||||
"preparingLogs": " โปรดรอสักครู่ในขณะที่เราเตรียมบันทึกของคุณ... เราจะส่งการแจ้งเตือนเมื่อเสร็จสิ้น การดำเนินการนี้อาจใช้เวลาสักครู่สำหรับการเตรียมข้อมูลขนาดใหญ่",
|
||||
"supportLogs": "บันทึกการสนับสนุน"
|
||||
"supportLogs": "บันทึกการสนับสนุน",
|
||||
"schedule_desc": "เราตรวจพบว่างานตามกำหนดการบางส่วนหรือทั้งหมดของคุณโอนย้ายไม่สำเร็จในระหว่างการอัปเกรด โปรดยืนยันกำหนดการของคุณในแท็บกำหนดการ",
|
||||
"backup_desc": "เราตรวจพบว่าการย้ายข้อมูลสำรองอาจล้มเหลวบางส่วนหรือทั้งหมด โปรดยืนยันข้อมูลสำรองของคุณในหน้าข้อมูลสำรอง",
|
||||
"backup_title": "คำเตือนการโยกย้ายข้อมูลสำรอง",
|
||||
"schedule_title": "คำเตือนการโยกย้ายกำหนดการ"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "ออฟไลน์",
|
||||
@ -671,7 +672,26 @@
|
||||
"uses": "จำนวนการใช้งานที่อนุญาต (-1==ไม่มีขีดจำกัด)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "รหัสผ่านสั้นเกินไป จำนวนตัวอักขระขั้นต่ำ: 8"
|
||||
"passLength": "รหัสผ่านสั้นเกินไป จำนวนตัวอักขระขั้นต่ำ: 8",
|
||||
"roleManager": "ผู้จัดการบทบาทต้องเป็นประเภทจำนวนเต็ม (ID ผู้จัดการ) หรือเป็น None",
|
||||
"roleName": "ชื่อบทบาทต้องเป็นสตริงที่มีความยาวมากกว่า 1 ตัวอักษร และต้องไม่มีสัญลักษณ์ใด ๆ ดังนี้: [ ] , ",
|
||||
"filesPageLen": "ความยาวต้องมากกว่า 1 สำหรับคุณสมบัติ",
|
||||
"typeIntMinVal0": "ต้องเป็นจำนวนเต็มที่มีค่าต่ำสุดเป็น 0",
|
||||
"userName": " ต้องเป็นประเภทสตริง, ตัวอักษรตัวเล็กทั้งหมด, มีความยาวอย่างน้อย 4 ตัวอักษร และไม่เกิน 20 ตัวอักษร",
|
||||
"serverCreateName": "ชื่อเซิร์ฟเวอร์ต้องเป็นสตริงที่มีความยาวอย่างน้อย 2 ตัวอักษร และต้องไม่มีสัญลักษณ์: \\\\ / หรือ # ",
|
||||
"serverLogPath": "เส้นทางบันทึกเซิร์ฟเวอร์ต้องเป็นสตริงที่มีความยาวอย่างน้อย 1 ตัวอักษร",
|
||||
"taskIntervalType": "ประเภทช่วงเวลาในการทำงานต้องเป็นหนึ่งในสิ่งต่อไปนี้: ",
|
||||
"backupName": "ชื่อการสำรองข้อมูลจะต้องเป็นสตริงและมีความยาวขั้นต่ำ 3 ตัวอักษร",
|
||||
"enumErr": "การตรวจสอบล้มเหลว ข้อมูลที่ยอมรับได้ ได้แก่: ",
|
||||
"insufficientPerms": "ข้อผิดพลาดการอนุญาต: ขาดการอนุญาตสำหรับทรัพยากรนี้",
|
||||
"roleServerId": "ID เซิร์ฟเวอร์ต้องเป็นสตริงที่มีความยาวอย่างน้อย 1 ตัวอักษร",
|
||||
"roleServerPerms": "สิทธิ์การใช้งานเซิร์ฟเวอร์ต้องเป็นสตริงแบบ 8 บิต",
|
||||
"serverExeCommand": "คำสั่งในการดำเนินการเซิร์ฟเวอร์ต้องเป็นสตริงที่มีความยาวอย่างน้อย 1 ตัวอักษร",
|
||||
"typeBool": "ต้องเป็น true หรือ false (ชนิดบูลีน)",
|
||||
"typeEmail": "ต้องเป็นประเภทอีเมล",
|
||||
"typeInteger": "ต้องเป็นตัวเลข",
|
||||
"typeList": "ต้องเป็นประเภทลิสต์/อาร์เรย์ ",
|
||||
"typeString": "ต้องเป็นประเภทสตริง"
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "คุณแน่ใจหรือไม่ว่าต้องการลบ Webhook นี้?",
|
||||
|
@ -23,13 +23,12 @@
|
||||
"fullAccess": "Tam Erişim",
|
||||
"getToken": "Bir Token Al",
|
||||
"name": "Ad",
|
||||
"nameDesc": "Bu API tokeninin adı ne olsun?",
|
||||
"nameDesc": "Bu API tokeninin adı ne olsun? ",
|
||||
"no": "Hayır",
|
||||
"pageTitle": "Kullanıcı API Anahtarlarını Düzenle",
|
||||
"permName": "Yetki İsmi",
|
||||
"perms": "Yetkiler",
|
||||
"server": "Sunucu: ",
|
||||
"superUser": "Süper Kullanıcı",
|
||||
"yes": "Evet"
|
||||
},
|
||||
"base": {
|
||||
@ -75,7 +74,7 @@
|
||||
"backups": "Yedeklemeler",
|
||||
"bePatientClone": "Sunucuyu klonlarken lütfen sabırlı olunuz.<br /> Bu ekran birazdan kendini yenileyecektir",
|
||||
"bePatientRestart": "Sunucuyu yeniden başlatırken lütfen sabırlı olunuz.<br /> Bu ekran birazdan kendini yenileyecektir",
|
||||
"bePatientStart": "Sunucuyu başlatırken başlatırken lütfen sabırlı olunuz.<br /> Bu ekran birazdan kendini yenileyecektir",
|
||||
"bePatientStart": "Sunucuyu başlatırken lütfen sabırlı olunuz.<br /> Bu ekran birazdan kendini yenileyecektir.",
|
||||
"bePatientStop": "Sunucuyu durdururken başlatırken lütfen sabırlı olunuz.<br /> Bu ekran birazdan kendini yenileyecektir",
|
||||
"cannotSee": "Gözükmeyen şeyler mi var?",
|
||||
"cannotSeeOnMobile": "Mobilde gözükmeyen şeyler mi var?",
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Yazdır"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Tabloda veri bulunmuyor",
|
||||
"info": "_TOTAL_ kayıttan _START_ - _END_ arasındaki kayıtlar gösteriliyor",
|
||||
"infoEmpty": "0 kayıttan 0 - 0 arasındaki kayıtlar gösteriliyor",
|
||||
"infoFiltered": "(_MAX_ kayıt içerisinden filtrelenen)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "_MENU_ kayıt göster",
|
||||
"loadingRecords": "Yükleniyor...",
|
||||
"paginate": {
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "ve ",
|
||||
"return": "Arayüze Geri Dön",
|
||||
"selfHost": "Bu depoyu kendiniz barındırıyorsanız lütfen adresinizi kontrol ediniz veya sorun giderme kılavuzumuza bakınız.",
|
||||
"serverJars1": "Sunucu JARs API'ına erişilemiyor.",
|
||||
"serverJars2": "en güncel bilgilere sahiptir",
|
||||
"start-error": "{} sunucusu başlamatılamadı. Hata kodu: {}",
|
||||
"superError": "Bu işlemi tamamlamak için süper kullanıcı olmanız gerekir.",
|
||||
"terribleFailure": "Ne Korkunç Bir Hata!"
|
||||
@ -238,7 +235,11 @@
|
||||
"finishedPreparing": "Destek günlüklerinizi hazırlamayı tamamladık. İndirmek için lütfen indir'e tıklayın",
|
||||
"logout": "Oturumu Kapat",
|
||||
"preparingLogs": " Günlüklerinizi hazırlarken lütfen bekleyin... Hazır olduklarında bir bildirim göndereceğiz. Bu, büyük dağıtımlar için biraz zaman alabilir.",
|
||||
"supportLogs": "Destek Günlükleri"
|
||||
"supportLogs": "Destek Günlükleri",
|
||||
"backup_desc": "Yedek taşımasının kısmen veya tamamen başarısız olmuş olabileceğini tespit ettik. Lütfen yedekler sekmesindeki yedek kayıtlarınızı kontrol edin.",
|
||||
"schedule_desc": "Yükseltme sırasında zamanlanmış görevlerinizin bir kısmının veya tamamının başarıyla aktarılmadığını tespit ettik. Lütfen zamanlamalar sekmesinden zamanlamalarınızı onaylayın.",
|
||||
"backup_title": "Yedek Taşıma Uyarısı",
|
||||
"schedule_title": "Zamanlama Taşıma Uyarısı"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "Çevrimdışı",
|
||||
@ -304,7 +305,7 @@
|
||||
"actions": "Eylemler",
|
||||
"after": "Yedeklemeden sonra bir komut çalıştır",
|
||||
"backupAtMidnight": "Gece yarısında otomatik yedekleme yapılsın mı?",
|
||||
"backupNow": "Backup Now!",
|
||||
"backupNow": "Şimdi Yedekle!",
|
||||
"backupTask": "Bir yedekleme görevi başlatıldı.",
|
||||
"backups": "Sunucu Yedekleri",
|
||||
"before": "Yedeklemeden önce bir komut çalıştır",
|
||||
@ -529,7 +530,7 @@
|
||||
"newSchedule": "Yeni Zamanlama",
|
||||
"nextRun": "Sonraki Çalışma",
|
||||
"no": "Hayır",
|
||||
"no-schedule": "Şu anda bu sunucu için herhangi bir zamanlama bulunmamaktadır. Başlamak için: ",
|
||||
"no-schedule": "Şu anda bu sunucu için herhangi bir zamanlama bulunmamaktadır. Başlamak için:",
|
||||
"scheduledTasks": "Zamanlanmış Görevler",
|
||||
"yes": "Evet"
|
||||
},
|
||||
|
@ -1,18 +1,18 @@
|
||||
{
|
||||
"404": {
|
||||
"contact": "Зв'язатись з Crafty Control підтримкою через Discord",
|
||||
"notFound": "Сторінку не найдено!",
|
||||
"notFound": "Сторінку не найдено",
|
||||
"unableToFind": "Нам не вдалося знайти сторінку, яку ви шукаєте. Спробуйте ще раз або поверніться й оновіть."
|
||||
},
|
||||
"accessDenied": {
|
||||
"accessDenied": "Доступ заборонено",
|
||||
"contact": "Зв'язатись з Crafty Control підтримкою через Discord",
|
||||
"contactAdmin": "Щоб отримати доступ до цього ресурсу, зверніться до адміністратора свого сервера або, якщо ви вважаєте, що вже маєте доступ до цього ресурсу, зверніться до служби підтримки.",
|
||||
"noAccess": "У вас немає доступу до цього ресурсу."
|
||||
"noAccess": "У вас немає доступу до цього ресурсу"
|
||||
},
|
||||
"apiKeys": {
|
||||
"apiKeys": "API Ключі",
|
||||
"auth": "Авторизовані?",
|
||||
"auth": "Авторизовані? ",
|
||||
"buttons": "Кнопки",
|
||||
"config": "Конфігурація",
|
||||
"crafty": "Crafty: ",
|
||||
@ -23,13 +23,12 @@
|
||||
"fullAccess": "Повний доступ",
|
||||
"getToken": "Отримати Токен",
|
||||
"name": "Ім'я",
|
||||
"nameDesc": "Як ви хочете назвати даний API токен?",
|
||||
"nameDesc": "Як ви хочете назвати даний API токен? ",
|
||||
"no": "Ні",
|
||||
"pageTitle": "Редагування Користувацьких API ключів",
|
||||
"permName": "Назва дозволу",
|
||||
"perms": "Дозволи",
|
||||
"server": "Сервер: ",
|
||||
"superUser": "СуперЮзер",
|
||||
"yes": "Так"
|
||||
},
|
||||
"base": {
|
||||
@ -99,7 +98,7 @@
|
||||
"motd": "MOTD",
|
||||
"newServer": "Створити новий сервер",
|
||||
"nextBackup": "Наступний:",
|
||||
"no-servers": "Зараз відсутні сервери. Щоб розпочати, натисніть.",
|
||||
"no-servers": "Зараз відсутні сервери. Щоб розпочати, натисніть",
|
||||
"offline": "Оффлайн",
|
||||
"online": "Онлайн",
|
||||
"players": "Гравці",
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "Друк"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "Немає даних у цій таблиці",
|
||||
"info": "Показ _START_ до _END_ з _TOTAL_ рядків",
|
||||
"infoEmpty": "Показ 0 до 0 з 0 рядків",
|
||||
"infoFiltered": "(відфльтровано з _MAX_ загалом рядків)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "Показати _MENU_ рядки",
|
||||
"loadingRecords": "Завантаження...",
|
||||
"paginate": {
|
||||
@ -200,7 +199,7 @@
|
||||
"hereIsTheError": "Ось помилка",
|
||||
"installerJava": "Не вдалось встановити {} : Forge сервер потребує Java. Ми бачимо що, Java не інстальована. Будь ласка, встановіть java і лиш тоді сервер.",
|
||||
"internet": "Ми виявили, що машина, на якій працює Crafty, не має підключення до Інтернету. Підключення клієнта до сервера може бути обмежено.",
|
||||
"migration": "Основне серверне сховище Crafty переноситься в нове місце. На цей час усі запуски серверів призупинено. Зачекайте, поки ми завершимо цю міграцію.",
|
||||
"migration": "Основне серверне сховище Crafty переноситься в нове місце. На цей час усі запуски серверів призупинено. Зачекайте, поки ми завершимо цю міграцію",
|
||||
"no-file": "Здається, ми не можемо знайти потрібний файл. Ще раз перевірте шлях. Чи має Crafty належні дозволи?",
|
||||
"noInternet": "Crafty має проблеми з доступом до Інтернету. Створення сервера вимкнено. Перевірте підключення до Інтернету та оновіть сторінку.",
|
||||
"noJava": "Сервер {} не вдалося запустити з кодом помилки: ми виявили, що Java не встановлено. Установіть Java, а потім запустіть сервер.",
|
||||
@ -209,8 +208,6 @@
|
||||
"privMsg": "і ",
|
||||
"return": "Повернутись до панелі",
|
||||
"selfHost": "Якщо ви самостійно розміщуєте цей репозеторій, перевірте свою адресу або зверніться до нашого посібника з усунення несправностей.",
|
||||
"serverJars1": "API сервера JAR недоступний. Будь ласка, перевірте",
|
||||
"serverJars2": "для найактуальнішої інформації.",
|
||||
"start-error": "Сервер {} не запустився через помилку: {}",
|
||||
"superError": "Ви маєте мати права суперюзера для виконання даного завдання.",
|
||||
"terribleFailure": "Яка Жахлива Невдача!"
|
||||
@ -234,10 +231,14 @@
|
||||
"activityLog": "Логи активностей",
|
||||
"backupComplete": "Бекап успішно завершено для сервера {}",
|
||||
"backupStarted": "Бекап успішно розпочато для сервера {}",
|
||||
"backup_desc": "Ми зафіксували, що міграція бекапів можливо частково або повністю провалилась. Будь ласка перевірте ваші записи бекапів у відповідній вкладці.",
|
||||
"backup_title": "Увага міграція бекапів",
|
||||
"downloadLogs": "Завантажити логи для підтримки?",
|
||||
"finishedPreparing": "Ми підготували логи. Будь ласка натисніть завантажити",
|
||||
"logout": "Вихід",
|
||||
"preparingLogs": "Будь ласка зачекайте поки ми підготуємо для вас логи... Ми надішлемо вам сповіщення коли усе буде готово. Це може зайняти трішки часу для великих проєктів.",
|
||||
"preparingLogs": " Будь ласка зачекайте поки ми підготуємо для вас логи... Ми надішлемо вам сповіщення коли усе буде готово. Це може зайняти трішки часу для великих проєктів.",
|
||||
"schedule_desc": "Ми зафіксували, що деякі або всі ваші заплановані завдання не вдалось успішно перенести поки робиться оновлення. Будь ласка перевірте ваші заплановані завдання у відповідній вкладці.",
|
||||
"schedule_title": "Увага міграція запланованих завдань",
|
||||
"supportLogs": "Логи для підтримки"
|
||||
},
|
||||
"offline": {
|
||||
@ -262,7 +263,7 @@
|
||||
"match": "Паролі мають співпадати",
|
||||
"newRole": "Додати нову роль",
|
||||
"newUser": "Додати нового користувача",
|
||||
"noMounts": "Show no Mounts on Dash",
|
||||
"noMounts": "Не показувати диски на панелі",
|
||||
"pageTitle": "Панель конфігурації",
|
||||
"role": "Роль",
|
||||
"roleUsers": "Ролі юзерів",
|
||||
@ -281,7 +282,7 @@
|
||||
"configUpdate": "Востаннє оновлено: ",
|
||||
"created": "Створено: ",
|
||||
"delRole": "Видалити роль",
|
||||
"doesNotExist": "Ви не можете видалити те, чого не існує!",
|
||||
"doesNotExist": "Ви не можете видалити те, чого не існує",
|
||||
"pageTitle": "Редагувати роль",
|
||||
"pageTitleNew": "Нова роль",
|
||||
"permAccess": "Доступ?",
|
||||
@ -313,7 +314,7 @@
|
||||
"compress": "Стиснути бекап",
|
||||
"confirm": "Прийняти",
|
||||
"confirmDelete": "Ви дійсно бажаєте видати бекап? Ця дія незворотня.",
|
||||
"confirmRestore": "Ви впевненні що бажаєте відновити даний бекап? При відновленні сервер буде вимкнуто та відновлено за допомогою даного бекапу, минулі файли будуть втрачені!",
|
||||
"confirmRestore": "Ви впевненні що бажаєте відновити даний бекап? При відновленні сервер буде вимкнуто та відновлено за допомогою даного бекапу, минулі файли будуть втрачені.",
|
||||
"currentBackups": "Поточні бекапи",
|
||||
"default": "Звичайний Бекап",
|
||||
"defaultExplain": "Бекап цього Crafty буде створений перед оновленням. Це не можна змінити чи видалити.",
|
||||
@ -349,7 +350,7 @@
|
||||
"serverConfig": {
|
||||
"bePatientDelete": "Будь ласка зачекайте поки Crafty видалить сервер з панелі. Ця сторінка закриється через кілька секунд.",
|
||||
"bePatientDeleteFiles": "Будь ласка зачекайте поки Crafty видалить сервер з панелі та видалить усі його файли. Ця сторінка закриється через кілька секунд.",
|
||||
"bePatientUpdate": "Please be patient while we update the server. Download times can vary depending upon your internet speeds.<br /> This screen will refresh in a moment",
|
||||
"bePatientUpdate": "Будь ласка, наберіться терпіння поки ми оновлюємо сервер. Час завантаження може змінюватись відповідно до швидкості вашого інтернету.<br /> Цей екран оновиться, за хвилинку",
|
||||
"cancel": "Відміна",
|
||||
"countPlayers": "Враховувати сервер до загальної кількості гравців",
|
||||
"crashTime": "Краш таймаут",
|
||||
@ -386,7 +387,7 @@
|
||||
"serverLogLocation": "Логи сервера",
|
||||
"serverLogLocationDesc": "Шлях до логів сервера",
|
||||
"serverName": "Назва сервера",
|
||||
"serverNameDesc": "Як назвати даний сервер?",
|
||||
"serverNameDesc": "Як назвати даний сервер",
|
||||
"serverPath": "Робоча папка сервера",
|
||||
"serverPathDesc": "Повний шлях до папки сервера (не посилання на виконуваний файл)",
|
||||
"serverPort": "Порт сервера",
|
||||
@ -399,13 +400,13 @@
|
||||
"statsHint2": "Це не змінює порт вашого сервера. Ви мусите власноруч змінити налаштування в server.properties або іншому конфігураційному файлі.",
|
||||
"stopBeforeDeleting": "Будь ласка зупиніть сервер перед тим як видаляти його",
|
||||
"timeoutExplain1": "Скільки Crafty має чекати вимкнення вашого сервера після запуску",
|
||||
"timeoutExplain2": "команди перед тим як примусово його вимкнути?",
|
||||
"timeoutExplain2": "команди перед тим як примусово його вимкнути.",
|
||||
"update": "Оновити виконуваний файл",
|
||||
"yesDelete": "Так, видалити",
|
||||
"yesDeleteFiles": "Так, видалити файли"
|
||||
},
|
||||
"serverConfigHelp": {
|
||||
"desc": "Тут можна змінити конфігурацію вашого сервера.",
|
||||
"desc": "Тут можна змінити конфігурацію вашого сервера",
|
||||
"perms": [
|
||||
"Рекомендовано <code>НЕ</code> змінювати шлях до сервера який створив Crafty.",
|
||||
"Зміна шляхів <code>МОЖЕ</code> зламати щось, особливо в операційних системах типу Linux, де дозволи на файли більш заблоковані.",
|
||||
@ -475,7 +476,7 @@
|
||||
"serverPlayerManagement": {
|
||||
"bannedPlayers": "Заблоковані користувачі",
|
||||
"loadingBannedPlayers": "Завантаження заблокованих користувачів",
|
||||
"players": "Користувачі"
|
||||
"players": "Гравці"
|
||||
},
|
||||
"serverScheduleConfig": {
|
||||
"backup": "Бекап серверу",
|
||||
@ -578,7 +579,7 @@
|
||||
"explainRoot": "Натисніть кнопку нижче, щоб вибрати кореневий каталог вашого сервера всередині архіву",
|
||||
"importServer": "Імпортувати готовий сервер",
|
||||
"importServerButton": "Імпортувати сервер!",
|
||||
"importZip": "Імпортувати з Архіву(Zip) ",
|
||||
"importZip": "Імпортувати з Архіву(Zip)",
|
||||
"importing": "Імпортування сервера...",
|
||||
"labelZipFile": "Виберіть архів (Zip)",
|
||||
"maxMem": "Максимум пам'яті",
|
||||
@ -623,7 +624,7 @@
|
||||
"startup": {
|
||||
"almost": "Закінчуємо. Тримайся міцніше...",
|
||||
"cache": "Оновлення файлу кешу Big Bucket",
|
||||
"internals": "Налаштування та запуск внутрішніх компонентів Crafty ",
|
||||
"internals": "Налаштування та запуск внутрішніх компонентів Crafty",
|
||||
"internet": "Перевірка доступу до інтернету",
|
||||
"server": "Ініціалізація ",
|
||||
"serverInit": "Ініціалізація серверів",
|
||||
@ -637,10 +638,10 @@
|
||||
"configArea": "Область конфігурації користувача",
|
||||
"configAreaDesc": "Тут ви можете змінити всі налаштування користувача",
|
||||
"confirmDelete": "Ви впевненні що бажаєте видалити даного користувача? Це незворотня дія.",
|
||||
"craftyPermDesc": "Дозволи Crafty для цього користувача",
|
||||
"craftyPermDesc": "Дозволи Crafty для цього користувача ",
|
||||
"craftyPerms": "Доступ Crafty: ",
|
||||
"created": "Створений: ",
|
||||
"delSuper": "Ви не можете видалити суперюзера!",
|
||||
"delSuper": "Ви не можете видалити суперюзера",
|
||||
"deleteUser": "Видалити користувача: ",
|
||||
"deleteUserB": "Видалити користувача",
|
||||
"enabled": "Увімкнуто",
|
||||
@ -671,12 +672,14 @@
|
||||
"uses": "Дозволена кількість використань(-1==Без ліміту)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "Пароль, надто короткий. Мінімальна довжина: 8 символів"
|
||||
"passLength": "Пароль, надто короткий. Мінімальна довжина: 8 символів",
|
||||
"enumErr": "помилка валідації. Прийнятні дані включають: ",
|
||||
"insufficientPerms": "Помилка доступу: Відсутній доступ до цього ресурсу"
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "Ви впевнені, що хочете видалити цей Вебхук?",
|
||||
"areYouSureRun": "Ви впевнені, що хочете перевірити цей Вебхук?",
|
||||
"backup_server": "Бекап серверу завершено!",
|
||||
"backup_server": "Бекап серверу завершено",
|
||||
"bot_name": "Назва бота",
|
||||
"color": "Вибрати колір",
|
||||
"crash_detected": "Сервер впав",
|
||||
|
@ -12,10 +12,10 @@
|
||||
},
|
||||
"apiKeys": {
|
||||
"apiKeys": "API 密钥",
|
||||
"auth": "已授权?",
|
||||
"auth": "已授权? ",
|
||||
"buttons": "按钮",
|
||||
"config": "配置",
|
||||
"crafty": "Crafty:",
|
||||
"crafty": "Crafty: ",
|
||||
"createNew": "创建新的 API 令牌",
|
||||
"created": "创建时间",
|
||||
"deleteKeyConfirmation": "您想要删除这个 API 密钥吗?此操作不能撤销。",
|
||||
@ -23,13 +23,12 @@
|
||||
"fullAccess": "完全访问",
|
||||
"getToken": "获得一个令牌",
|
||||
"name": "名称",
|
||||
"nameDesc": "你想把这个 API 令牌叫做什么?",
|
||||
"nameDesc": "你想把这个 API 令牌叫做什么? ",
|
||||
"no": "否",
|
||||
"pageTitle": "编辑用户 API 密钥",
|
||||
"permName": "权限名称",
|
||||
"perms": "权限",
|
||||
"server": "服务器:",
|
||||
"superUser": "超级用户",
|
||||
"server": "服务器: ",
|
||||
"yes": "是"
|
||||
},
|
||||
"base": {
|
||||
@ -49,7 +48,7 @@
|
||||
"subscriptionLevel": "等级",
|
||||
"supportTeam": "支持与文档团队",
|
||||
"thankYou": "感谢",
|
||||
"translationDesc": "帮助我们翻译的社区!",
|
||||
"translationDesc": "帮助我们翻译的社区![ 活跃 = 🟢 不活跃/已离职 = ⚪ ]",
|
||||
"translationName": "名称",
|
||||
"translationTitle": "语言翻译",
|
||||
"translator": "译者"
|
||||
@ -143,12 +142,12 @@
|
||||
"pdf": "PDF",
|
||||
"print": "打印"
|
||||
},
|
||||
"decimal": "",
|
||||
"decimal": ".",
|
||||
"emptyTable": "数据表中没有可用的数据",
|
||||
"info": "正在显示从 _START_ 到 _END_ 的共 _TOTAL_ 个项目",
|
||||
"infoEmpty": "正在显示从 0 到 0 的共 0 个项目",
|
||||
"infoFiltered": "(从 _MAX_ 个项目中筛选出)",
|
||||
"infoPostFix": "",
|
||||
"infoPostFix": "|",
|
||||
"lengthMenu": "显示 _MENU_ 个项目",
|
||||
"loadingRecords": "正在加载……",
|
||||
"paginate": {
|
||||
@ -193,7 +192,7 @@
|
||||
"embarassing": "哦,天哪,这太尴尬了。",
|
||||
"error": "错误!",
|
||||
"eulaAgree": "你同意吗?",
|
||||
"eulaMsg": "你必须同意最终用户许可协议(EULA)。一份 Minecraft EULA 副本的链接在此消息下方。",
|
||||
"eulaMsg": "你必须同意 ",
|
||||
"eulaTitle": "同意最终用户许可协议(EULA)",
|
||||
"fileError": "文件类型必须是图片。",
|
||||
"fileTooLarge": "上传失败。上传的文件过大。联系系统管理员以获取协助。",
|
||||
@ -206,11 +205,9 @@
|
||||
"noJava": "服务器 {} 启动失败,并输出了如下错误码:我们检测到 Java 未安装。请先安装 java 然后再启动服务器。",
|
||||
"not-downloaded": "我们似乎找不到您的可执行文件。它下载完成了吗?可执行文件的权限设置正确了吗?",
|
||||
"portReminder": "我们检测到这是你首次运行 {}。请确保从您的路由器/防火墙转发 {} 端口,以使程序可以从公网远程访问。",
|
||||
"privMsg": "以及",
|
||||
"privMsg": "以及 ",
|
||||
"return": "返回仪表板",
|
||||
"selfHost": "如果您自托管此仓库,请检查您的地址或参考我们的故障排除指南。",
|
||||
"serverJars1": "无法访问服务器 JAR API。请检查",
|
||||
"serverJars2": "以获取最新信息。",
|
||||
"start-error": "服务器 {} 启动失败,错误代码为:{}",
|
||||
"superError": "您必须作为超级用户来完成此操作。",
|
||||
"terribleFailure": "多糟糕的错误!"
|
||||
@ -234,11 +231,15 @@
|
||||
"activityLog": "活动日志",
|
||||
"backupComplete": "服务器 {} 的备份已完成",
|
||||
"backupStarted": "服务器 {} 的备份已开始",
|
||||
"downloadLogs": "下载支持日志:",
|
||||
"downloadLogs": "下载支持日志?",
|
||||
"finishedPreparing": "我们已准备好您的支持日志。请点击“下载”来下载",
|
||||
"logout": "退出登录",
|
||||
"preparingLogs": " 请等待,我们正在准备您的日志……准备好时我们会发送一次提醒。这对于大型的部署来说可能需要一点时间。",
|
||||
"supportLogs": "支持日志"
|
||||
"supportLogs": "支持日志",
|
||||
"backup_title": "备份迁移警告",
|
||||
"schedule_title": "计划迁移警告",
|
||||
"backup_desc": "我们检测到备份迁移可能已经部分或完全失败。请在备份选项卡中确认您的备份记录。",
|
||||
"schedule_desc": "我们检测到您的一些或全部计划任务在升级时未成功转移。请在计划选项卡中确认您的计划。"
|
||||
},
|
||||
"offline": {
|
||||
"offline": "离线",
|
||||
@ -278,8 +279,8 @@
|
||||
"rolesConfig": {
|
||||
"config": "角色配置",
|
||||
"configDesc": "您可以在这里更改您的角色设置",
|
||||
"configUpdate": "上次更新:",
|
||||
"created": "创建时间:",
|
||||
"configUpdate": "上次更新: ",
|
||||
"created": "创建时间: ",
|
||||
"delRole": "删除角色",
|
||||
"doesNotExist": "您不能删除还不存在的东西",
|
||||
"pageTitle": "编辑角色",
|
||||
@ -289,12 +290,12 @@
|
||||
"permsServer": "此角色拥有的对这些特定服务器的权限",
|
||||
"roleConfigArea": "角色配置区",
|
||||
"roleDesc": "您希望把这个角色叫做什么?",
|
||||
"roleName": "角色名称:",
|
||||
"roleName": "角色名称: ",
|
||||
"rolePerms": "角色权限",
|
||||
"roleServers": "允许的服务器",
|
||||
"roleTitle": "角色设置",
|
||||
"roleUserName": "用户名称",
|
||||
"roleUsers": "角色用户:",
|
||||
"roleUsers": "角色用户: ",
|
||||
"selectManager": "选择此角色的管理员",
|
||||
"serverAccess": "访问?",
|
||||
"serverName": "服务器名称",
|
||||
@ -322,7 +323,7 @@
|
||||
"download": "下载",
|
||||
"edit": "编辑",
|
||||
"enabled": "已启用",
|
||||
"excludedBackups": "排除的路径:",
|
||||
"excludedBackups": "排除的路径: ",
|
||||
"excludedChoose": "选择您希望从您的备份中排除的路径",
|
||||
"exclusionsTitle": "备份排除项",
|
||||
"failed": "失败",
|
||||
@ -355,7 +356,7 @@
|
||||
"crashTime": "崩溃超时",
|
||||
"crashTimeDesc": "我们应该在考虑您的服务器已崩溃之前等待多久?",
|
||||
"deleteFilesQuestion": "从设备上删除服务器文件?",
|
||||
"deleteFilesQuestionMessage": "您想要 Crafty 从主机上删除所有的服务器文件吗?",
|
||||
"deleteFilesQuestionMessage": "您想要 Crafty 从主机上删除所有的服务器文件吗?<br><br><strong>包含服务器备份。</strong>",
|
||||
"deleteServer": "删除服务器",
|
||||
"deleteServerQuestion": "删除服务器?",
|
||||
"deleteServerQuestionMessage": "您确定要删除此服务器吗?在此之后将无法撤销……",
|
||||
@ -463,7 +464,7 @@
|
||||
"unsupportedLanguage": "警告:这不是一个受支持的文件类型",
|
||||
"unzip": "解压",
|
||||
"upload": "上传",
|
||||
"uploadTitle": "上传文件到:",
|
||||
"uploadTitle": "上传文件到: ",
|
||||
"waitUpload": "请等待,我们正在上传您的文件……这需要一点时间。",
|
||||
"yesDelete": "是,我知道结果"
|
||||
},
|
||||
@ -480,11 +481,11 @@
|
||||
"serverScheduleConfig": {
|
||||
"backup": "备份服务器",
|
||||
"basic": "基本",
|
||||
"children": "已链接的子任务:",
|
||||
"children": "已链接的子任务: ",
|
||||
"command": "指令",
|
||||
"command-explain": "您想要让我们执行什么指令?不要包含“/”",
|
||||
"cron": "定时(Cron)",
|
||||
"cron-explain": "输入您的定时(Cron)字符串",
|
||||
"cron-explain": "输入您的定时(Cron)字符串 -- 注意:最后一项的 0 = 周一。",
|
||||
"custom": "自定义指令",
|
||||
"days": "天",
|
||||
"enabled": "启用",
|
||||
@ -512,7 +513,7 @@
|
||||
"cancel": "取消",
|
||||
"cannotSee": "什么都看不到?",
|
||||
"cannotSeeOnMobile": "尝试点击一个计划任务来查看全部详细信息。",
|
||||
"child": "父计划 ID",
|
||||
"child": "父计划 ID ",
|
||||
"close": "关闭",
|
||||
"command": "指令",
|
||||
"confirm": "确认",
|
||||
@ -554,7 +555,6 @@
|
||||
"serverTerm": {
|
||||
"commandInput": "输入您的指令",
|
||||
"delay-explained": "服务进程已经在刚才启动,并且正在延迟 Minecraft 服务器实例的启动",
|
||||
"downloading": "下载中……",
|
||||
"importing": "正在导入……",
|
||||
"installing": "正在安装……",
|
||||
"restart": "重启",
|
||||
@ -586,7 +586,7 @@
|
||||
"minMem": "最小内存",
|
||||
"myNewServer": "我的新服务器",
|
||||
"newServer": "创建新服务器",
|
||||
"noRole": "未找到角色。当前搜索参数:",
|
||||
"noRole": "根据当前搜索参数未找到角色",
|
||||
"noneRoles": "未选择角色",
|
||||
"quickSettings": "快捷设置",
|
||||
"quickSettingsDescription": "别担心,你可以稍后再更改这些设置",
|
||||
@ -633,23 +633,23 @@
|
||||
},
|
||||
"userConfig": {
|
||||
"apiKey": "API 密钥",
|
||||
"auth": "已授权?",
|
||||
"auth": "已授权? ",
|
||||
"config": "配置",
|
||||
"configArea": "用户配置区",
|
||||
"configAreaDesc": "您可以在这里更改您的所有用户设置",
|
||||
"confirmDelete": "您想要删除这个用户吗?此操作不可逆。",
|
||||
"craftyPermDesc": "此用户拥有的 Crafty 权限",
|
||||
"craftyPerms": "Crafty 权限:",
|
||||
"created": "创建时间:",
|
||||
"craftyPermDesc": "此用户拥有的 Crafty 权限 ",
|
||||
"craftyPerms": "Crafty 权限: ",
|
||||
"created": "创建时间: ",
|
||||
"delSuper": "您不能删除超级用户",
|
||||
"deleteUser": "删除用户:",
|
||||
"deleteUser": "删除用户: ",
|
||||
"deleteUserB": "删除用户",
|
||||
"enabled": "已启用",
|
||||
"gravDesc": "此电子邮件仅用于 Gravatar™。Crafty 不会在任何情况下使用该邮箱进行除了查阅您的 Gravatar™ 以外的操作",
|
||||
"gravEmail": "Gravatar™ 邮箱",
|
||||
"lastIP": "上次使用 IP:",
|
||||
"lastLogin": "上次登录:",
|
||||
"lastUpdate": "上次更新:",
|
||||
"lastIP": "上次使用 IP: ",
|
||||
"lastLogin": "上次登录: ",
|
||||
"lastUpdate": "上次更新: ",
|
||||
"leaveBlank": "如果要编辑此用户但不更改密码,请留空。",
|
||||
"manager": "管理员",
|
||||
"member": "成员?",
|
||||
@ -672,7 +672,26 @@
|
||||
"uses": "使用次数限制(-1==无限制)"
|
||||
},
|
||||
"validators": {
|
||||
"passLength": "密码过短。最短长度:8"
|
||||
"passLength": "密码过短。最短长度:8",
|
||||
"backupName": "备份名称必须为字符串,且最短长度为 3。",
|
||||
"filesPageLen": "属性的长度必须大于 1",
|
||||
"typeList": "必须为列表/数组类型 ",
|
||||
"userName": " 必须为字符串类型,全部小写,且最短为 4 个字符,最长为 20 个字符",
|
||||
"roleName": "角色名称必须为多于 1 个字符的字符串。必须不包含以下符号:[ ] , ",
|
||||
"serverCreateName": "服务器名称必须为长度至少为 2 的字符串,且必须不包含:\\ / 或 # ",
|
||||
"enumErr": "验证失败。接受的数据包括: ",
|
||||
"insufficientPerms": "权限错误:缺少此资源的权限",
|
||||
"roleManager": "角色管理员必须为整数类型(管理员 ID)或无",
|
||||
"roleServerId": "服务器 ID 属性必须为长度至少为 1 的字符串",
|
||||
"roleServerPerms": "服务器权限必须为 8 位的字符串",
|
||||
"serverExeCommand": "服务器运行命令必须为长度至少为 1 的字符串。",
|
||||
"serverLogPath": "服务器日志路径必须为长度至少为 1 的字符串",
|
||||
"taskIntervalType": "任务间隔类型必须为下列值之一: ",
|
||||
"typeBool": "必须为 true 或 false(布尔类型)",
|
||||
"typeEmail": "必须为邮箱类型。",
|
||||
"typeIntMinVal0": "必须为最小值为 0 的整数。",
|
||||
"typeInteger": "必须为数字。",
|
||||
"typeString": "必须为字符串类型。"
|
||||
},
|
||||
"webhooks": {
|
||||
"areYouSureDel": "您确定要删除此 webhook 吗?",
|
||||
|
22
main.py
22
main.py
@ -115,6 +115,23 @@ def controller_setup():
|
||||
controller.clear_support_status()
|
||||
|
||||
|
||||
def get_migration_notifications():
|
||||
migration_notifications = []
|
||||
for file in os.listdir(
|
||||
os.path.join(APPLICATION_PATH, "app", "migrations", "status")
|
||||
):
|
||||
if os.path.isfile(file):
|
||||
with open(
|
||||
os.path.join(APPLICATION_PATH, "app", "migrations", "status", file),
|
||||
encoding="utf-8",
|
||||
) as status_file:
|
||||
status_json = json.load(status_file)
|
||||
for item in status_json:
|
||||
if not status_json[item].get("status"):
|
||||
migration_notifications.append(item)
|
||||
return migration_notifications
|
||||
|
||||
|
||||
def tasks_starter():
|
||||
"""
|
||||
Method starts stats recording, app scheduler, and
|
||||
@ -350,6 +367,9 @@ if __name__ == "__main__":
|
||||
helper.db_path, pragmas={"journal_mode": "wal", "cache_size": -1024 * 10}
|
||||
)
|
||||
database_proxy.initialize(database)
|
||||
Helpers.ensure_dir_exists(
|
||||
os.path.join(APPLICATION_PATH, "app", "migrations", "status")
|
||||
)
|
||||
migration_manager = MigrationManager(database, helper)
|
||||
migration_manager.up() # Automatically runs migrations
|
||||
|
||||
@ -408,7 +428,7 @@ if __name__ == "__main__":
|
||||
controller.set_project_root(APPLICATION_PATH)
|
||||
tasks_manager = TasksManager(helper, controller, file_helper)
|
||||
import3 = Import3(helper, controller)
|
||||
|
||||
helper.migration_notifications = get_migration_notifications()
|
||||
# Check to see if client config.json version is different than the
|
||||
# Master config.json in helpers.py
|
||||
Console.info("Checking for remote changes to config.json")
|
||||
|
@ -4,18 +4,18 @@ argon2-cffi==23.1.0
|
||||
cached_property==1.5.2
|
||||
colorama==0.4.6
|
||||
croniter==1.4.1
|
||||
cryptography==42.0.4
|
||||
cryptography==43.0.1
|
||||
libgravatar==1.0.4
|
||||
nh3==0.2.14
|
||||
packaging==23.2
|
||||
peewee==3.13
|
||||
psutil==5.9.5
|
||||
pyOpenSSL==24.0.0
|
||||
pyOpenSSL==24.2.1
|
||||
pyjwt==2.8.0
|
||||
PyYAML==6.0.1
|
||||
requests==2.32.0
|
||||
requests==2.32.3
|
||||
termcolor==1.1
|
||||
tornado==6.4.1
|
||||
tornado==6.4.2
|
||||
tzlocal==5.1
|
||||
jsonschema==4.19.1
|
||||
orjson==3.9.15
|
||||
|
@ -3,7 +3,7 @@ sonar.organization=crafty-controller
|
||||
|
||||
# This is the name and version displayed in the SonarCloud UI.
|
||||
sonar.projectName=Crafty 4
|
||||
sonar.projectVersion=4.4.4
|
||||
sonar.projectVersion=4.4.5
|
||||
sonar.python.version=3.9, 3.10, 3.11
|
||||
sonar.exclusions=app/migrations/**, app/frontend/static/assets/vendors/**
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user