hello API 8 !

This commit is contained in:
Ayush Saini 2023-08-13 17:21:49 +05:30
parent 3a2b6ade68
commit 0284fee95c
1166 changed files with 26061 additions and 375100 deletions

View file

@ -1,8 +1,7 @@
#!/usr/bin/env -S python3.10 -O
#!/usr/bin/env -S python3.11 -O
# Released under the MIT License. See LICENSE for details.
#
"""BallisticaCore server manager."""
"""BallisticaKit server manager."""
from __future__ import annotations
import json
@ -11,47 +10,16 @@ import signal
import subprocess
import sys
import time
import _thread
from pathlib import Path
from threading import Lock, Thread, current_thread
from typing import TYPE_CHECKING
from nbstreamreader import NonBlockingStreamReader as NBSR
ERROR_LOGGING=False
import os,platform,shutil
def migrate_to_aarch():
maps = ["BridgitMash.so","FloatingIsland.so","InTheAir.so"]
games = ["CanonFight.so","DuelElimination.so","FlappyBird.so","LaserTracer.so","MonkeyClimb.so","OneNightNoStand.so","RealSoccer.so",
"SquidRace.so","StumbleRace.so","SubwayRun.so","UFOAttackGame.so"]
features = ["StumbledScoreScreen.so"]
tools = ["corelib.so"]
root = os.path.realpath(".")+"/dist/ba_root"
for map in maps:
shutil.copy(root+"/mods/aarch64/"+map,root+'/mods/maps/'+map)
for game in games:
shutil.copyfile(root+"/mods/aarch64/"+game,root+'/mods/games/'+game)
for f in features:
shutil.copyfile(root+"/mods/aarch64/"+f,root+'/mods/features/'+f)
for t in tools:
shutil.copyfile(root+"/mods/aarch64/"+t,root+'/mods/tools/'+t)
with open(".we_are_good","w") as f:
pass
# by default we have x86_64 setup
# if we found aarch64 system copy required files
if platform.processor() == 'aarch64':
print("We are on aarch64 system")
if os.path.exists(".we_are_good"):
pass
else:
migrate_to_aarch()
# We make use of the bacommon and efro packages as well as site-packages
# included with our bundled Ballistica dist, so we need to add those paths
# before we import them.
sys.path += [
str(Path(Path(__file__).parent, 'dist', 'ba_data', 'python')),
str(Path(Path(__file__).parent, 'dist', 'ba_data', 'python-site-packages'))
str(Path(Path(__file__).parent, 'dist', 'ba_data', 'python-site-packages')),
]
from bacommon.servermanager import ServerConfig, StartServerModeCommand
@ -60,16 +28,14 @@ from efro.error import CleanError
from efro.terminal import Clr
if TYPE_CHECKING:
from typing import Optional, Union
from types import FrameType
from bacommon.servermanager import ServerCommand
VERSION_STR = '1.3'
VERSION_STR = '1.3.1'
# Version history:
# 1.3.1
# Windows binary is now named BallisticaCoreHeadless.exe
# Windows binary is now named BallisticaKitHeadless.exe
# 1.3:
# Added show_tutorial config option
# Added team_names config option
@ -96,10 +62,10 @@ VERSION_STR = '1.3'
class ServerManagerApp:
"""An app which manages BallisticaCore server execution.
"""An app which manages BallisticaKit server execution.
Handles configuring, launching, re-launching, and otherwise
managing BallisticaCore operating in server mode.
managing BallisticaKit operating in server mode.
"""
# How many seconds we wait after asking our subprocess to do an immediate
@ -114,24 +80,24 @@ class ServerManagerApp:
self._interactive = sys.stdin.isatty()
self._wrapper_shutdown_desired = False
self._done = False
self._subprocess_commands: list[Union[str, ServerCommand]] = []
self._subprocess_commands: list[str | ServerCommand] = []
self._subprocess_commands_lock = Lock()
self._subprocess_force_kill_time: Optional[float] = None
self._subprocess_force_kill_time: float | None = None
self._auto_restart = True
self._config_auto_restart = True
self._config_mtime: Optional[float] = None
self._last_config_mtime_check_time: Optional[float] = None
self._config_mtime: float | None = None
self._last_config_mtime_check_time: float | None = None
self._should_report_subprocess_error = False
self._running = False
self._interpreter_start_time: Optional[float] = None
self._subprocess: Optional[subprocess.Popen[bytes]] = None
self._subprocess_launch_time: Optional[float] = None
self._interpreter_start_time: float | None = None
self._subprocess: subprocess.Popen[bytes] | None = None
self._subprocess_launch_time: float | None = None
self._subprocess_sent_config_auto_restart = False
self._subprocess_sent_clean_exit = False
self._subprocess_sent_unclean_exit = False
self._subprocess_thread: Optional[Thread] = None
self._subprocess_exited_cleanly: Optional[bool] = None
self.nbsr = None
self._subprocess_thread: Thread | None = None
self._subprocess_exited_cleanly: bool | None = None
# This may override the above defaults.
self._parse_command_line_args()
@ -159,9 +125,10 @@ class ServerManagerApp:
dbgstr = 'debug' if __debug__ else 'opt'
print(
f'{Clr.CYN}{Clr.BLD}Bcs server manager {VERSION_STR}'
f'{Clr.CYN}{Clr.BLD}BallisticaKit server manager {VERSION_STR}'
f' starting up ({dbgstr} mode)...{Clr.RST}',
flush=True)
flush=True,
)
# Python will handle SIGINT for us (as KeyboardInterrupt) but we
# need to register a SIGTERM handler so we have a chance to clean
@ -184,8 +151,9 @@ class ServerManagerApp:
assert self._subprocess_thread is not None
if self._subprocess_thread.is_alive():
print(f'{Clr.CYN}Waiting for subprocess exit...{Clr.RST}',
flush=True)
print(
f'{Clr.CYN}Waiting for subprocess exit...{Clr.RST}', flush=True
)
# Mark ourselves as shutting down and wait for the process to wrap up.
self._done = True
@ -222,6 +190,7 @@ class ServerManagerApp:
def _run_interactive(self) -> None:
"""Run the app loop to completion interactively."""
import code
self._prerun()
# Print basic usage info for interactive mode.
@ -229,7 +198,8 @@ class ServerManagerApp:
f"{Clr.CYN}Interactive mode enabled; use the 'mgr' object"
f' to interact with the server.\n'
f"Type 'help(mgr)' for more information.{Clr.RST}",
flush=True)
flush=True,
)
context = {'__name__': '__console__', '__doc__': None, 'mgr': self}
@ -250,7 +220,8 @@ class ServerManagerApp:
print(
f'{Clr.SRED}Unexpected interpreter exception:'
f' {exc} ({type(exc)}){Clr.RST}',
flush=True)
flush=True,
)
self._postrun()
@ -282,39 +253,45 @@ class ServerManagerApp:
# we'll hopefully still give it enough time to process/print.
time.sleep(0.1)
def screenmessage(self,
message: str,
color: Optional[tuple[float, float, float]] = None,
clients: Optional[list[int]] = None) -> None:
def screenmessage(
self,
message: str,
color: tuple[float, float, float] | None = None,
clients: list[int] | None = None,
) -> None:
"""Display a screen-message.
This will have no name attached and not show up in chat history.
They will show up in replays, however (unless clients is passed).
"""
from bacommon.servermanager import ScreenMessageCommand
self._enqueue_server_command(
ScreenMessageCommand(message=message, color=color,
clients=clients))
def chatmessage(self,
message: str,
clients: Optional[list[int]] = None) -> None:
self._enqueue_server_command(
ScreenMessageCommand(message=message, color=color, clients=clients)
)
def chatmessage(
self, message: str, clients: list[int] | None = None
) -> None:
"""Send a chat message from the server.
This will have the server's name attached and will be logged
in client chat windows, just like other chat messages.
"""
from bacommon.servermanager import ChatMessageCommand
self._enqueue_server_command(
ChatMessageCommand(message=message, clients=clients))
ChatMessageCommand(message=message, clients=clients)
)
def clientlist(self) -> None:
"""Print a list of connected clients."""
from bacommon.servermanager import ClientListCommand
self._enqueue_server_command(ClientListCommand())
self._block_for_command_completion()
def kick(self, client_id: int, ban_time: Optional[int] = None) -> None:
def kick(self, client_id: int, ban_time: int | None = None) -> None:
"""Kick the client with the provided id.
If ban_time is provided, the client will be banned for that
@ -323,8 +300,10 @@ class ServerManagerApp:
ban time.
"""
from bacommon.servermanager import KickCommand
self._enqueue_server_command(
KickCommand(client_id=client_id, ban_time=ban_time))
KickCommand(client_id=client_id, ban_time=ban_time)
)
def restart(self, immediate: bool = True) -> None:
"""Restart the server subprocess.
@ -334,15 +313,19 @@ class ServerManagerApp:
the next clean transition point (the end of a series, etc).
"""
from bacommon.servermanager import ShutdownCommand, ShutdownReason
self._enqueue_server_command(
ShutdownCommand(reason=ShutdownReason.RESTARTING,
immediate=immediate))
ShutdownCommand(
reason=ShutdownReason.RESTARTING, immediate=immediate
)
)
# If we're asking for an immediate restart but don't get one within
# the grace period, bring down the hammer.
if immediate:
self._subprocess_force_kill_time = (
time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT)
time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT
)
def shutdown(self, immediate: bool = True) -> None:
"""Shut down the server subprocess and exit the wrapper.
@ -352,8 +335,10 @@ class ServerManagerApp:
the next clean transition point (the end of a series, etc).
"""
from bacommon.servermanager import ShutdownCommand, ShutdownReason
self._enqueue_server_command(
ShutdownCommand(reason=ShutdownReason.NONE, immediate=immediate))
ShutdownCommand(reason=ShutdownReason.NONE, immediate=immediate)
)
# An explicit shutdown means we know to bail completely once this
# subprocess completes.
@ -363,7 +348,8 @@ class ServerManagerApp:
# the grace period, bring down the hammer.
if immediate:
self._subprocess_force_kill_time = (
time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT)
time.time() + self.IMMEDIATE_SHUTDOWN_TIME_LIMIT
)
def _parse_command_line_args(self) -> None:
"""Parse command line args."""
@ -382,8 +368,7 @@ class ServerManagerApp:
raise CleanError('Expected a config path as next arg.')
path = sys.argv[i + 1]
if not os.path.exists(path):
raise CleanError(
f"Supplied path does not exist: '{path}'.")
raise CleanError(f"Supplied path does not exist: '{path}'.")
# We need an abs path because we may be in a different
# cwd currently than we will be during the run.
self._config_path = os.path.abspath(path)
@ -400,15 +385,19 @@ class ServerManagerApp:
i += 2
elif arg == '--interactive':
if did_set_interactive:
raise CleanError('interactive/noninteractive can only'
' be specified once.')
raise CleanError(
'interactive/noninteractive can only'
' be specified once.'
)
self._interactive = True
did_set_interactive = True
i += 1
elif arg == '--noninteractive':
if did_set_interactive:
raise CleanError('interactive/noninteractive can only'
' be specified once.')
raise CleanError(
'interactive/noninteractive can only'
' be specified once.'
)
self._interactive = False
did_set_interactive = True
i += 1
@ -425,6 +414,7 @@ class ServerManagerApp:
def _par(cls, txt: str) -> str:
"""Spit out a pretty paragraph for our help text."""
import textwrap
ind = ' ' * 2
out = textwrap.fill(txt, 80, initial_indent=ind, subsequent_indent=ind)
return f'{out}\n'
@ -434,50 +424,67 @@ class ServerManagerApp:
"""Print app help."""
filename = os.path.basename(__file__)
out = (
f'{Clr.BLD}{filename} usage:{Clr.RST}\n' + cls._par(
'This script handles configuring, launching, re-launching,'
' and otherwise managing BallisticaCore operating'
' in server mode. It can be run with no arguments, but'
' accepts the following optional ones:') + f'\n'
f'{Clr.BLD}--help:{Clr.RST}\n'
f' Show this help.\n'
f'\n'
f'{Clr.BLD}--config [path]{Clr.RST}\n' + cls._par(
'Set the config file read by the server script. The config'
' file contains most options for what kind of game to host.'
' It should be in yaml format. Note that yaml is backwards'
' compatible with json so you can just write json if you'
' want to. If not specified, the script will look for a'
' file named \'config.yaml\' in the same directory as the'
' script.') + '\n'
f'{Clr.BLD}--root [path]{Clr.RST}\n' + cls._par(
'Set the ballistica root directory. This is where the server'
' binary will read and write its caches, state files,'
' downloaded assets to, etc. It needs to be a writable'
' directory. If not specified, the script will use the'
' \'dist/ba_root\' directory relative to itself.') + '\n'
f'{Clr.BLD}--interactive{Clr.RST}\n'
f'{Clr.BLD}--noninteractive{Clr.RST}\n' + cls._par(
'Specify whether the script should run interactively.'
' In interactive mode, the script creates a Python interpreter'
' and reads commands from stdin, allowing for live interaction'
' with the server. The server script will then exit when '
'end-of-file is reached in stdin. Noninteractive mode creates'
' no interpreter and is more suited to being run in automated'
' scenarios. By default, interactive mode will be used if'
' a terminal is detected and noninteractive mode otherwise.') +
'\n'
f'{Clr.BLD}--no-auto-restart{Clr.RST}\n' +
cls._par('Auto-restart is enabled by default, which means the'
' server manager will restart the server binary whenever'
' it exits (even when uncleanly). Disabling auto-restart'
' will cause the server manager to instead exit after a'
' single run and also to return error codes if the'
' server binary did so.') + '\n'
f'{Clr.BLD}--no-config-auto-restart{Clr.RST}\n' + cls._par(
'By default, when auto-restart is enabled, the server binary'
' will be automatically restarted if changes to the server'
' config file are detected. This disables that behavior.'))
f'{Clr.BLD}{filename} usage:{Clr.RST}\n'
+ cls._par(
'This script handles configuring, launching, re-launching,'
' and otherwise managing BallisticaKit operating'
' in server mode. It can be run with no arguments, but'
' accepts the following optional ones:'
)
+ f'\n'
f'{Clr.BLD}--help:{Clr.RST}\n'
f' Show this help.\n'
f'\n'
f'{Clr.BLD}--config [path]{Clr.RST}\n'
+ cls._par(
'Set the config file read by the server script. The config'
' file contains most options for what kind of game to host.'
' It should be in yaml format. Note that yaml is backwards'
' compatible with json so you can just write json if you'
' want to. If not specified, the script will look for a'
' file named \'config.yaml\' in the same directory as the'
' script.'
)
+ '\n'
f'{Clr.BLD}--root [path]{Clr.RST}\n'
+ cls._par(
'Set the ballistica root directory. This is where the server'
' binary will read and write its caches, state files,'
' downloaded assets to, etc. It needs to be a writable'
' directory. If not specified, the script will use the'
' \'dist/ba_root\' directory relative to itself.'
)
+ '\n'
f'{Clr.BLD}--interactive{Clr.RST}\n'
f'{Clr.BLD}--noninteractive{Clr.RST}\n'
+ cls._par(
'Specify whether the script should run interactively.'
' In interactive mode, the script creates a Python interpreter'
' and reads commands from stdin, allowing for live interaction'
' with the server. The server script will then exit when '
'end-of-file is reached in stdin. Noninteractive mode creates'
' no interpreter and is more suited to being run in automated'
' scenarios. By default, interactive mode will be used if'
' a terminal is detected and noninteractive mode otherwise.'
)
+ '\n'
f'{Clr.BLD}--no-auto-restart{Clr.RST}\n'
+ cls._par(
'Auto-restart is enabled by default, which means the'
' server manager will restart the server binary whenever'
' it exits (even when uncleanly). Disabling auto-restart'
' will cause the server manager to instead exit after a'
' single run and also to return error codes if the'
' server binary did so.'
)
+ '\n'
f'{Clr.BLD}--no-config-auto-restart{Clr.RST}\n'
+ cls._par(
'By default, when auto-restart is enabled, the server binary'
' will be automatically restarted if changes to the server'
' config file are detected. This disables that behavior.'
)
)
print(out)
def load_config(self, strict: bool, print_confirmation: bool) -> None:
@ -493,26 +500,32 @@ class ServerManagerApp:
for trynum in range(maxtries):
try:
self._config = self._load_config_from_file(
print_confirmation=print_confirmation)
print_confirmation=print_confirmation
)
return
except Exception as exc:
if strict:
raise CleanError(
f'Error loading config file:\n{exc}') from exc
print(f'{Clr.RED}Error loading config file:\n{exc}.{Clr.RST}',
flush=True)
f'Error loading config file:\n{exc}'
) from exc
print(
f'{Clr.RED}Error loading config file:\n{exc}.{Clr.RST}',
flush=True,
)
if trynum == maxtries - 1:
print(
f'{Clr.RED}Max-tries reached; giving up.'
f' Existing config values will be used.{Clr.RST}',
flush=True)
flush=True,
)
break
print(
f'{Clr.CYN}Please correct the error.'
f' Will re-attempt load in {retry_seconds}'
f' seconds. (attempt {trynum + 1} of'
f' {maxtries - 1}).{Clr.RST}',
flush=True)
f' seconds. (attempt {trynum+1} of'
f' {maxtries-1}).{Clr.RST}',
flush=True,
)
for _j in range(retry_seconds):
# If the app is trying to die, drop what we're doing.
@ -521,11 +534,9 @@ class ServerManagerApp:
time.sleep(1)
def _load_config_from_file(self, print_confirmation: bool) -> ServerConfig:
out: Optional[ServerConfig] = None
out: ServerConfig | None = None
if not os.path.exists(self._config_path):
# Special case:
# If the user didn't specify a particular config file, allow
# gracefully falling back to defaults if the default one is
@ -536,16 +547,17 @@ class ServerManagerApp:
f'{Clr.YLW}Default config file not found'
f' (\'{self._config_path}\'); using default'
f' settings.{Clr.RST}',
flush=True)
flush=True,
)
self._config_mtime = None
self._last_config_mtime_check_time = time.time()
return ServerConfig()
# Don't be so lenient if the user pointed us at one though.
raise RuntimeError(
f"Config file not found: '{self._config_path}'.")
raise RuntimeError(f"Config file not found: '{self._config_path}'.")
import yaml
with open(self._config_path, encoding='utf-8') as infile:
user_config_raw = yaml.safe_load(infile.read())
@ -562,8 +574,10 @@ class ServerManagerApp:
out = ServerConfig()
if print_confirmation:
print(f'{Clr.CYN}Valid server config file loaded.{Clr.RST}',
flush=True)
print(
f'{Clr.CYN}Valid server config file loaded.{Clr.RST}',
flush=True,
)
return out
def _enable_tab_completion(self, locs: dict) -> None:
@ -571,6 +585,7 @@ class ServerManagerApp:
try:
import readline
import rlcompleter
readline.set_completer(rlcompleter.Completer(locs).complete)
readline.parse_and_bind('tab:complete')
except ImportError:
@ -582,7 +597,7 @@ class ServerManagerApp:
while not self._done:
self._run_server_cycle()
def _handle_term_signal(self, sig: int, frame: FrameType) -> None:
def _handle_term_signal(self, sig: int, frame: FrameType | None) -> None:
"""Handle signals (will always run in the main thread)."""
del sig, frame # Unused.
sys.exit(1 if self._should_report_subprocess_error else 0)
@ -606,46 +621,43 @@ class ServerManagerApp:
# run under us. This causes it to ignore ctrl-c presses and other
# slight behavior tweaks. Hmm; should this be an argument instead?
os.environ['BA_SERVER_WRAPPER_MANAGED'] = '1'
# Set an environment var to change the device name.
# Device name is used while making connection with master server,
# cloud-console recognize us with this name.
os.environ['BA_DEVICE_NAME'] = self._config.party_name
print(f'{Clr.CYN}Launching server subprocess...{Clr.RST}', flush=True)
binary_name = ('BallisticaCoreHeadless.exe'
if os.name == 'nt' else './bombsquad_headless')
if platform.processor() == 'aarch64':
binary_name = './bombsquad_headless_aarch64'
binary_name = (
'BallisticaKitHeadless.exe'
if os.name == 'nt'
else './ballisticakit_headless'
)
assert self._ba_root_path is not None
self._subprocess = None
# Launch!
try:
if ERROR_LOGGING:
self._subprocess = subprocess.Popen(
[binary_name, '-cfgdir', self._ba_root_path],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd='dist')
self.nbsr = NBSR(self._subprocess.stdout)
self.nbsrerr = NBSR(self._subprocess.stderr)
else:
self._subprocess = subprocess.Popen(
[binary_name, '-cfgdir', self._ba_root_path],
stdin=subprocess.PIPE,
cwd='dist')
self._subprocess = subprocess.Popen(
[binary_name, '--config-dir', self._ba_root_path],
stdin=subprocess.PIPE,
cwd='dist',
)
except Exception as exc:
self._subprocess_exited_cleanly = False
print(
f'{Clr.RED}Error launching server subprocess: {exc}{Clr.RST}',
flush=True)
flush=True,
)
# Do the thing.
try:
self._run_subprocess_until_exit()
except Exception as exc:
print(f'{Clr.RED}Error running server subprocess: {exc}{Clr.RST}',
flush=True)
print(
f'{Clr.RED}Error running server subprocess: {exc}{Clr.RST}',
flush=True,
)
self._kill_subprocess()
@ -655,13 +667,18 @@ class ServerManagerApp:
# up the interpreter, its possible that it will not break out of its
# loop via the usual SystemExit that gets sent when we die.
if self._interactive:
while (self._interpreter_start_time is None
or time.time() - self._interpreter_start_time < 0.5):
while (
self._interpreter_start_time is None
or time.time() - self._interpreter_start_time < 0.5
):
time.sleep(0.1)
# Avoid super fast death loops.
if (not self._subprocess_exited_cleanly and self._auto_restart
and not self._done):
if (
not self._subprocess_exited_cleanly
and self._auto_restart
and not self._done
):
time.sleep(5.0)
# If they don't want auto-restart, we'll exit the whole wrapper.
@ -676,7 +693,6 @@ class ServerManagerApp:
# If we want to die completely after this subprocess has ended,
# tell the main thread to die.
if self._wrapper_shutdown_desired:
# Only do this if the main thread is not already waiting for
# us to die; otherwise it can lead to deadlock.
# (we hang in os.kill while main thread is blocked in Thread.join)
@ -700,7 +716,7 @@ class ServerManagerApp:
bincfg = {}
# Some of our config values translate directly into the
# ballisticacore config file; the rest we pass at runtime.
# ballisticakit config file; the rest we pass at runtime.
bincfg['Port'] = self._config.port
bincfg['Auto Balance Teams'] = self._config.auto_balance_teams
bincfg['Show Tutorial'] = self._config.show_tutorial
@ -733,13 +749,16 @@ class ServerManagerApp:
Must be called from the server process thread.
"""
import pickle
assert current_thread() is self._subprocess_thread
assert self._subprocess is not None
assert self._subprocess.stdin is not None
val = repr(pickle.dumps(command))
assert '\n' not in val
execcode = (f'import ba._servermode;'
f' ba._servermode._cmd({val})\n').encode()
execcode = (
f'import baclassic._servermode;'
f' baclassic._servermode._cmd({val})\n'
).encode()
self._subprocess.stdin.write(execcode)
self._subprocess.stdin.flush()
@ -756,21 +775,10 @@ class ServerManagerApp:
self._send_server_command(StartServerModeCommand(self._config))
while True:
# If the app is trying to shut down, nope out immediately.
if self._done:
break
# output=self._subprocess.stdout.readline()
# print(output)
if ERROR_LOGGING:
out = self.nbsr.readline(0.1)
out2 = self.nbsrerr.readline(0.1)
if out:
sys.stdout.write(out.decode("utf-8"))
_thread.start_new_thread(dump_logs, (out.decode("utf-8"),))
if out2:
sys.stdout.write(out2.decode("utf-8"))
_thread.start_new_thread(dump_logs, (out2.decode("utf-8"),))
# Pass along any commands to our process.
with self._subprocess_commands_lock:
for incmd in self._subprocess_commands:
@ -789,25 +797,28 @@ class ServerManagerApp:
# If they want to force-kill our subprocess, simply exit this
# loop; the cleanup code will kill the process if its still
# alive.
if (self._subprocess_force_kill_time is not None
and time.time() > self._subprocess_force_kill_time):
if (
self._subprocess_force_kill_time is not None
and time.time() > self._subprocess_force_kill_time
):
print(
f'{Clr.CYN}Immediate shutdown time limit'
f' ({self.IMMEDIATE_SHUTDOWN_TIME_LIMIT:.1f} seconds)'
f' expired; force-killing subprocess...{Clr.RST}',
flush=True)
flush=True,
)
break
# Watch for the server process exiting..
code: Optional[int] = self._subprocess.poll()
code: int | None = self._subprocess.poll()
if code is not None:
clr = Clr.CYN if code == 0 else Clr.RED
print(
f'{clr}Server subprocess exited'
f' with code {code}.{Clr.RST}',
flush=True)
self._subprocess_exited_cleanly = (code == 0)
flush=True,
)
self._subprocess_exited_cleanly = code == 0
break
time.sleep(0.25)
@ -820,12 +831,17 @@ class ServerManagerApp:
minutes_since_launch = (now - self._subprocess_launch_time) / 60.0
# If we're doing auto-restart with config changes, handle that.
if (self._auto_restart and self._config_auto_restart
and not self._subprocess_sent_config_auto_restart):
if (self._last_config_mtime_check_time is None
or (now - self._last_config_mtime_check_time) > 3.123):
if (
self._auto_restart
and self._config_auto_restart
and not self._subprocess_sent_config_auto_restart
):
if (
self._last_config_mtime_check_time is None
or (now - self._last_config_mtime_check_time) > 3.123
):
self._last_config_mtime_check_time = now
mtime: Optional[float]
mtime: float | None
if os.path.isfile(self._config_path):
mtime = Path(self._config_path).stat().st_mtime
else:
@ -834,7 +850,8 @@ class ServerManagerApp:
print(
f'{Clr.CYN}Config-file change detected;'
f' requesting immediate restart.{Clr.RST}',
flush=True)
flush=True,
)
self.restart(immediate=True)
self._subprocess_sent_config_auto_restart = True
@ -842,18 +859,22 @@ class ServerManagerApp:
# (and enforce a 6 hour max if not provided)
clean_exit_minutes = 360.0
if self._config.clean_exit_minutes is not None:
clean_exit_minutes = min(clean_exit_minutes,
self._config.clean_exit_minutes)
clean_exit_minutes = min(
clean_exit_minutes, self._config.clean_exit_minutes
)
if clean_exit_minutes is not None:
if (minutes_since_launch > clean_exit_minutes
and not self._subprocess_sent_clean_exit):
if (
minutes_since_launch > clean_exit_minutes
and not self._subprocess_sent_clean_exit
):
opname = 'restart' if self._auto_restart else 'shutdown'
print(
f'{Clr.CYN}clean_exit_minutes'
f' ({clean_exit_minutes})'
f' elapsed; requesting soft'
f' {opname}.{Clr.RST}',
flush=True)
flush=True,
)
if self._auto_restart:
self.restart(immediate=False)
else:
@ -864,18 +885,22 @@ class ServerManagerApp:
# (and enforce a 7 hour max if not provided)
unclean_exit_minutes = 420.0
if self._config.unclean_exit_minutes is not None:
unclean_exit_minutes = min(unclean_exit_minutes,
self._config.unclean_exit_minutes)
unclean_exit_minutes = min(
unclean_exit_minutes, self._config.unclean_exit_minutes
)
if unclean_exit_minutes is not None:
if (minutes_since_launch > unclean_exit_minutes
and not self._subprocess_sent_unclean_exit):
if (
minutes_since_launch > unclean_exit_minutes
and not self._subprocess_sent_unclean_exit
):
opname = 'restart' if self._auto_restart else 'shutdown'
print(
f'{Clr.CYN}unclean_exit_minutes'
f' ({unclean_exit_minutes})'
f' elapsed; requesting immediate'
f' {opname}.{Clr.RST}',
flush=True)
flush=True,
)
if self._auto_restart:
self.restart(immediate=True)
else:
@ -904,8 +929,7 @@ class ServerManagerApp:
self._subprocess.terminate()
try:
self._subprocess.wait(timeout=10)
self._subprocess_exited_cleanly = (
self._subprocess.returncode == 0)
self._subprocess_exited_cleanly = self._subprocess.returncode == 0
except subprocess.TimeoutExpired:
self._subprocess_exited_cleanly = False
self._subprocess.kill()
@ -913,7 +937,7 @@ class ServerManagerApp:
def main() -> None:
"""Run the BallisticaCore server manager."""
"""Run the BallisticaKit server manager."""
try:
ServerManagerApp().run()
except CleanError as exc:
@ -923,16 +947,5 @@ def main() -> None:
sys.exit(1)
def dump_logs(msg):
if os.path.isfile('logs.log'):
size = os.path.getsize('logs.log')
if size > 2000000:
os.remove('logs.log')
with open("logs.log", "a") as f:
f.write(msg)
if __name__ == '__main__':
main()
main()

View file

@ -39,6 +39,7 @@
},
"translation_contributors": [
"!edMedic💊",
"!nobal",
"!ParkuristTurist!",
"\"9۝ÅЇρѺ۝ƬǀGΞЯ",
"/in/dev/",
@ -56,10 +57,12 @@
"_Fami",
"Omar a",
"Bruno A.",
"Abdullah A.S",
"aaalligator",
"aadesh",
"Aaron",
"Erik Abbevik",
"Abcd",
"Abdo",
"Abduh",
"Abdul",
@ -71,6 +74,7 @@
"Gifasa abidjahsi",
"Abinav",
"Abir",
"Abne",
"Abolfadl",
"Abolfazl",
"Abraham",
@ -87,6 +91,7 @@
"Adonay",
"AdOwn69",
"Adrián",
"Aeliux",
"Aely",
"Aenigmus",
"Aether",
@ -130,6 +135,7 @@
"Alexyze",
"Algene123456",
"ALI",
"Mohamed ali",
"Shadiq Ali",
"alireza",
"alirezaalidokht",
@ -151,6 +157,7 @@
"Amedeo",
"ameen",
"Kidane Amen-Allah",
"Amin",
"amin.ir",
"Amir",
"amir22games",
@ -159,6 +166,7 @@
"AmirMahdi.D :P",
"Amirul",
"Ange Kevin Amlaman",
"AMOGUSS85",
"amr",
"Anandchaursiya",
"Anas",
@ -200,6 +208,7 @@
"arda",
"Hellmann Arias",
"Muhammad Arief",
"Arihant",
"Arimaru",
"Arin",
"arjanex",
@ -278,18 +287,21 @@
"Bendy",
"Sérgio Benevides",
"Simon Bengtsson",
"Beniamino",
"Alfano Beniamino",
"Benjamin",
"Benjamín",
"benjapol",
"Ori bennov",
"BenVectorgames",
"Benyamin",
"benybrot96",
"berkay",
"Silvio Berlusconi",
"Bernardiny",
"Anton Bang Berner",
"Felix Bernhard",
"Beroudzin",
"Davide Bigotto",
"bilibili@Medic药",
"Bima",
@ -320,6 +332,7 @@
"Antoine Boulanger",
"Thomas Bouwmeester",
"Ali x boy",
"boyhero7779",
"Bořivoj",
"Paul braga",
"Sammy Braun",
@ -336,6 +349,7 @@
"Bsamhero",
"BSODPK",
"Marvin Bublitz",
"BudaCcm",
"Vincent R. Buenaventura",
"Buskebam",
"Buto11",
@ -356,6 +370,7 @@
"Fabio Cannavacciuolo",
"CANOVER",
"Fedrigo Canpanjoło",
"Carl",
"Yan Carlos",
"CarlosE.",
"mark Dave a carposo",
@ -408,13 +423,16 @@
"cuddles98",
"cukomus",
"CYCL0YT",
"Filipec CZ",
"D",
"D-Mega",
"Dada",
"Daichi",
"Daivaras",
"Dajo6596YT",
"Dakkat",
"Mikkel Damgaard",
"DanAlfred",
"Danco",
"Dani",
"Daniel",
@ -430,7 +448,7 @@
"David",
"Davide",
"DavidPlayzLol",
"DavidPlayzloll",
"Davidplayzloll",
"DaymanLP",
"Ddávid",
"Die or Dead",
@ -443,6 +461,7 @@
"Dennis",
"Dennys",
"Alex Derbenew",
"Dr : developer",
"df",
"Santanu Dhar",
"Guilherme Dias",
@ -488,6 +507,7 @@
"Glen Edwards",
"Amr Wassiem Eessa",
"ef",
"EgorZH",
"Ali ehs",
"Eiva",
"EK",
@ -498,11 +518,13 @@
"ElderLink",
"elfree",
"Elian",
"ELMEX95",
"Elsans320_YT",
"Elskoser",
"ElVolKo",
"ali emad",
"Ramy Emad",
"Emanuel_12",
"Emil",
"Kürti Emil",
"Muhammed emir",
@ -515,6 +537,7 @@
"Enrico",
"enzo",
"Era",
"Era0S (Spazton)",
"Erick",
"Erkam",
"Jonas Ernst",
@ -550,6 +573,7 @@
"Shaikh Fazal",
"Fea",
"FearLessCuBer",
"Feder28",
"Federico",
"Fedrigo",
"Marco Fabián Feijoó",
@ -605,6 +629,7 @@
"GeoMatHeo",
"Gerry",
"GG (9.2)",
"Mohammad gh",
"Onkar Ghagarum",
"GHAIS",
"Omar Ghali",
@ -617,6 +642,7 @@
"Aidan Gil",
"Noe Marley Ginting",
"Giovalli99",
"DEVEGGHI GIOVANNI",
"Giovanny",
"Dc superhero girl",
"Givij",
@ -630,6 +656,7 @@
"박준서(PJS GoodNews)",
"gowthamvelkarthik.k",
"Nicola Grassi",
"Dario Greggio",
"Gerrit Grobler",
"Oliver Grosskloss",
"Alexis Guijarro",
@ -671,6 +698,7 @@
"Florian Haxhijaj",
"Hayate",
"Hayate16",
"hcy_2022",
"hehhwushh",
"Lukas Heim",
"Hugues Heitz",
@ -702,6 +730,7 @@
"Jeremy Horbul",
"Hosein",
"hoseinا",
"HOSSAM",
"Phan Lê Minh Hoàng",
"Jorge Isaac Huertero",
"Hussain",
@ -712,6 +741,7 @@
"iBearzGaming",
"Iboyindyza",
"Ibrahim",
"Iddrejiot",
"Ignacio",
"IgnUp21",
"Igomen15",
@ -724,6 +754,7 @@
"Ily77788",
"Ilya",
"IlyxaGold",
"Imad",
"d imitris",
"Nik ali imran",
"IND_PIYUSH",
@ -737,6 +768,7 @@
"InvisibleDude",
"Anestis Ioakimidis",
"Dragomir Ioan",
"IorYou4600 (V2)",
"Isa",
"Israelme03",
"Tobias Dencker Israelsen",
@ -745,6 +777,7 @@
"ivan",
"iViietZ",
"MOHD IZWAN",
"J3zrel",
"JaaJ",
"Al jabbar",
"Jacek",
@ -772,6 +805,7 @@
"Jeulis",
"Jewellbenj",
"jgst2007@gmail.com",
"Jhoncat086@gmail.com",
"Zhou Jianchu",
"jimmy",
"Jiren",
@ -811,6 +845,7 @@
"kadaradam",
"Efe Kahraman",
"KalakCZ",
"kalenk",
"Adam Kalousek",
"kalpesh",
"Kalyan",
@ -826,9 +861,11 @@
"Burak Karadeniz(MythB)",
"Daniel Karami",
"Karim",
"Karlimero",
"Kasra",
"Kaushik",
"KawaiiON",
"kazooicek",
"KD",
"Kejuxs",
"Mani kelidari",
@ -875,6 +912,7 @@
"kroш)",
"Patel krumil",
"Krunal",
"kueue",
"Alok Kumar",
"sarath kumar",
"Aapeli Kumpulainen",
@ -887,10 +925,12 @@
"Kyle",
"Jan Kölling",
"L_JK",
"Labrador",
"John Patrick Lachica",
"laikrai",
"m a lakum",
"Dmitry Lamperujev",
"Language",
"K. Larsen",
"Nicklas Larsen",
"Shin Lasung",
@ -912,11 +952,14 @@
"LickyBeeYT",
"Nicola Ligas",
"Limak09",
"LimonAga",
"lin",
"Dustin Lin",
"Kyle Lin",
"Linus",
"Linux44313",
"Lippu",
"Lisavidxxxxxxx5",
"LiteBalt",
"LittleNyanCat",
"Juunhao Liu",
@ -927,11 +970,13 @@
"Loex",
"Loko",
"Longkencok",
"杰瑞 longmouses",
"looooooooou",
"LordHiohi",
"Lordigno",
"lorenzo",
"Lostguybrazil",
"Loup",
"mian louw",
"69 lover",
"Jordan Vega Loza",
@ -942,7 +987,7 @@
"Ludicrouswizard",
"satrio ludji",
"Ludovico",
"Luis (GalaxyM4)",
"Luis",
"Jose Luis",
"Luis(GalaxtM4)",
"luislinares",
@ -1008,13 +1053,17 @@
"Eduardo de Matos",
"Matteo",
"Matthias",
"Nepote Mattia",
"Ihsan Maulana ( @ihsanm27)",
"Muhammad Akbar Maulana",
"MAVIS",
"Mavook",
"MazeMan111",
"Federico Mazzone",
"Andrea Mazzucchelli",
"Medic",
"Medic别闹我有药",
"Medic药",
"German Medin",
"Martin Medina",
"Mehret Mehanzel",
@ -1030,6 +1079,7 @@
"Davis Michelle",
"Mick",
"Miguel",
"Luiz \"Foxy\" Miguel",
"Miguelterrazas123",
"Mikael",
"mike",
@ -1041,6 +1091,7 @@
"minh123456789thcsvk",
"MinhAn19203",
"Azfar Ahmed Mirza",
"misael",
"Deepak Mishra",
"Mistetas3002",
"Skramh Miugrik",
@ -1054,6 +1105,7 @@
"Mohamadamin",
"Mohamed",
"Mohammad",
"Mohammad.cur",
"Mohammad11dembele",
"MOHAMMADERFAN",
"Mohammadhosain",
@ -1112,7 +1164,10 @@
"Neel",
"Nel",
"Nemeil",
"E0/Era0S/Spazton neo",
"Era (Spazton neo)",
"Era0S (Spazton neo)",
"Era0S/Spazton neo/E0",
"Mattia Nepote",
"The nerd",
"Gabriel Del Nero",
@ -1152,17 +1207,20 @@
"NullWizard",
"Dhimas Wildan Nz",
"*** Adel NZ. ***",
"Odhalit",
"Ognjen",
"okko",
"Bastián Olea",
"Nikita Oleshko",
"Omar",
"OmarBv",
"omgxd5",
"On3GaMs",
"No One",
"No one",
"Adam Oros",
"Andrés Ortega",
"Zangar Orynbetov",
"Oscar",
"Osmanlı2002",
"Osmanys",
"OyUnBoZaN (NEMUTLUTURKUMDİYENE)",
@ -1191,6 +1249,8 @@
"PC261133",
"PC295933",
"PC432736",
"PC607666",
"PC912334",
"pebikristia",
"Pedro",
"Jiren/Juan Pedro",
@ -1226,8 +1286,10 @@
"Pluisbaard",
"Jaideep Kumar PM",
"podolianyn",
"Pofani",
"poggersCat",
"Pong",
"Lehlogonolo \"YetNT\" Poole",
"Pooya",
"pouriya",
"Pouya",
@ -1243,15 +1305,19 @@
"pszlklismo",
"Pulidomedia.com",
"haris purnama",
"Deva Puspita",
"GABRIEL PUTRICK",
"Bodnár Péter",
"Qellow",
"Gangler Quentin",
"Quezz3x",
"Qwsa",
"QŴE",
"Anbarasan R",
"efvdtrrgvvfygttty5 5 r",
"Felo Raafat",
"Tim Rabatr",
"Vinni The Rabbit",
"Radfrom",
"RadicalGamer",
"Radicool",
@ -1259,6 +1325,7 @@
"raghul",
"khaled rahma",
"Rayhan Rahmats",
"Babang Raja",
"Ralfreengz",
"1. Ramagister",
"Rostislav RAMAGISTER",
@ -1331,6 +1398,7 @@
"Ronianagranada",
"roninjhie@gmail.com",
"Rori",
"Rottlez",
"Mario Roveda",
"Roy",
"Rubanen",
@ -1338,6 +1406,7 @@
"Dosta Rumson",
"Hong Ruoyong",
"Philip Ruppert",
"Language Russia",
"Ryan",
"LiÇViN:Cviatkoú Kanstançin Rygoravič",
"Ricky Joe S.Flores",
@ -1352,6 +1421,7 @@
"Salted",
"Matteo Salvini",
"Salvo04",
"Samen",
"San",
"SaNt0RiNiKits577YT",
"Guilherme Santana",
@ -1379,9 +1449,11 @@
"ShadowQ",
"shafay",
"Manan Shah",
"Fares Shaheen",
"shakesm",
"Sharvesh",
"Nalam Shashwath",
"shemas",
"Haige Shi",
"ShockedGaming",
"Shogun",
@ -1389,6 +1461,8 @@
"Dominik Sikora",
"Leonardo Henrique da Silva",
"Sebastian Silva",
"silver_volt4",
"Aviv Simel",
"Simotoring",
"Pawan Singh sisodiya",
"Skick",
@ -1480,6 +1554,7 @@
"TestGame1",
"TestGame1👽🔥",
"testwindows8189",
"tetee}",
"tgd4",
"Than",
"Thanakorn7215",
@ -1514,6 +1589,7 @@
"TozeLeal",
"Trung Hieu Le Tran",
"Translator",
"TrialTemp",
"Trivago",
"El Trolax",
"tseringlama",
@ -1544,6 +1620,7 @@
"Deepanshu Verma",
"Jop Vernooij",
"Via",
"Vickey",
"Victor",
"paulo victor",
"Vigosl",
@ -1552,6 +1629,7 @@
"Robin Vinith",
"vinoth",
"Vishal",
"Vitorinox",
"VoidNumberZero",
"Voxel",
"Voxel25",
@ -1602,6 +1680,7 @@
"YannSonic",
"Yantohrmnt401",
"Halil Yarkin",
"Yaroslav (Spaz1)",
"amr yasser",
"YellowTractor",
"Yasin YILMAZ",
@ -1649,6 +1728,7 @@
"ZkyweR",
"Nagy Zoltán",
"Lukáš Zounek",
"ZOUZ",
"ZpeedTube",
"|_Jenqa_|",
"¥¥S.A.N.A¥",
@ -1680,6 +1760,7 @@
"Андрей Коваленко",
"куатжан",
"Ваня Марков",
"маталка",
"Драган Милановић",
"Игор Милановић",
"Марко Милановић",
@ -1696,6 +1777,7 @@
"Рома",
"Ромашка :3",
"Кирилл Рябцев",
"Ерасыл Фазылов (Paraxilius)",
"ZEPT\"Александр Фартунов\"",
"Эмир",
"Өмүрзаков Эрсултан",
@ -1715,6 +1797,7 @@
"امیرعلی",
"اوتاكوDZ",
"ایلی",
"ایهان",
"بساام",
"جود",
"حسين حساني",
@ -1753,6 +1836,7 @@
"٦٤٦٦٤٦٤٦",
"علیرضا پودینه",
"वेदाँश त्यागी",
"லோகேஷ்",
"അർഷഖ് ഹസ്സൻ",
"วีรภัทร",
"แมวผงาด(JuniorMeowMeow)",
@ -1778,22 +1862,26 @@
"志夏",
"志夏。",
"志夏君deron",
"扎卡拉Zakara",
"枫夜",
"毛毛毛大毛",
"炸弹朋友和Medic药",
"熊老三",
"盐焗汽水er",
"神仙",
"纳皮猪NapPig.com",
"药药Medic",
"蔚蓝枫叶",
"陈星宇你就是歌姬吧",
"随风飘姚",
"鲨鱼俱乐部",
"鲨鱼服·Medic",
"鲲鹏元帅",
"꧁ephyro꧂",
"가라사대",
"공팔이",
"권찬근",
"김두한",
"김원재",
"넌",
"먹꾸리",

View file

@ -335,6 +335,7 @@
"getMoreGamesText": "الحصول على المزيد من الألعاب",
"titleText": "إضافة لعبة"
},
"allText": "جميع",
"allowText": "السماح",
"alreadySignedInText": "تم تسجيل الدخول من حسابك من جهاز آخر.\n يرجى تبديل الحسابات أو إغلاق اللعبة على الأجهزة الأخرى\n وحاول مرة أخرى.",
"apiVersionErrorText": "خطأ في تحميل الجزء ${NAME}; انه مخصص للإصدار رقم ${VERSION_USED}; يجب استخدام الإصدار ${VERSION_REQUIRED}.",
@ -560,6 +561,7 @@
"disableRemoteAppConnectionsText": "تعطيل اتصالات التطبيق عن بعد",
"disableXInputDescriptionText": "يسمح أكثر من 4 وحدات تحكم ولكن قد لا تعمل كذلك.",
"disableXInputText": "xinput تعطيل",
"disabledText": "معطل",
"doneText": "تم",
"drawText": "تعادل",
"duplicateText": "مكرر",
@ -627,6 +629,7 @@
"useMusicFolderText": "مجلد ملفات الموسيقى"
},
"editText": "تعديل",
"enabledText": "مفعل",
"endText": "إنهاء",
"enjoyText": "استمتع",
"epicDescriptionFilterText": "${DESCRIPTION} بحركة ملحمية بطيئة",
@ -816,7 +819,7 @@
"fullScreenCmdText": "ملء الشاشة (Cmd-F)",
"fullScreenCtrlText": "الشاشه كامله (Ctrl-F)",
"gammaText": "غاما",
"highText": "متوسط",
"highText": "عالي الدقة",
"higherText": "العالي",
"lowText": "منخفض",
"mediumText": "متوسط",
@ -1125,12 +1128,16 @@
"pleaseWaitText": "الرجاء الانتظار . . .",
"pluginClassLoadErrorText": "فشل في تشغيل الاضافة '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "خطأ في بدء الاضافة '${PLUGIN}: ${ERROR}",
"pluginSettingsText": "إعدادات الإضافة",
"pluginsAutoEnableNewText": "تفعيل الإضافات الجديدة تلقائياً",
"pluginsDetectedText": "تم العثور على اضافات جديدة. اعد التشغيل لتفعيلها، او قم بتخصيصها في الاعدادات.",
"pluginsDisableAllText": "تعطيل كل الإضافات",
"pluginsEnableAllText": "تفعيل كل الإضافات",
"pluginsRemovedText": "${NUM} لم تعد الاضافة موجودة.",
"pluginsText": "اضافات",
"practiceText": "تدريب",
"pressAnyButtonPlayAgainText": "اضغط اي زر للعب مجددا...",
"pressAnyButtonText": "اظغط اي زر للإستمرار...",
"pressAnyButtonText": "اضغط أي زر للاستمرار...",
"pressAnyButtonToJoinText": "اضغط اي زر للإنضمام",
"pressAnyKeyButtonPlayAgainText": "اضغط اي زر /اي مفتاح للعب مجددا...",
"pressAnyKeyButtonText": "اضغظ اي مفتاح/زر للإستمرار",
@ -1216,7 +1223,9 @@
"revertText": "العودة",
"runText": "ركض",
"saveText": "حفظ",
"scanScriptsErrorText": "حدث خطأ (أخطاء) في مسح النصوص البرمجية ؛ انظر السجل للحصول على التفاصيل.",
"scanScriptsErrorText": "حدث خطأ أو أخطاء في مسح النصوص البرمجية. اظر إلى السجل لمعرفة التفاصيل.",
"scanScriptsMultipleModulesNeedUpdatesText": "${API} apiواخرى يجب تحديثها ل ${PATH} و ${NUM}",
"scanScriptsSingleModuleNeedsUpdatesText": "${API} api يجب تحديثها ل ${PATH}",
"scoreChallengesText": "نقاط التحديات",
"scoreListUnavailableText": ".قائمة النقاط غير متاحة",
"scoreText": "نتيجة",
@ -1251,7 +1260,7 @@
"enablePackageModsText": "تمكين تعديل الحزمة المحلية",
"enterPromoCodeText": "ادخل الرمز",
"forTestingText": "ملاحظة: هذه القيم هي فقط للاختبار وسيتم فقدانها عند خروج التطبيق.",
"helpTranslateText": "هي عبارة عن ترجمة ${APP_NAME}الترجمات غير الإنجليزية ل\nجماعية، إذا أردت المساهمة أو تصحيح الأخطاء اللغوية والإملائية\n!قم بزيارة الرابط أدناه، وشكرًا لكم مقدمًا",
"helpTranslateText": "ترجمات ${APP_NAME} بلغات أخرى غير الإنجليزية هي جهود تعاونية مدعومة من قبل المجتمع.\nإذا كنت ترغب في المساهمة أو تصحيح ترجمة معينة، يرجى اتباع الرابط أدناه.\nشكرًا لك مقدمًا!",
"kickIdlePlayersText": "طرد اللاعبين غير النشطين",
"kidFriendlyModeText": "وضع الأطفال (يقلل العنف، إلخ)",
"languageText": "لغة",
@ -1260,6 +1269,7 @@
"netTestingText": "اختبار الشبكة",
"resetText": "إعادة تعيين",
"showBombTrajectoriesText": "عرض مسارات القنبلة",
"showInGamePingText": "عرض التأخير الداخلي للعبة",
"showPlayerNamesText": "إظهار اسماء اللاعبين",
"showUserModsText": "عرض مجلد التعديل",
"titleText": "المتقدمة",

View file

@ -7,6 +7,7 @@
"changeOncePerSeason": "Вы можаце змяніць толькі адзін раз за сезон.",
"changeOncePerSeasonError": "Трэба пачакаць наступнага сезона, каб зноў змяніць гэта (${NUM} days)",
"customName": "Зрабіць імя",
"googlePlayGamesAccountSwitchText": "Калі вы жадаеце выкарыстоўваць іншы ўліковы запіс Google,\nвыберыце яго ў Google Play Games.",
"linkAccountsEnterCodeText": "Увесцi Код",
"linkAccountsGenerateCodeText": "Стварыць Код",
"linkAccountsInfoText": "(сінхранізацыя гульні паміж рознымі платформамі)",
@ -14,6 +15,7 @@
"linkAccountsInstructionsText": "Каб звязаць 2 акаўнта, стварыце код на першым\nз іх і увядзіце яго ў другім.\nПрагрэс і пакупкі будуць сінранізаваны.\nВы можаце звязаць да ${COUNT} акаўнтаў.\n\nАсцярожна! Гэта нельга адмяніць!",
"linkAccountsText": "Звязаць Акаўнты",
"linkedAccountsText": "Злучаныя Акаўнты:",
"manageAccountText": "Кiраваць акаўнтам",
"nameChangeConfirm": "Змяніць імя акаўнта на ${NAME} ?",
"resetProgressConfirmNoAchievementsText": "Гэта скіне ўвесь ваш кааператыўны прагрэс\nды лакальныя лепшыя вынікі (акрамя білетаў).\nГэты працэс незваротны. Вы ўпэўнены?",
"resetProgressConfirmText": "Гэта скіне ўвесь ваш кааператыўны\nпрагрэс, дасягненні ды лакальныя вынікі\n(акрамя білетаў). Гэты працэс незваротны.\nВы ўпэўнены?",
@ -40,6 +42,7 @@
"titleText": "Акаўнт",
"unlinkAccountsInstructionsText": "Выберыце ўліковы запіс, каб спыніць сувязь",
"unlinkAccountsText": "Адлучэнне акаунтау",
"unlinkLegacyV1AccountsText": "Адключэнне устарэлых уліковых запісаў (V1)",
"v2LinkInstructionsText": "Выкарыстоўвайце гэтую спасылку, каб стварыць уліковы запіс або ўвайсці.",
"viaAccount": "(праз акаунт ${NAME})",
"youAreSignedInAsText": "Вы ўвайшлі як:"
@ -328,10 +331,12 @@
"achievementsRemainingText": "Дасягенні, Якія Засталіся",
"achievementsText": "Дасягненні",
"achievementsUnavailableForOldSeasonsText": "Прабачце, спецыфіка дасягненняў недаступна для старога сезона.",
"activatedText": "${THING} Актыўны",
"addGameWindow": {
"getMoreGamesText": "Атрымаць больш гульняў...",
"titleText": "Дадаць гульню"
},
"allText": "Усё",
"allowText": "Дазволіць",
"alreadySignedInText": "Ваш уліковы запіс увайшоў з іншай прылады;\nкалі ласка, пераключыце ўліковыя запісы альбо зачыніце гульню на вашым\nіншыя прылады і паспрабуйце яшчэ раз",
"apiVersionErrorText": "Нельга загрузіць модуль ${NAME}; ён прапануецца для api-версіі ${VERSION_USED}; мы карыстаемся ${VERSION_REQUIRED}.",
@ -498,6 +503,7 @@
"welcome2Text": "Вы таксама можаце зарабляць білеты многімі з такіх жа\nзаняткаў. Білеты дазваляюць адкрываць новых персанажаў, \nмапы, міні-гульні, удзельнічаць у турнірах і іншае.",
"yourPowerRankingText": "Ваш Узровень:"
},
"copyConfirmText": "Капіравана ў буфэр",
"copyOfText": "Копія ${NAME}",
"copyText": "Копія",
"createEditPlayerText": "<Стварыць/Змяніць Гульца>",
@ -544,7 +550,9 @@
"deleteText": "Выдаліць",
"demoText": "Дэманстрацыя",
"denyText": "Адхіліць",
"deprecatedText": "Састарэў",
"desktopResText": "Дазвол Экрана",
"deviceAccountUpgradeText": "Увага:\nВы ўзайшлі ў акаўнт дэвайса\n(${NAME}).\nАкаўнты дэвайса будуць Выдалены ў будучай абнове.",
"difficultyEasyText": "Лёгка",
"difficultyHardOnlyText": "Толькі на Складаным Узроўні",
"difficultyHardText": "Цяжка",
@ -553,6 +561,7 @@
"disableRemoteAppConnectionsText": "Адключыць злучэнні з аддаленым дадаткам",
"disableXInputDescriptionText": "Дазваляе больш за 4 кантролераў, але можа таксама не працаваць.",
"disableXInputText": "Адключыць XInput",
"disabledText": "Выключана",
"doneText": "Зроблена",
"drawText": "Нічыя",
"duplicateText": "Дублікат",
@ -621,12 +630,15 @@
"useMusicFolderText": "Тэчка з Музыкай"
},
"editText": "Рэдагаваць",
"enabledText": "Уключана",
"endText": "Канец",
"enjoyText": "Поспехаў!",
"epicDescriptionFilterText": "${DESCRIPTION} у эпічным рэжыме.",
"epicNameFilterText": "${NAME} у Эпічным Рэжыме",
"errorAccessDeniedText": "доступ забаронены",
"errorDeviceTimeIncorrectText": "Час вашага дэвайса Няверны на ${HOURS} Гадзін.\nГэта можа прывесці да праблем.\nКалі ласка праверце ваш час і зону часа ў устаноўках",
"errorOutOfDiskSpaceText": "не хапае месца на дыске",
"errorSecureConnectionFailText": "Нельга Наладзіць бяспечнае падключэнне да інтэрнету. Функцыі інтэренту могуць не працаваць.",
"errorText": "Памылка",
"errorUnknownText": "Невядомая памылка",
"exitGameText": "Зачыніць ${APP_NAME}?",
@ -696,7 +708,7 @@
"emailItText": "Паслаць",
"favoritesSaveText": "Захаваць як абранае",
"favoritesText": "Абранае",
"freeCloudServerAvailableMinutesText": "Наступны бясплатны воблачны сервер будзе абноўлены праз ${MINUTES} мінут",
"freeCloudServerAvailableMinutesText": "Наступны дармовы воблачны сервер даступны праз ${MINUTES} хвілін.",
"freeCloudServerAvailableNowText": "Бясплатны воблачны сервер абнавіўся!",
"freeCloudServerNotAvailableText": "Бясплатных воблачных сервераў няма.",
"friendHasSentPromoCodeText": "${COUNT} квіткоў ${APP_NAME} ад ${NAME}",
@ -768,7 +780,7 @@
"showMyAddressText": "Паказаць мой адрас",
"startHostingPaidText": "Арганізаваць зараз за ${COST}",
"startHostingText": "Арганізаваць",
"startStopHostingMinutesText": "Вы можаце пачаць і спыніць хостынг бясплатна на працягу наступных ${MINUTES} мінут.",
"startStopHostingMinutesText": "Вы можаце запускаць і спыняць хостынг задарма цягам наступных ${MINUTES} хвілін.",
"stopHostingText": "Спыніць хостынг",
"titleText": "Сабраць",
"wifiDirectDescriptionBottomText": "Калі ўсе прылады падтрымліваюць 'Wi-Fi Direct', яны могуць карыстацца ім, каб падключыцца\nадзін да другога. Калі ўсе прылады падключаны, вы можаце ствараць лоббі, карыстаючыся\nўкладкай \"Лакальная сетка\" так жа, як і з звычайнай WiFi сеткай.\n\nДля лепшых вынікаў хост Wi-Fi Direct павінен таксама быць хостам гульні ${APP_NAME}.",
@ -793,7 +805,7 @@
"ticketPack4Text": "Вельмі Вялікі Пакет Квіткоў",
"ticketPack5Text": "Гіганцкі Пакет Квіткоў",
"ticketPack6Text": "Максімальны Пакет Квіткоў",
"ticketsFromASponsorText": "Атрымаць ${COUNT} квіткоў\nад спонсара",
"ticketsFromASponsorText": "Пагледзце Рэкламу і \nатрымайце ${COUNT} Квіткоў",
"ticketsText": "${COUNT} Квіткоў",
"titleText": "Атрымаць Квіткі",
"unavailableLinkAccountText": "Прабачце, пакупкі недаступныя на гэтай платформе.\nВы можаце злучыць гэты акаўнт з іншым акаўнтам на\nіншайплатформе і рабіць пакупкі на ім.",
@ -804,6 +816,8 @@
"youHaveText": "вы маеце ${COUNT} квіткоў"
},
"googleMultiplayerDiscontinuedText": "Прабачце, мультігульны сервіс Гугл не даступны у гэты час.\nЯ клапачуся над гэтым з усёй скорасцю.\n\nДа таго часу, калі ласка паспрабуйце другое падключэнне",
"googlePlayPurchasesNotAvailableText": "Пакупкі ў Google Play недаступныя.\nМагчыма, вам патрэбна абнавіць прыкладанне крамы.",
"googlePlayServicesNotAvailableText": "Сэрвісы Google Play недаступныя.\nНекаторыя функцыі прыкладання могуць быць адключаныя.",
"googlePlayText": "Google Play",
"graphicsSettingsWindow": {
"alwaysText": "Заўсёды",
@ -976,7 +990,7 @@
"seasonEndedDaysAgoText": "Сезон скончыўся ${NUMBER} дзён таму.",
"seasonEndsDaysText": "Сезон скончыцца праз ${NUMBER} дзён.",
"seasonEndsHoursText": "Сезон скончыцца праз ${NUMBER} гадзін.",
"seasonEndsMinutesText": "Сезон скончыцца праз ${NUMBER} мінут.",
"seasonEndsMinutesText": "Сезон скончыцца праз ${NUMBER} хвілін.",
"seasonText": "Сезон ${NUMBER}",
"tournamentLeagueText": "Вы павінны дасягнуць ${NAME} лігі, каб увайсці ў гэты турнір.",
"trophyCountsResetText": "Трафейныя ачкі знікнуць у наступным сезоне."
@ -1002,6 +1016,7 @@
"creditsText": "Падзякі",
"demoMenuText": "Дэма-Меню",
"endGameText": "Скончыць Гульню",
"endTestText": "Тэст пакончаны",
"exitGameText": "Зачыніць Гульню",
"exitToMenuText": "Выйсці ў меню?",
"howToPlayText": "Як Гуляць",
@ -1021,6 +1036,7 @@
"maxConnectionsText": "Максімальная колькасць падключэнняў.",
"maxPartySizeText": "Максімальны памер групы.",
"maxPlayersText": "Максімальная колькасць гульцоў.",
"merchText": "Мэрч! (Кастам!)",
"modeArcadeText": "Аркадны рэжым.",
"modeClassicText": "Класічны рэжым.",
"modeDemoText": "Дэмо рэжым",
@ -1061,12 +1077,13 @@
"notSignedInErrorText": "Вы павінны ўвайсці, каб выканаць гэта.",
"notSignedInGooglePlayErrorText": "Вы павінны ўвайсці з Google Play, каб выканаць гэта.",
"notSignedInText": "не ўвайшлі",
"notUsingAccountText": "Заўвага: Ігнараванне улiковага запiсу ${SERVICE}.\nПерайдзіце ў «Уліковы запіс -> Увайсці з дапамогай ${SERVICE}», калі вы жадаеце яго выкарыстоўваць.",
"nothingIsSelectedErrorText": "Нічога не выбрана!",
"numberText": "№${NUMBER}",
"offText": "Выключана",
"okText": "Так",
"onText": "Уключана",
"oneMomentText": "Адну мінуту...",
"oneMomentText": "Адзін момант...",
"onslaughtRespawnText": "${PLAYER} з'явіцца ў ${WAVE} хвалі",
"orText": "${A} ці ${B}",
"otherText": "Іншае...",
@ -1117,7 +1134,14 @@
"playlistsText": "Плэйлісты",
"pleaseRateText": "Калі вам падабаецца ${APP_NAME}, калі ласка, знайдзіце\nчас, каб ацаніць яго ці напісаць водгук. Гэта забя-\nспечвае сувязь і дапамагае развіццю гульні.\n\nДзякуй!\n-Эрык",
"pleaseWaitText": "Калі ласка пачакай...",
"pluginsDetectedText": "Выяўлены новыя ўбудовы. Уключыце / наладзьце іх у наладах.",
"pluginClassLoadErrorText": "Памылка пры загрузцы класа падключанага модулю \"${PLUGIN}\": ${ERROR}",
"pluginInitErrorText": "Памылка пры ініцыялізацыі плагіна \"${PLUGIN}\": ${ERROR}",
"pluginSettingsText": "Устаноўкі Плагінаў",
"pluginsAutoEnableNewText": "Аўтаматычнае ўключэнне новых плагінаў",
"pluginsDetectedText": "Выяўлены новыя плагiны. Перазапусціце, каб выкарыстоўваць іх, або наладзьце іх у наладах",
"pluginsDisableAllText": "Адключыць усе плагіны",
"pluginsEnableAllText": "Выбраць усе плагіны",
"pluginsRemovedText": "${NUM} Плагін(аў) Няма.",
"pluginsText": "Убудовы",
"practiceText": "Практыка",
"pressAnyButtonPlayAgainText": "Націсніце любую кнопку, каб перазапусціць...",
@ -1208,7 +1232,9 @@
"revertText": "Аднавіць",
"runText": "Бяжаць",
"saveText": "Захаваць",
"scanScriptsErrorText": "Памылкі пры сканаванні сцэнарыяў; падрабязнасці глядзіце ў логах.",
"scanScriptsErrorText": "Памылкі пры сканаванні плагаў. Падрабязнасці глядзіце ў логах.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} і ${NUM} іншых модуляў патрэбна абнавіць для API ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} патрэбна абнавіць для API ${API}.",
"scoreChallengesText": "Іншыя Вынікі",
"scoreListUnavailableText": "Вынікі недаступны.",
"scoreText": "Ачкі",
@ -1253,6 +1279,7 @@
"netTestingText": "Тэсціраванне Сеткі",
"resetText": "Скінуць",
"showBombTrajectoriesText": "Паказваць Траекторыi Бомб",
"showInGamePingText": "Паказываць Пынг Гульні",
"showPlayerNamesText": "Паказваць Імёны Гульцоў",
"showUserModsText": "Паказаць Тэчку З Модамі",
"titleText": "Дадаткова",
@ -1360,7 +1387,7 @@
"timeExpiredText": "Час Скончыўся",
"timeSuffixDaysText": "${COUNT} дзён",
"timeSuffixHoursText": "${COUNT} гадзін",
"timeSuffixMinutesText": "${COUNT} мінут",
"timeSuffixMinutesText": "${COUNT} хвілін",
"timeSuffixSecondsText": "${COUNT} секунд",
"tipText": "Парада",
"titleText": "BombSquad",
@ -1373,6 +1400,7 @@
"tournamentStandingsText": "Месцы ў Турніры",
"tournamentText": "Турнір",
"tournamentTimeExpiredText": "Час Турніра Скончыўся",
"tournamentsDisabledWorkspaceText": "Турніры адключаныя, калі працоўныя вобласці актыўныя.\nКаб зноў уключыць турніры, адключыце працоўную вобласць і перазапусціце гульню.",
"tournamentsText": "Турніры",
"translations": {
"characterNames": {
@ -1527,6 +1555,7 @@
"Italian": "Італьянская",
"Japanese": "Японская",
"Korean": "Карэйская",
"Malay": "Малаі",
"Persian": "Фарсі",
"Polish": "Польская",
"Portuguese": "Партугальская",
@ -1650,14 +1679,14 @@
"Your friend code was used by ${ACCOUNT}": "${ACCOUNT} выкарыстаў ваш сяброўскі код"
},
"settingNames": {
"1 Minute": "1 Мінута",
"1 Minute": "1 Хвіліна",
"1 Second": "1 Секунда",
"10 Minutes": "10 Мінут",
"2 Minutes": "2 мінуты",
"10 Minutes": "10 Хвілін",
"2 Minutes": "2 Хвіліны",
"2 Seconds": "2 Секунды",
"20 Minutes": "20 Мінут",
"20 Minutes": "20 Хвілін",
"4 Seconds": "4 Секунды",
"5 Minutes": "5 Мінут",
"5 Minutes": "5 Хвілін",
"8 Seconds": "8 секунд",
"Allow Negative Scores": азволiць Адмоўныя Вынікі",
"Balance Total Lives": "Размяркоўваць Здароўе, Якое Засталося",
@ -1810,6 +1839,7 @@
"usesExternalControllerText": "Гэта гульня можа выкарыстоўваць знешні кантролер для кіравання.",
"usingItunesText": "Выкарыстанне музычнага прыкладання для саўндтрэка ...",
"usingItunesTurnRepeatAndShuffleOnText": "Калі ласка, праверце, што ператасаванне і паўтор усяго ў iTunes ўключаны. ",
"v2AccountLinkingInfoText": "Да прывязкі акаўнту V2, Нажміце 'Кіраваць акаўнтамі'.",
"validatingTestBuildText": "Праверка Тэставай Зборкі...",
"victoryText": "Перамога!",
"voteDelayText": "Вы не можаце пачаць яшчэ адно галасаванне на працягу ${NUMBER} секунд",
@ -1842,6 +1872,7 @@
},
"waveText": "Хваля",
"wellSureText": "Выдатна!",
"whatIsThisText": "Гэта што?",
"wiimoteLicenseWindow": {
"titleText": "DarwiinRemote Copyright"
},
@ -1860,6 +1891,8 @@
"winsPlayerText": "${NAME} Перамагае!",
"winsTeamText": "${NAME} Перамагаюць!",
"winsText": "${NAME} Перамагае!",
"workspaceSyncErrorText": "Памылка сінхранізацыі ${WORKSPACE}. Падрабязнасці глядзіце ў часопісе памылак.",
"workspaceSyncReuseText": "Немагчыма сінхранізаваць ${WORKSPACE}. Паўторнае выкарыстанне папярэдняй сінхранізаванай версіі.",
"worldScoresUnavailableText": "Сусветныя вынікі недаступны.",
"worldsBestScoresText": "Лепшыя Сусветныя Вынікі",
"worldsBestTimesText": "Лепшы Сусветны Час",

View file

@ -338,6 +338,7 @@
"getMoreGamesText": "获取更多游戏模式…",
"titleText": "添加比赛"
},
"allText": "全部",
"allowText": "允许",
"alreadySignedInText": "您的账号已在其他设备登录;\n请切换账号或者退出已登录的设备\n然后再试一次",
"apiVersionErrorText": "无法加载模组${NAME};它的API版本为 ${VERSION_USED},我们需要 ${VERSION_REQUIRED}.",
@ -506,14 +507,14 @@
},
"copyConfirmText": "复制到剪贴板",
"copyOfText": "${NAME} 复制",
"copyText": "copy",
"copyText": "复制",
"createEditPlayerText": "<创建/编辑玩家>",
"createText": "创建",
"creditsWindow": {
"additionalAudioArtIdeasText": "添补音频、初期原图和创意:${NAME}",
"additionalMusicFromText": "添补背景音乐:${NAME}",
"allMyFamilyText": "帮助进行游戏测试的我的所有好友和家人",
"codingGraphicsAudioText": "编码、图像和音频${NAME}",
"codingGraphicsAudioText": "编程、图形引擎和音频引擎${NAME}",
"languageTranslationsText": "语言翻译:",
"legalText": "法律:",
"publicDomainMusicViaText": "版权公有音乐:${NAME}",
@ -562,6 +563,7 @@
"disableRemoteAppConnectionsText": "解除手柄应用链接",
"disableXInputDescriptionText": "允许使用4个以上的控制器但可能不会正常工作",
"disableXInputText": "禁用XInput",
"disabledText": "禁用",
"doneText": "完成",
"drawText": "平局",
"duplicateText": "复制",
@ -579,7 +581,7 @@
"titleText": "列表编辑器"
},
"editProfileWindow": {
"accountProfileInfoText": "此特殊玩家档案,\n可能含有其中一个图标:\n\n${ICONS}\n\n基于您的登录平台以显示\n相关图标。",
"accountProfileInfoText": "此特殊玩家档案,\n可能含有其中一个图标:\n\n${ICONS}\n\n基于您的登录平台以显示\n相关图标。(其中一部分可能已经绝版)",
"accountProfileText": "(账户资料)",
"availableText": "\"${NAME}\"可用。",
"changesNotAffectText": "注意:更改不会影响已经存在的比赛角色",
@ -631,6 +633,7 @@
"useMusicFolderText": "音乐文件夹"
},
"editText": "修改",
"enabledText": "启用",
"endText": "结束",
"enjoyText": "尽情享用吧!",
"epicDescriptionFilterText": "史诗级慢动作 ${DESCRIPTION}。",
@ -645,7 +648,7 @@
"exportSuccessText": "退出'${NAME}'",
"externalStorageText": "外部存储器",
"failText": "失败",
"fatalErrorText": "哎呀,有些档案遗失或损坏了。\n请尝试重新安装游戏或者\n联系 ${EMAIL} 寻求帮助",
"fatalErrorText": "哎呀,有些文件丢失或损坏了喵~\n请尝试重新安装游戏或者\n联系 ${EMAIL} 寻求帮助",
"fileSelectorWindow": {
"titleFileFolderText": "选择一个文件或文件夹",
"titleFileText": "选择一个文件",
@ -677,7 +680,7 @@
"editText": "编辑比\n赛列表",
"gameListText": "比赛列表",
"newText": "新建比\n赛列表",
"showTutorialText": "显示教程",
"showTutorialText": "播放教程",
"shuffleGameOrderText": "随机比赛模式",
"titleText": "自定义${TYPE}列表"
},
@ -686,8 +689,8 @@
},
"gamesToText": "${WINCOUNT}比${LOSECOUNT}",
"gatherWindow": {
"aboutDescriptionLocalMultiplayerExtraText": "请记住:如果你有足够多的游戏手柄,\n派对中的任意设备可允许多个玩家同时游戏。",
"aboutDescriptionText": "使用这些选项卡来组织一场派对。\n\n通过派对你可以和好友在不同的设备上\n一起玩游戏和比赛。\n\n使用手柄右上角的${PARTY}按钮\n来发起派对聊天和互动。\n在菜单中时按${BUTTON}",
"aboutDescriptionLocalMultiplayerExtraText": "请记住:如果你有足够多的游戏手柄,\n那你就可以让多个玩家用手柄同时游戏。",
"aboutDescriptionText": "这个选项卡是用来联机(开派对/房间)的喵~\n\n在派对中你可以和朋友在不同的设备上\n一起玩游戏和比赛。\n\n点击右上角的${PARTY}按钮\n来发起派对聊天和互动。\n手柄请在菜单中时按${BUTTON}",
"aboutText": "关于",
"addressFetchErrorText": "<获取地址出错>",
"appInviteInfoText": "邀请好友一起玩BombSquad新玩家可获得 ${COUNT}免费点券。\n每成功邀请到一位好友您可获得${YOU_COUNT}点券。",
@ -715,10 +718,10 @@
"friendHasSentPromoCodeText": "从 ${NAME} 中获取 ${COUNT} 张 ${APP_NAME} 点券",
"friendPromoCodeAwardText": "每使用一次,你可收到${COUNT}张点券。",
"friendPromoCodeExpireText": "代码将在 ${EXPIRE_HOURS} 小时后失效,代码仅适用于新玩家。",
"friendPromoCodeInstructionsText": "要使用代码,可打开 ${APP_NAME},按\"设置->高级->输入促销代码\"操作。\n所有支持平台的下载链接见 bombsquadgame.com。",
"friendPromoCodeInstructionsText": "要使用代码,可打开 ${APP_NAME},按\"设置->高级->输入兑换代码\"操作。\n要下载最新版请访问www.bombsquad.cn",
"friendPromoCodeRedeemLongText": "达到${MAX_USES}人后,就不可获得${COUNT}免费点券。(防止玩家用来作弊)",
"friendPromoCodeRedeemShortText": "可在游戏中兑换${COUNT}免费点券。",
"friendPromoCodeWhereToEnterText": "(在\"设置->高级->输入促销代码\"中)",
"friendPromoCodeWhereToEnterText": "(在\"设置->高级->输入兑换代码\"中)",
"getFriendInviteCodeText": "获取好友邀请码",
"googlePlayDescriptionText": "邀请Google Play玩家来加入你的派对",
"googlePlayInviteText": "邀请",
@ -733,7 +736,7 @@
"inviteAFriendText": "好友还未加入该游戏?邀请他们\n一起玩新玩家可获得${COUNT}张免费点券。",
"inviteFriendsText": "邀请朋友",
"joinPublicPartyDescriptionText": "加入一个公开派对",
"localNetworkDescriptionText": "加入一个局域网派对(通过wifi蓝牙etc等)",
"localNetworkDescriptionText": "加入一个局域网派对(通过wifi蓝牙各种方式)",
"localNetworkText": "本地网络",
"makePartyPrivateText": "将我的派对变成私人派对",
"makePartyPublicText": "将我的派对变成公开派对",
@ -744,7 +747,7 @@
"manualJoinableFromInternetText": "是否可从互联网连接?:",
"manualJoinableNoWithAsteriskText": "否*",
"manualJoinableYesText": "是",
"manualRouterForwardingText": "* 若要解决此问题请尝试将您的路由器设置为将UDP端口${PORT}转发到你的本地地址地址一般是192.168.*.1",
"manualRouterForwardingText": "* 若要解决此问题请尝试将您的路由器设置为将UDP端口${PORT}转发到你的本地地址地址一般是192.168.*.*",
"manualText": "手动",
"manualYourAddressFromInternetText": "互联网地址:",
"manualYourLocalAddressText": "本地地址:",
@ -767,7 +770,7 @@
"partyStatusNotPublicText": "你的派对是私人的",
"pingText": "延迟",
"portText": "端口",
"privatePartyCloudDescriptionText": "私有方在专用的云服务器上运行;无需路由器配置",
"privatePartyCloudDescriptionText": "私人服务器在官方的云服务器上运行;无需路由器配置",
"privatePartyHostText": "创建一个私人派对",
"privatePartyJoinText": "加入一个公开派对",
"privateText": "私人",
@ -781,14 +784,14 @@
"startHostingText": "创建",
"startStopHostingMinutesText": "你还可以使用${MINUTES}分钟的免费服务器",
"stopHostingText": "停止主机",
"titleText": "多人游戏",
"titleText": "在线游戏",
"wifiDirectDescriptionBottomText": "如果所有设备都设有 Wi-Fi Direct 面板,那他们应该可以使用通过它来找到彼此,\n然后相互连接。一旦所有设备都相互连接上了你就可以通过“本地网络”选项卡\n在此组织派对常规的无线局域网也是一样。\n\n如要取得最佳效果Wi-Fi Direct 创建者也应是${APP_NAME} 派对的创建者",
"wifiDirectDescriptionTopText": "无需无线网络即可直接\n通过Wi-Fi Direct连接安卓设备。对于安装了Android 4.2或更高版本操作系统的设备效果更好。\n\n要使用该功能可打开无线网络连接设置然后在菜单中寻找'Wi-Fi Direct'。",
"wifiDirectOpenWiFiSettingsText": "打开无线网络连接设置",
"wifiDirectText": "Wi-Fi Direct",
"worksBetweenAllPlatformsText": "(所有平台之间运作)",
"worksWithGooglePlayDevicesText": "适用于运行Google Play安卓版游戏的设备",
"youHaveBeenSentAPromoCodeText": "您已送出一个 ${APP_NAME} 促销代码:"
"youHaveBeenSentAPromoCodeText": "您已送出一个 ${APP_NAME} 兑换代码:"
},
"getTicketsWindow": {
"freeText": "免费!",
@ -829,7 +832,7 @@
"mediumText": "中",
"neverText": "关",
"resolutionText": "分辨率",
"showFPSText": "显示FPS",
"showFPSText": "显示FPS帧数",
"texturesText": "材质质量",
"titleText": "图像质量",
"tvBorderText": "电视边缘",
@ -838,9 +841,9 @@
},
"helpWindow": {
"bombInfoText": "炸弹\n比拳头伤害高但也能把自己送上西天。\n给你个建议等引线快烧完的时候\n再把炸弹扔向敌人。",
"canHelpText": "${APP_NAME}可以帮助。",
"canHelpText": "${APP_NAME}小帮助可以帮你快速入门!",
"controllersInfoText": "你可以和好友在同一网络下玩${APP_NAME},或者\n如果你有足够多的手柄那也可以在同一个设备上游戏。\n${APP_NAME}支持各种选择;你甚至可以通过免费的'${REMOTE_APP_NAME}'\n用手机作为游戏手柄。\n更多信息请参见设置->手柄。",
"controllersInfoTextRemoteOnly": "你可以通过与你的朋友们一起游玩${APP_NAME}\n或者你可以使用${REMOTE_APP_NAME}\n它会将你的手机作为手柄在同一个设备上与你的朋友一起游玩",
"controllersInfoTextRemoteOnly": "你可以通过局域网与你的朋友们一起游玩${APP_NAME}\n或者你可以使用${REMOTE_APP_NAME}\n它会将你的手机作为手柄在同一个设备上与你的朋友一起游玩",
"controllersText": "手柄",
"controlsSubtitleText": "你的友好的${APP_NAME}角色具有几个基本动作:",
"controlsText": "控制键",
@ -849,11 +852,11 @@
"friendsGoodText": "这对你而言都是好事。和三五好友一起玩${APP_NAME}最有趣了,\n最多可以支持8个玩家一起玩进入",
"friendsText": "好友",
"jumpInfoText": "跳跃\n跳跃可以跳过较窄的缝隙\n或是把炸弹扔的更远\n或是表达你难以掩盖的喜悦之情。",
"orPunchingSomethingText": "或用拳猛击敌人,将它砸下悬崖,然后在它下落的途中用粘性炸弹炸掉它。",
"orPunchingSomethingText": "还可以用拳头攻击,或者把敌人举起来然后丢下去,或者更多好玩的...",
"pickUpInfoText": "拾起\n你可以拾起旗子敌人\n还有所有没固定在地上的东西\n然后再扔出去吧。",
"powerupBombDescriptionText": "将炸弹最大投掷数量\n由一个提升为三个",
"powerupBombNameText": "三连炸弹",
"powerupCurseDescriptionText": "你可能想要避开这些。\n…或者你想试试看",
"powerupCurseDescriptionText": "最好不要接触它。\n...或者你想试试",
"powerupCurseNameText": "诅咒",
"powerupHealthDescriptionText": "完全回血!\n想不到吧!",
"powerupHealthNameText": "医疗包",
@ -873,7 +876,7 @@
"powerupsText": "道具",
"punchInfoText": "拳击\n跑得越快拳击的伤害\n越高。所以像疯子一样\n旋转跳跃吧",
"runInfoText": "冲刺\n按任意键冲刺如果你用手柄操作将会容易许多。\n冲刺跑的虽快但会造成转向困难。且冲且珍惜。",
"someDaysText": "有些时候你只是想挥拳猛击某些东西,或把什么东西给炸飞。",
"someDaysText": "当你想攻击别人时,你可以用各种炸弹",
"titleText": "${APP_NAME}帮助",
"toGetTheMostText": "要想最痛快地玩这个游戏,你需要:",
"welcomeText": "欢迎来到${APP_NAME}"
@ -891,7 +894,7 @@
"arrowsToExitListText": "按${LEFT}或${RIGHT}退出列表",
"buttonText": "按钮",
"cantKickHostError": "你不能踢房主啊喂!",
"chatBlockedText": "玩家 ${NAME} 被禁言 ${TIME} 秒.",
"chatBlockedText": "玩家 ${NAME} 被禁言 ${TIME} 秒,有话慢点说",
"connectedToGameText": "加入 '${NAME}'",
"connectedToPartyText": "加入${NAME}的房间!",
"connectingToPartyText": "正在连接...",
@ -899,7 +902,7 @@
"connectionFailedPartyFullText": "连接出错:房间满员了…",
"connectionFailedText": "连接失败。",
"connectionFailedVersionMismatchText": "连接失败;创建者正在运行不同版本的游戏。\n请确保你们都安装了最新版本然后再试一次。",
"connectionRejectedText": "连接被拒绝",
"connectionRejectedText": "连接被拒绝,你有可能被踢了",
"controllerConnectedText": "${CONTROLLER}已连接。",
"controllerDetectedText": "检测到1个手柄。",
"controllerDisconnectedText": "${CONTROLLER}断开连接。",
@ -940,8 +943,8 @@
"timeOutText": "(将在${TIME}秒内超出时限)",
"touchScreenJoinWarningText": "您已以触摸屏方式加入。\n如果这是一个错误点击“菜单->离开游戏菜单”。",
"touchScreenText": "触摸屏",
"unableToResolveHostText": "错误:房主有问题",
"unavailableNoConnectionText": "哎呀,这个用不了呢(网络连接故障?",
"unableToResolveHostText": "错误:请输入正确的地址",
"unavailableNoConnectionText": "哎呀,这个用不了呢(请等待连接主服务器",
"vrOrientationResetCardboardText": "重置VR定位。\n您需使用外部手柄来玩该游戏。",
"vrOrientationResetText": "VR定位重置。",
"willTimeOutText": "(若空闲则会超出时限)"
@ -963,7 +966,7 @@
"kickVoteStartedText": "踢出${NAME}的投票已被发起",
"kickVoteText": "投票踢出玩家",
"kickVotingDisabledText": "投票踢出已被禁用.",
"kickWithChatText": "在聊天框中输入 ${YES} 来同意,输入 ${NO} 来拒绝(输入2来弃权)",
"kickWithChatText": "在聊天框中输入 ${YES} 来同意,输入 ${NO} 来拒绝",
"killsTallyText": "${COUNT}次击杀",
"killsText": "击杀数",
"kioskWindow": {
@ -1018,10 +1021,10 @@
"endTestText": "结束测试",
"exitGameText": "退出",
"exitToMenuText": "退出到菜单",
"howToPlayText": "帮助",
"howToPlayText": "帮助",
"justPlayerText": "(仅${NAME}",
"leaveGameText": "离开游戏",
"leavePartyConfirmText": "确实要离开吗",
"leavePartyConfirmText": "你确定要离开",
"leavePartyText": "离开派对",
"quitText": "离开游戏",
"resumeText": "回到游戏",
@ -1047,7 +1050,7 @@
"multiPlayerCountText": "${COUNT}名玩家",
"mustInviteFriendsText": "注意:你必须在“${GATHER}”面板中邀请好友,\n或连接多个\n手柄和好友一起游戏。",
"nameBetrayedText": "${NAME}背叛了${VICTIM}",
"nameDiedText": "${NAME}挂了。",
"nameDiedText": "${NAME}寄了",
"nameKilledText": "${NAME}把${VICTIM}杀了",
"nameNotEmptyText": "名字不能为空",
"nameScoresText": "${NAME}得分咯!",
@ -1138,7 +1141,7 @@
"pleaseWaitText": "请稍等...",
"pluginClassLoadErrorText": "加载'${PLUGIN}'插件时出错了耶: ${ERROR}",
"pluginInitErrorText": "初始化'${PLUGIN}'插件失败了啦: ${ERROR}",
"pluginSettingsText": "插件设置",
"pluginSettingsText": "插件设置",
"pluginsAutoEnableNewText": "自动启用新插件",
"pluginsDetectedText": "新插件安装成功,请重启游戏或在设置中设置它们~",
"pluginsDisableAllText": "禁用所有插件",
@ -1176,7 +1179,7 @@
"purchasingText": "正在购买…",
"quitGameText": "退出${APP_NAME}",
"quittingIn5SecondsText": "在5秒后退出...",
"randomPlayerNamesText": "企鹅王,企鹅骑士团成员,王♂の传人,挨揍使我快乐,ChineseBomber,一拳超人,二营长の意大利炮,野渡无人舟自横,马克斯,雪糕,炸鸡翅,手柄玩家18子,寻找宝藏的海盗,炸弹投手,炸弹不是糖果,我是对面的,万有引力,鸟语花香,年大吉,小狗狗,大狗子,二狗子,三狗子,四狗子,五狗子,高质量人类,吴签,菜虚困,劈我瓜是吧,是我dio哒,亚达哟,王雷卖鱼,蕉♂个朋友,小猪配齐,摇摆羊,可莉,胡桃,钟离,七七,刻晴,甘雨,巴巴托斯,温迪,旅行者,绿坝娘,哔哩哔哩,别闹我有药",
"randomPlayerNamesText": "企鹅王,企鹅骑士团成员,王♂の传人,挨揍使我快乐,ChineseBomber,一拳超人,二营长の意大利炮,野渡无人舟自横,马克斯,雪糕,炸鸡翅,手柄玩家18子,寻找宝藏的海盗,炸弹投手,炸弹不是糖果,我是对面的,万有引力,鸟语花香,年大吉,小狗狗,大狗子,二狗子,三狗子,四狗子,五狗子,高质量人类,吴签,菜虚困,劈我瓜是吧,是我dio哒,亚达哟,王雷卖鱼,蕉♂个朋友,小猪配齐,陈星宇批发商,蒙飞批发商,蒙腾批发商,渴望被怜爱的弱受杰瑞,汤姆猫,小灰机,炸弹大队队长,炸弹教主",
"randomText": "随机",
"rankText": "排行",
"ratingText": "排名",
@ -1234,7 +1237,9 @@
"revertText": "还原",
"runText": "运行",
"saveText": "保存",
"scanScriptsErrorText": "扫描脚本存在一个或多个错误;查看错误日志来了解详情。",
"scanScriptsErrorText": "检查Mod文件时发现错误,报错见炸队日志文件喵",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} 和 ${NUM} 个模组需要升级到API${API}才能使用喵~",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} 需要升级到API${API}才能使用喵~",
"scoreChallengesText": "得分挑战",
"scoreListUnavailableText": "得分列表不可用。",
"scoreText": "得分",
@ -1245,10 +1250,10 @@
},
"scoreWasText": "(是${COUNT}",
"selectText": "选择",
"seriesWinLine1PlayerText": "得",
"seriesWinLine1TeamText": "得",
"seriesWinLine1Text": "得",
"seriesWinLine2Text": "系列",
"seriesWinLine1PlayerText": "得",
"seriesWinLine1TeamText": "得",
"seriesWinLine1Text": "得",
"seriesWinLine2Text": "冠军",
"settingsWindow": {
"accountText": "账户",
"advancedText": "高级",
@ -1268,26 +1273,26 @@
"disableThisNotice": "(可在高级设置中关闭此通知)",
"enablePackageModsDescriptionText": "(启用额外的模组功能,但是禁用多人模式)",
"enablePackageModsText": "启用本地程序包修改",
"enterPromoCodeText": "输入促销代码",
"enterPromoCodeText": "输入兑换代码喵~",
"forTestingText": "注意:这些数值仅用于测试,并会在应用程序退出时丢失。",
"helpTranslateText": "${APP_NAME}的非英语翻译是社区\n共同努力的成果。如果您希望参与翻译或对其提出更正\n请点击以下链接。先行感谢!",
"helpTranslateText": "${APP_NAME}有中文汉化是咱们社区\n共同努力的成果。如果您希望参与翻译或对其提出更正\n请点击这个按钮。十分感谢!",
"kickIdlePlayersText": "踢掉空闲玩家",
"kidFriendlyModeText": "儿童友好模式(低暴力等)",
"languageText": "语言",
"moddingGuideText": "修改指南",
"moddingGuideText": "Mod文档",
"mustRestartText": "您必须重启游戏来使之生效",
"netTestingText": "网络测试",
"resetText": "恢复默认值",
"showBombTrajectoriesText": "显示炸弹轨迹",
"showInGamePingText": "显示游戏延迟",
"showPlayerNamesText": "显示玩家名字",
"showUserModsText": "显示修改文件夹",
"showUserModsText": "显示Mod文件夹",
"titleText": "高级",
"translationEditorButtonText": "${APP_NAME}翻译编辑器",
"translationFetchErrorText": "翻译状态不可用",
"translationFetchingStatusText": "检查翻译进度…",
"translationInformMe": "所选语言可更新时请通知我!",
"translationNoUpdateNeededText": "当前语言是最新的;",
"translationFetchingStatusText": "正在检查翻译进度…",
"translationInformMe": "中文需要更新翻译时请通知我!",
"translationNoUpdateNeededText": "当前语言是最新的;呜!",
"translationUpdateNeededText": "**当前语言需要更新!! **",
"vrTestingText": "VR测试"
},
@ -1334,7 +1339,7 @@
"charactersText": "人物",
"comingSoonText": "敬请期待……",
"extrasText": "额外部分",
"freeBombSquadProText": "BombSquad现在是免费的由于最初您是通过购买所得您将获得\nBombSquad专业版升级和${COUNT}点券,以表感谢。\n尽享全新功能同时感谢您的支持\n-Eric",
"freeBombSquadProText": "炸弹小分队现在是免费的,由于最初您是通过购买所得,您将获得\n炸弹小分队专业版升级和${COUNT}点券,以表感谢。\n尽享全新功能同时感谢您的支持\n-Eric",
"gameUpgradesText": "游戏升级",
"holidaySpecialText": "假期特献",
"howToSwitchCharactersText": "(进入\"${SETTINGS} -> ${PLAYER_PROFILES}\"指定和自定义人物)",
@ -1361,14 +1366,14 @@
"winterSpecialText": "冬季特献",
"youOwnThisText": "- 您已拥有 -"
},
"storeDescriptionText": "8人派对游戏尽显疯狂!\n\n在爆炸类迷你游戏中炸飞您的好友或电脑如夺旗战、冰球战及史诗级慢动作死亡竞赛\n\n简单的控制和广泛的手柄支持可轻松允许多达8人参与游戏您甚至可以通过免费的“BombSquad Remote”应用将您的移动设备作为手柄使用\n\n投射炸弹\n\n更多信息请登录www.froemling.net/bombsquad。",
"storeDescriptionText": "8人派对游戏疯狂乱炸!\n\n在迷你型爆炸游戏炸飞你的基友或机器人如夺旗战、冰球战及史诗级慢动作死亡竞赛\n\n控制简单操作便捷可轻松支持多达8人同时游戏您甚至可以通过免费的“炸弹小分队手柄”应用将您的手机作为手柄使用\n\n炸死他们吧hiahiahia\n\n更多信息请打开www.froemling.net/bombsquad。",
"storeDescriptions": {
"blowUpYourFriendsText": "炸飞你的好友。",
"competeInMiniGamesText": "在从竞速到飞行的迷你游戏中一较高下。",
"customize2Text": "自定义角色、迷你游戏,甚至背景音乐",
"customizeText": "自定义角色并创建自己的迷你游戏播放列表。",
"sportsMoreFunText": "加入炸药后运动变得更加有趣。",
"teamUpAgainstComputerText": "组队对抗电脑程序。"
"blowUpYourFriendsText": "炸飞你的朋友们",
"competeInMiniGamesText": "在竞速游戏、飞行游戏中一决高下吧",
"customize2Text": "支持自定义角色、游戏玩法,甚至背景音乐",
"customizeText": "选择角色并创建自己的游戏关卡吧",
"sportsMoreFunText": "加入炸药后游戏会变得更嗨皮。",
"teamUpAgainstComputerText": "或者和机器人PK"
},
"storeText": "商店",
"submitText": "提交",
@ -1629,26 +1634,26 @@
"Entering tournament...": "进入锦标赛……",
"Invalid code.": "代码无效。",
"Invalid payment; purchase canceled.": "不可用的付款方式:交易取消",
"Invalid promo code.": "促销代码无效。",
"Invalid promo code.": "诶呀,代码好像无效了捏~",
"Invalid purchase.": "购买无效。",
"Invalid tournament entry; score will be ignored.": "错误的联赛资料,分数会被忽略。",
"Invalid tournament entry; score will be ignored.": "由于你的联赛资料错误,分数会被忽略...",
"Item unlocked!": "项目已解除锁定!",
"LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "连接账号行为取消。${ACCOUNT} 含有\n重要数据可能会丢失。\n如果你想要的话你可以反向链接账号。\n(那样就会丢失这个账号的数据)",
"Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "将帐户${ACCOUNT}关联到此帐户吗?\n${ACCOUNT}将共享数据。\n此操作不能撤销。",
"Max number of playlists reached.": "已达到最大列表数目。",
"Max number of profiles reached.": "已达到最大档案数目。",
"Maximum friend code rewards reached.": "邀请码奖励达到上限",
"Message is too long.": "消息太长.",
"Message is too long.": "诶呀,消息有点长捏~有话慢慢说",
"No servers are available. Please try again soon.": "当前没有空余的服务器,请稍后再试",
"Profile \"${NAME}\" upgraded successfully.": "${NAME}档案升级成功。",
"Profile could not be upgraded.": "档案不可升级。",
"Purchase successful!": "购买成功!",
"Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "登录领取${COUNT}点券。\n明日再来领取${TOMORROW_COUNT}。",
"Received ${COUNT} tickets for signing in.\nCome back tomorrow to receive ${TOMORROW_COUNT}.": "登录成功 获得${COUNT}点券喵~\n明日再来领取${TOMORROW_COUNT}。",
"Server functionality is no longer supported in this version of the game;\nPlease update to a newer version.": "此版本的游戏不再支持服务器功能;\n请更新到较新版本。",
"Sorry, there are no uses remaining on this code.": "对不起,此代码已经无法继续使用了。",
"Sorry, this code has already been used.": "对不起,此代码已被使用。",
"Sorry, this code has expired.": "对不起,此代码已失效。",
"Sorry, this code only works for new accounts.": "对不起,此代码仅适用于新账户。",
"Sorry, this code only works for new accounts.": "此代码只能新用户使用啊喂!你是新用户嘛",
"Still searching for nearby servers; please try again soon.": "正在搜索附近的服务器,请稍后再试",
"Temporarily unavailable; please try again later.": "目前暂不可用;请稍候再试!",
"The tournament ended before you finished.": "本次锦标赛在你完成之前结束。",
@ -1664,17 +1669,17 @@
"You already own this!": "你已拥有了!",
"You can join in ${COUNT} seconds.": "你在${COUNT} 秒后可以加入",
"You don't have enough tickets for this!": "你的点券不足!",
"You don't own that.": "你尚未拥有",
"You don't own that.": "你没有真正购买它呢..(也许你正在用破解版)",
"You got ${COUNT} tickets!": "你获得了${COUNT}点券!",
"You got a ${ITEM}!": "你获得了一个${ITEM}",
"You have been promoted to a new league; congratulations!": "你已被升级至一个新联赛;恭喜!",
"You have been promoted to a new league; congratulations!": "你已被升级至一个新联赛等级;恭喜!",
"You must update to a newer version of the app to do this.": "你必须升级到最新版本才可以",
"You must update to the newest version of the game to do this.": "你必须更新到最新版来做到这一点。",
"You must wait a few seconds before entering a new code.": "你必须在输入新代码前稍等几秒。",
"You ranked #${RANK} in the last tournament. Thanks for playing!": "你在上一场锦标赛中排名#${RANK}。多谢玩赏本游戏!",
"Your account was rejected. Are you signed in?": "您的账号被拒绝。您是否已登录?",
"Your copy of the game has been modified.\nPlease revert any changes and try again.": "你的游戏副本已被更改。\n请恢复任何更改并重试。",
"Your friend code was used by ${ACCOUNT}": "${ACCOUNT}已使用您的好友代码"
"Your copy of the game has been modified.\nPlease revert any changes and try again.": "你的游戏似乎不是原版。\n请删除Mod并使用官方最新版再重试。",
"Your friend code was used by ${ACCOUNT}": "${ACCOUNT}使用了你的分享代码了哦~"
},
"settingNames": {
"1 Minute": "1分钟",
@ -1709,7 +1714,7 @@
"None": "无",
"Normal": "正常",
"Pro Mode": "专业模式",
"Respawn Times": "重生時長",
"Respawn Times": "复活时间",
"Score to Win": "得分取胜",
"Short": "短",
"Shorter": "更短",
@ -1731,21 +1736,21 @@
"tips": {
"A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "一记完美、及时的“跑跳旋转拳”可一次性击杀敌人,并\n助你一生享有好友的尊重。",
"Always remember to floss.": "地面上的辅助线可能会有用。",
"Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "使用首选名称和外观,而非采用随机形式\n来为自己和好友创建玩家档案。",
"Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "诅咒之盒把你变成了一个定时炸弹。\n唯一的解决方法是迅速抢占一个生命值包。",
"Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "请不要总是使用系统提供的随机档案,\n你可以在账户-玩家档案里创建自己的档案喵~",
"Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "诅咒之盒把你变成了一个定时炸弹。\n唯一的解决方法是迅速抢到医疗包。",
"Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "尽管长相不同,所有人物的技能是相同的,\n所以只需随意挑选一个与你最相似的。",
"Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "不要因为拥有能量盾牌而狂妄自大;你仍然可能使自己坠入悬崖。",
"Don't run all the time. Really. You will fall off cliffs.": "不要总是奔跑。真的。你可能会坠入悬崖。",
"Don't spin for too long; you'll become dizzy and fall.": "不要旋转得太久,不然你会眩晕并摔倒。",
"Don't run all the time. Really. You will fall off cliffs.": "不要一直奔跑,真的,你可能会坠入悬崖。",
"Don't spin for too long; you'll become dizzy and fall.": "不要旋转得太久,不然你会傻乎乎地眩晕并摔倒。",
"Hold any button to run. (Trigger buttons work well if you have them)": "按住任意按钮来奔跑。(如果你有的话,扳机按钮将会很有用)",
"Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按钮来奔跑。你将会更快地抵达一些地方,\n但是转弯效果并不好所以当心悬崖。",
"Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "寒冰炸弹并非很厉害,但它们能够冻结\n任何被击中者使他们极易粉碎。",
"If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人将你提起,出拳攻击他们,他们便会放手。\n这在现实生活中同样有效。",
"Hold down any button to run. You'll get places faster\nbut won't turn very well, so watch out for cliffs.": "按住任意按钮来奔跑,比普通行走的速度会快得多。\n但是奔跑时不太好转弯所以当心摔下悬崖。",
"Ice bombs are not very powerful, but they freeze\nwhoever they hit, leaving them vulnerable to shattering.": "冰冻炸弹伤害并不高,但它们能够冻结\n被伤到的人然后他们身体会变得脆弱一碰就碎",
"If someone picks you up, punch them and they'll let go.\nThis works in real life too.": "如果有人把你抓起来了,出拳攻击他们,他们便会放手。\n这在现实生活中同样有效。",
"If you are short on controllers, install the '${REMOTE_APP_NAME}' app\non your mobile devices to use them as controllers.": "如果您缺控制器,可以在手机安装「${REMOTE_APP_NAME}」\n然后手机就可以当作控制器啦~",
"If you are short on controllers, install the 'BombSquad Remote' app\non your iOS or Android devices to use them as controllers.": "如果你没有手柄请在你的iOS或Android设备上安装\n“BombSquad Remote”应用程序并将它们作为手柄使用。",
"If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一个黏黏弹将你困住,你应该四处跳动并转圈。你可能\n将炸弹抖落,或如果没有其他办法,你最后的时刻将是有趣的。",
"If you kill an enemy in one hit you get double points for it.": "如果你一击杀死一个敌人,你将获得双倍分。",
"If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你捡到一个诅咒之盒,你唯一的生存希望是\n在接下来的几秒内找到一个加血包。",
"If you get a sticky-bomb stuck to you, jump around and spin in circles. You might\nshake the bomb off, or if nothing else your last moments will be entertaining.": "如果一个黏黏弹将你困住,你应该四处跳动并转圈。炸弹\n可能被抖落,或如果没有其他办法,你最后的时刻将是有趣的。",
"If you kill an enemy in one hit you get double points for it.": "如果你一击杀死一个敌人,你将获得双倍。",
"If you pick up a curse, your only hope for survival is to\nfind a health powerup in the next few seconds.": "如果你捡到一个诅咒之盒,你唯一的生存希望是\n在接下来的几秒内找到一个医疗包。",
"If you stay in one place, you're toast. Run and dodge to survive..": "如果你停留在一个地方,你就完了。为了生存而奔跑和躲避……",
"If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "如果众多玩家进进出出,在设置下打开“自动踢出闲置玩家”,以防\n任何玩家忘记离开游戏。",
"If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "如果你的设备过热,或者你想要节省电池电量,\n则在设置->图形中调低“视觉效果”或“分辨率”",
@ -1756,13 +1761,13 @@
"Jump just as you're throwing to get bombs up to the highest levels.": "就像你试图将炸弹扔到最高点那样跳起来。",
"Land-mines are a good way to stop speedy enemies.": "地雷是阻止高速敌人的一个很好的方式。",
"Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "很多东西都可以捡起来并投掷,包括其他玩家。将你的\n敌人抛下悬崖可能是一个有效的且情感上可获得满足的策略。",
"No, you can't get up on the ledge. You have to throw bombs.": "不,你不能在岩脊上起身。你必须要投掷炸弹。",
"No, you can't get up on the ledge. You have to throw bombs.": "不,你不能跳上塔台去。你必须要用炸弹炸死塔台上的人。",
"Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "玩家可在大多数游戏中途加入或离开,\n同时你也可以在百忙中插上或拔出手柄。",
"Practice using your momentum to throw bombs more accurately.": "练习借助你的力量更准确地投掷炸弹。",
"Practice using your momentum to throw bombs more accurately.": "多加练习,你的炸弹技能会变得更精准",
"Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "拳头跑得越快,拳击的伤害越高,\n所以请成为飞奔的拳击手吧。",
"Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "在投掷炸弹之前来回跑动,\n以“鞭打”炸弹并将其投掷更远。",
"Take out a group of enemies by\nsetting off a bomb near a TNT box.": "在TNT炸药箱附近引爆\n一个炸弹来消灭一群敌人。",
"The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "头部是最脆弱的区域,所以一个黏黏弹\n接触头部通常便意味着游戏结束。",
"The head is the most vulnerable area, so a sticky-bomb\nto the noggin usually means game-over.": "头部是最脆弱的区域,所以一个黏黏弹\n接触头部通常便意味着一个生命的结束。",
"This level never ends, but a high score here\nwill earn you eternal respect throughout the world.": "这一关卡永远不会结束,但是更高的得分将\n助你赢得全世界永恒的尊重。",
"Throw strength is based on the direction you are holding.\nTo toss something gently in front of you, don't hold any direction.": "投掷力量取决于你所保持的方向。\n如要向前方轻轻投掷某物不要保持在任何方向。",
"Tired of the soundtrack? Replace it with your own!\nSee Settings->Audio->Soundtrack": "更换背景音乐?更换成你自己音乐吧!\n参见设置->音频->背景音乐",

View file

@ -332,6 +332,7 @@
"getMoreGamesText": "獲取更多比賽模式",
"titleText": "新增比賽"
},
"allText": "全部",
"allowText": "允許",
"alreadySignedInText": "你的賬號已在其他設備上登錄\n請退出其他設備的登錄\n然後重試",
"apiVersionErrorText": "無法加載模塊${NAME}它的API版本為${VERSION_USED},我們需要${VERSION_REQUIRED}。",
@ -556,6 +557,7 @@
"disableRemoteAppConnectionsText": "取消Remote應用連接",
"disableXInputDescriptionText": "允許使用四個以上的控制器,但可能不會正常工作",
"disableXInputText": "禁用XInput",
"disabledText": "禁用",
"doneText": "完成",
"drawText": "平局",
"duplicateText": "複製",
@ -623,6 +625,7 @@
"useMusicFolderText": "音樂文件夾"
},
"editText": "修改",
"enabledText": "啓用",
"endText": "結束",
"enjoyText": "盡情享用吧",
"epicDescriptionFilterText": "史詩級慢動作${DESCRIPTION}",
@ -1121,7 +1124,11 @@
"pleaseWaitText": "請稍等....",
"pluginClassLoadErrorText": "加載插件類'${PLUGIN}'時出錯:${ERROR}",
"pluginInitErrorText": "初始化插件'${PLUGIN}'時出錯:${ERROR}",
"pluginSettingsText": "插件設置",
"pluginsAutoEnableNewText": "自動啟用新插件",
"pluginsDetectedText": "檢測到新插件。重新啓動以激活,或在設置中配置這些插件",
"pluginsDisableAllText": "禁用所有插件",
"pluginsEnableAllText": "啟用所有插件",
"pluginsRemovedText": "${NUM}個插件已丟失",
"pluginsText": "外掛程式",
"practiceText": "練習",
@ -1212,7 +1219,9 @@
"revertText": "還原",
"runText": "運行",
"saveText": "保存",
"scanScriptsErrorText": "掃描腳本時存在錯誤,查看錯誤日誌來了解詳情",
"scanScriptsErrorText": "錯誤掃描腳本。 有關詳細信息,請參閱日誌。",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} 和 ${NUM} 個其他模塊需要針對 api ${API} 進行更新。",
"scanScriptsSingleModuleNeedsUpdatesText": "需要為 api ${API} 更新 ${PATH}。",
"scoreChallengesText": "得分挑戰",
"scoreListUnavailableText": "得分列表不可用",
"scoreText": "得分",
@ -1256,6 +1265,7 @@
"netTestingText": "網絡連接測試",
"resetText": "恢復默認",
"showBombTrajectoriesText": "顯示炸彈軌跡",
"showInGamePingText": "顯示遊戲內延遲",
"showPlayerNamesText": "顯示玩家名稱",
"showUserModsText": "顯示MOD安裝文件夾",
"titleText": "高級設置",

View file

@ -8,6 +8,7 @@
"changeOncePerSeason": "Ovo možeš promjeniti samo jednom po sezoni.",
"changeOncePerSeasonError": "Moraš pričekati sljedeču sezonu da promjeniš ovo(${NUM} days)",
"customName": "Prilagođeno ime",
"googlePlayGamesAccountSwitchText": "Ako želite koristiti drugi Google račun,\nidite u aplikaciju Google Play Igre za promijeniti račun.",
"linkAccountsEnterCodeText": "Unesi kod",
"linkAccountsGenerateCodeText": "Stvori kod",
"linkAccountsInfoText": "(podijeli napredak na svim platformama)",
@ -15,6 +16,7 @@
"linkAccountsInstructionsText": "Da povežeš dva profila, stvori kod na \njednomod njih i unesi ga na drugom.\nNapredak i sve kupljeno bit će kombinirano.\nMožeš povezati najviše ${COUNT} profila.",
"linkAccountsText": "Poveži profile",
"linkedAccountsText": "Povezani računi:",
"manageAccountText": "Kontroliraj Račun",
"nameChangeConfirm": "Promjeni svoje ime u ${NAME}?",
"resetProgressConfirmNoAchievementsText": "Ovo će poništiti tvoj napredak u timskom modu i\ntvoje najbolje rezultate (ali ne i tvoje kupone).\nNemaš mogućnost povratka. Jesi li siguran?",
"resetProgressConfirmText": "Ovo će poništiti tvoj napredak u timskom modu,\npostignuća, i vaše najbolje rezultate\n(ali ne i tvoje kupone). Nemaš mogućnost\npovratka. Jesi li siguran?",
@ -41,6 +43,7 @@
"titleText": "Račun",
"unlinkAccountsInstructionsText": "Odaberi račun za prekid veze.",
"unlinkAccountsText": "Prekini vezu računa",
"unlinkLegacyV1AccountsText": "Odveži Stare (V1) Račune",
"v2LinkInstructionsText": "Koristite ovu vezu za kreiranje računa ili prijavu.",
"viaAccount": "(Preko ${NAME} računa)",
"youAreSignedInAsText": "Prijavljeni ste kao:"
@ -334,6 +337,7 @@
"getMoreGamesText": "Još igara...",
"titleText": "Dodaj igru"
},
"allText": "Sve",
"allowText": "Dopusti",
"alreadySignedInText": "Tvoj akaunt je prijavljen sa drugog uredjaja;\nmolimo promenite akaunt ili zatvori igru na\ntvom drugom uredjaju i probaj opet.",
"apiVersionErrorText": "Nemoguće je učitati modul ${NAME}; napravljen je za ${VERSION_USED} verziju aplikacije; potrebna je verzija ${VERSION_REQUIRED}.",
@ -501,6 +505,7 @@
"welcome2Text": "Možeš zarađivati kupone raznim aktivnostima.\nKupone možeš koristiti za otključavanje novih likova, mapa, i\nigara, ulaženje u turnire, i puno više.",
"yourPowerRankingText": "Tvoja pozicija"
},
"copyConfirmText": "Kopirano na međuspremnik.",
"copyOfText": "Kopija ${NAME}",
"copyText": "Kopirati",
"createEditPlayerText": "<Napravi/Uredi Igrača>",
@ -547,7 +552,9 @@
"deleteText": "Izbriši",
"demoText": "Demo",
"denyText": "Odbij",
"deprecatedText": "Zastareno",
"desktopResText": "Desktop rezolucija",
"deviceAccountUpgradeText": "Upozorenje:\nPrijavljeni ste s uređajnim računom\n(${NAME}).\nUređajni računi će biti izbrisani u budućem ažuriranju.",
"difficultyEasyText": "Lagano",
"difficultyHardOnlyText": "Samo u teškom modu",
"difficultyHardText": "Teško",
@ -556,6 +563,7 @@
"disableRemoteAppConnectionsText": "Isključi konekciju Remote-aplikacije",
"disableXInputDescriptionText": "Dozvoljava više od 4 kontrolera ali možda neće raditi dobro.",
"disableXInputText": "Isključi XInput",
"disabledText": "Deaktiviraj",
"doneText": "Gotovo",
"drawText": "Neriješeno",
"duplicateText": "Dupliciraj",
@ -624,12 +632,15 @@
"useMusicFolderText": "Mapa s Glazbenim Datotekama"
},
"editText": "Izmjeni",
"enabledText": "Aktiviraj",
"endText": "Kraj",
"enjoyText": "Uživaj",
"epicDescriptionFilterText": "${DESCRIPTION} U epskom usporenom filmu.",
"epicNameFilterText": "${NAME} (epski mod)",
"errorAccessDeniedText": "pristup zabranjen",
"errorDeviceTimeIncorrectText": "Vrijeme vašeg uređaja je krivo za ${HOURS} sati.\nOvo će stvarati probleme.\nMolimo provjerite vaše postavke vremena i vremenske zone.",
"errorOutOfDiskSpaceText": "nema prostora na disku",
"errorSecureConnectionFailText": "Nije moguće uspostaviti sigurnu vezu; internetska funkcionalnost može ne uspjeti.",
"errorText": "Greška",
"errorUnknownText": "nepoznata greška",
"exitGameText": "Izlaz iz ${APP_NAME}?",
@ -794,7 +805,7 @@
"ticketPack4Text": "Jumbo paket kupona",
"ticketPack5Text": "Mamutski paket kupona",
"ticketPack6Text": "Ultimativni paket kupona",
"ticketsFromASponsorText": "Dobij ${COUNT} kupona\nod sponzora",
"ticketsFromASponsorText": "Pogledaj reklamu\nza ${COUNT} kupona",
"ticketsText": "${COUNT} kupona",
"titleText": "Zaradi kupone",
"unavailableLinkAccountText": "Nažalost, kupovina nije dostupna na ovoj platformi.\nKao zaobilazno rješenje, možete povezati račun s računom na \ndrugoj platformi i tamo nastaviti kupovinu.",
@ -805,6 +816,8 @@
"youHaveText": "imaš ${COUNT} kupona"
},
"googleMultiplayerDiscontinuedText": "Oprostite, Google Play Games servis za partije u igrama više ne postoji.\nTrenutno radim na zamjeni što je brže moguće.\nTo tada, priključujte se u partije na druge načine.\n-Eric",
"googlePlayPurchasesNotAvailableText": "Google Play kupnje nisu dostupne.\nMožda ćete trebati ažurirati svoju trgovinu aplikacija.",
"googlePlayServicesNotAvailableText": "Google Play Services nije dostupan.\nNeke funkcionalnosti aplikacije mogu biti isključene.",
"googlePlayText": "Google Play",
"graphicsSettingsWindow": {
"alwaysText": "Uvijek",
@ -1003,6 +1016,7 @@
"creditsText": "Zasluge",
"demoMenuText": "Demo izbornik",
"endGameText": "Kraj igre",
"endTestText": "Završi Test",
"exitGameText": "Izlaz iz igre",
"exitToMenuText": "Povratak u izbornik?",
"howToPlayText": "Kako igrati",
@ -1022,6 +1036,7 @@
"maxConnectionsText": "Maksimalna konekcija",
"maxPartySizeText": "Maksimum veličine žurke",
"maxPlayersText": "Maksimum igrača",
"merchText": "Roba!",
"modeArcadeText": "Arkadni Mod",
"modeClassicText": "Klasični Mod",
"modeDemoText": "Demo Mod",
@ -1062,6 +1077,7 @@
"notSignedInErrorText": "Moraš se prijaviti da uradiš ovo.",
"notSignedInGooglePlayErrorText": "Moraš se ulogovati preko Google pleja da uradiš ovo.",
"notSignedInText": "nisi prijavljen",
"notUsingAccountText": "Bilješka: ignoriranje ${SERVICE} račun.\nIdite u 'Račun -> Prijavite se s ${SERVICE} ako ga želite koristiti.",
"nothingIsSelectedErrorText": "Ništa nije odabrano!",
"numberText": "#${NUMBER}",
"offText": "Isključeno",
@ -1120,7 +1136,11 @@
"pleaseWaitText": "Molimo sačekajte...",
"pluginClassLoadErrorText": "Pogreška učitavanja dodatka klase '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Pogreška iniciranja dodatka '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "Postavke Dodataka",
"pluginsAutoEnableNewText": "Automatski Uključi Nove Dodatke",
"pluginsDetectedText": "Novi dodatak(ci) detektiran(i) Resetiraj da ih ukljućiš ili ih konfiguriraj u postavkima",
"pluginsDisableAllText": "Isključi Sve Dodatke",
"pluginsEnableAllText": "Uključi Sve Dodatke",
"pluginsRemovedText": "${NUM} dodatak/ci više nisu pronađeni.",
"pluginsText": "Dodatci",
"practiceText": "Vježba",
@ -1212,7 +1232,7 @@
"revertText": "Poništi",
"runText": "Trk",
"saveText": "Spremi",
"scanScriptsErrorText": "Greška(e) skeniranja skripra; provjerite dnevnik za detalje.",
"scanScriptsErrorText": "Greška(e) skeniranja skripta. Provjerite dnevnik za detalje",
"scoreChallengesText": "Izazovi za rezultat",
"scoreListUnavailableText": "Lista s rezultatima nedostupna.",
"scoreText": "Rezultat",
@ -1257,6 +1277,7 @@
"netTestingText": "Testiranje mreže",
"resetText": "Poništi",
"showBombTrajectoriesText": "Pokaži putanju bombe",
"showInGamePingText": "Prikaži Ping",
"showPlayerNamesText": "Pokaži imena igrača",
"showUserModsText": "Pokaži mapu za modove",
"titleText": "Napredno",
@ -1377,6 +1398,7 @@
"tournamentStandingsText": "Poredak",
"tournamentText": "Turnir",
"tournamentTimeExpiredText": "Vrijeme turnira je isteklo",
"tournamentsDisabledWorkspaceText": "Turnamenti su deaktivirani kad su radni prostori upaljeni.\nDa re-aktiviraš turnamente, ugasi svoj radni prostor i resetiraj.",
"tournamentsText": "Turniri",
"translations": {
"characterNames": {
@ -1529,6 +1551,7 @@
"Italian": "Talijanski",
"Japanese": "Japanski",
"Korean": "Korejski",
"Malay": "Malajski",
"Persian": "Perzijski",
"Polish": "Poljski",
"Portuguese": "Portugalski",
@ -1812,6 +1835,7 @@
"usesExternalControllerText": "Ova igra koristi vanjski kontroler za kretanje.",
"usingItunesText": "Koristim glazbenu aplikaciju za glazbenu listu...",
"usingItunesTurnRepeatAndShuffleOnText": "Molim provjeri da je opcija shuffle uključena, a opcija repeat postavljena na SVE na iTunes. ",
"v2AccountLinkingInfoText": "Za povezivanje V2 računa, korist 'Upravlaj računima' botun",
"validatingTestBuildText": "Potvrđujem testnu verziju...",
"victoryText": "Pobjeda!",
"voteDelayText": "Nemožeš započeti još jedno glasanje ${NUMBER} sekundi",
@ -1844,6 +1868,7 @@
},
"waveText": "Nalet",
"wellSureText": "Sigurno!",
"whatIsThisText": "Što je ovo?",
"wiimoteLicenseWindow": {
"titleText": "DarwiinRemote Copyright"
},

File diff suppressed because it is too large Load diff

View file

@ -332,6 +332,7 @@
"getMoreGamesText": "Get More Games...",
"titleText": "Add Game"
},
"allText": "All",
"allowText": "Allow",
"alreadySignedInText": "Your account is signed in from another device;\nplease switch accounts or close the game on your\nother devices and try again.",
"apiVersionErrorText": "Can't load module ${NAME}; it targets api-version ${VERSION_USED}; we require ${VERSION_REQUIRED}.",
@ -558,6 +559,7 @@
"disableRemoteAppConnectionsText": "Disable Remote-App Connections",
"disableXInputDescriptionText": "Allows more than 4 controllers but may not work as well.",
"disableXInputText": "Disable XInput",
"disabledText": "Disabled",
"doneText": "Done",
"drawText": "Draw",
"duplicateText": "Duplicate",
@ -625,6 +627,7 @@
"useMusicFolderText": "Folder of Music Files"
},
"editText": "Edit",
"enabledText": "Enabled",
"endText": "End",
"enjoyText": "Enjoy!",
"epicDescriptionFilterText": "${DESCRIPTION} In epic slow motion.",
@ -1227,7 +1230,9 @@
"revertText": "Revert",
"runText": "Run",
"saveText": "Save",
"scanScriptsErrorText": "Error(s) scanning scripts; see log for details.",
"scanScriptsErrorText": "Error(s) scanning scripts. See log for details.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} and ${NUM} other module(s) need to be updated for api ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} needs to be updated for api ${API}.",
"scoreChallengesText": "Score Challenges",
"scoreListUnavailableText": "Score list unavailable.",
"scoreText": "Score",

View file

@ -333,6 +333,7 @@
"getMoreGamesText": "Kukuha ng higit pang mga laro…",
"titleText": "Magdagdag Ng Laro"
},
"allText": "Lahat",
"allowText": "Payagan",
"alreadySignedInText": "Ang iyong account ay naka-sign in mula sa isa pang device;\nMangyaring lumipat ng mga accounts o isara ang laro sa iyong\niba pang mga device at subukan muli.",
"apiVersionErrorText": "Hindi ma-load ang module ${NAME}; naka-target ang api-version ${VERSION_USED}; kailangan namin ${VERSION_REQUIRED}",
@ -558,6 +559,7 @@
"disableRemoteAppConnectionsText": "I-disable Ang Mga Remote-App Na Konekyson",
"disableXInputDescriptionText": "Pumayag ng higit sa 4 na controllers ngunit maaaring hindi mabuti ang kalagay",
"disableXInputText": "Disable XInput",
"disabledText": "Naka-disabled",
"doneText": "Tapos",
"drawText": "Patas",
"duplicateText": "I-duplicate",
@ -625,6 +627,7 @@
"useMusicFolderText": "Folder Ng Mga File Ng Musika"
},
"editText": "I-edit",
"enabledText": "Nakagana",
"endText": "Itigil",
"enjoyText": "Ikasiya!",
"epicDescriptionFilterText": "${DESCRIPTION} sa isang epic na slow motion.",
@ -1126,7 +1129,11 @@
"pleaseWaitText": "Hintay lang…",
"pluginClassLoadErrorText": "Error sa paglo-load ang '${PLUGIN}' na klaseng plugin : ${ERROR}",
"pluginInitErrorText": "Error sa pagsisimula ang '${PLUGIN}' na plugin: ${ERROR}",
"pluginSettingsText": "Settings ng mga Plugins",
"pluginsAutoEnableNewText": "Paganahin ang Bagong Plugins",
"pluginsDetectedText": "May nakitang bagong (mga) plugin. I-restart para i-activate ang mga ito, o i-configure ang mga ito sa mga setting.",
"pluginsDisableAllText": "Di-Paganahin ang mga Plugins",
"pluginsEnableAllText": "Paganahin Lahat ng mga Plugins",
"pluginsRemovedText": "Hindi na nahanapan ang ${NUM} ng (mga) plugin.",
"pluginsText": "Mga Plugin",
"practiceText": "Pagsasagawa",
@ -1217,7 +1224,9 @@
"revertText": "Ibalik",
"runText": "Takbo",
"saveText": "I-save",
"scanScriptsErrorText": "(Mga) error sa pag-scan ng mga script; tingnan ang log para sa mga detalye.",
"scanScriptsErrorText": "(Mga) error sa pag-scan ng mga script; Tignan ang log para sa mga detalye.",
"scanScriptsMultipleModulesNeedUpdatesText": "Kailangan maibago para sa API ${API} ang ${PATH} at mga ${NUM} na iba pang modules.",
"scanScriptsSingleModuleNeedsUpdatesText": "Kailangan maibago para sa api ${API} ang ${PATH}.",
"scoreChallengesText": "Mga Hamon sa Iskor",
"scoreListUnavailableText": "Hindi available ang listahan ng iskor",
"scoreText": "Iskor",
@ -1261,6 +1270,7 @@
"netTestingText": "Pagsusuri ng Network",
"resetText": "I-reset",
"showBombTrajectoriesText": "Ipakita ang Mga Trajectory ng Bomba",
"showInGamePingText": "Ipakita ang In-Game Ping",
"showPlayerNamesText": "Ipakita ang Mga Pangalan ng Manlalaro",
"showUserModsText": "Ipakita ang Mods Folder",
"titleText": "Advanced",

View file

@ -1189,7 +1189,11 @@
"pleaseWaitText": "Veuillez patienter...",
"pluginClassLoadErrorText": "Une erreur est survenue en chargeant la classe de plugins '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Une erreur est survenue en démarrant le plugin '${PLUGIN}' : ${ERROR}",
"pluginSettingsText": "Paramètres Des Plugins",
"pluginsAutoEnableNewText": "Activer Automatiquement Les Nouveaux Plugins",
"pluginsDetectedText": "Nouveaux plugins détectés. Redémarrez l'application pour les activer, ou configurez-les dans les paramètres.",
"pluginsDisableAllText": "Désactiver Tous Les Plugins",
"pluginsEnableAllText": "Activer Tous Les Plugins",
"pluginsRemovedText": "${NUM} plugin(s) ne sont plus disponibles.",
"pluginsText": "Plugins",
"practiceText": "Entraînement",
@ -1285,7 +1289,7 @@
"runBoldText": "COURIR",
"runText": "Courir",
"saveText": "Sauvegarder",
"scanScriptsErrorText": "Erreur(s) dans les scripts; voir journal pour détails.",
"scanScriptsErrorText": "Erreur(s) dans les scripts. Consulter le journal pour plus de détails.",
"scoreChallengesText": "Défis de Score",
"scoreListUnavailableText": "Liste des scores indisponible.",
"scoreText": "Score",
@ -1331,6 +1335,7 @@
"netTestingText": "Tester Votre Réseau",
"resetText": "Réinitialiser",
"showBombTrajectoriesText": "Montrer les trajectoires de bombe",
"showInGamePingText": "Afficher La Latence En Jeu",
"showPlayerNamesText": "Montrer les Noms des Joueurs",
"showUserModsText": "Montrer le Dossier des Mods",
"titleText": "Avancé",

View file

@ -340,6 +340,7 @@
"titleText": "Spiel hinzufügen",
"titleTextScale": 1.0
},
"allText": "Alle",
"allowText": "Erlauben",
"alreadySignedInText": "Dein Account wird schon von einem anderen Gerät verwendet;\nbitte wechsle den Account oder schließe das Spiel auf\ndeinem anderen Gerät und versuche es nochmal.",
"apiVersionErrorText": "Das Modul ${NAME} kann nicht geladen werden. Es benutzt API-Version ${VERSION_USED}, aber wir brauchen ${VERSION_REQUIRED}.",
@ -509,7 +510,7 @@
"powerRankingPointsToRankedText": "(${CURRENT} von ${REMAINING} pkte)",
"powerRankingText": "Power Rang",
"prizesText": "Preise",
"proMultInfoText": "Spieler mit dem ${PRO} Upgrade\nbekommen zu ${PERCENT}% mehr Punkte hier.",
"proMultInfoText": "Spieler mit dem ${PRO} Upgrade\nbekommen ${PERCENT}% Bonuspunkte.",
"seeMoreText": "Sieh weitere...",
"skipWaitText": "Überspringen",
"timeRemainingText": "Übrige Zeit",
@ -587,6 +588,7 @@
"disableRemoteAppConnectionsText": "Remote-App Verbindungen verbieten",
"disableXInputDescriptionText": "Erlaubt mehr als 4 Controller aber kann schlechter funktionieren.",
"disableXInputText": "XInput deaktivieren",
"disabledText": "Deaktiviert",
"doneText": "Fertig",
"drawText": "Unentschieden",
"duplicateText": "dublizieren",
@ -660,6 +662,7 @@
"useMusicFolderText": "Ordner mit Musikdateien"
},
"editText": "bearbeiten",
"enabledText": "Atkiviert",
"endText": "Ende",
"enjoyText": "Viel Spaß!",
"epicDescriptionFilterText": "${DESCRIPTION} In epischer Zeitlupe.",
@ -1308,7 +1311,9 @@
"revertText": "Zurücksetzen",
"runText": "Rennen",
"saveText": "Speichern",
"scanScriptsErrorText": "Fehler beim scannen der Skripts; sehe Protokoll für Details.",
"scanScriptsErrorText": "Fehler beim Scannen der Skripts; siehe Protokoll für Details.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} und ${NUM} weitere(s) Modul(e) muss an API ${API} angepasst werden.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} muss an API ${API} angepasst werden.",
"scoreChallengesText": "Punkte Herausforderungen",
"scoreListUnavailableText": "Bestenliste ist nicht verfügbar",
"scoreText": "Punkte",

View file

@ -342,6 +342,7 @@
"titleText": "Ádzd Gámzé",
"titleTextScale": 1.01
},
"allText": "Alcllwerf",
"allowText": "Alzéow",
"alreadySignedInText": "Yr co wcowief woeijo wife ewf;\norc woeful oj ceofjwoejfowief\nocjwoef weofwocijweofw.",
"apiVersionErrorText": "Cznt lzdz mdls ${NAME}; zt tarng faptr ${VERSION_USED}; wz rojafoqrz ${VERSION_REQUIRED}.",
@ -589,6 +590,7 @@
"disableRemoteAppConnectionsText": "Disojf c woij ewof-app cowjf woejwe",
"disableXInputDescriptionText": "Allow mor wow ejo4 cow oeicjwo cobu oaf woejfowie jowrj",
"disableXInputText": "Dio cow eofwije",
"disabledText": "Dfewfczfwef",
"doneText": "Dónz",
"drawText": "Drawz",
"duplicateText": "DSFcoiwjef",
@ -662,6 +664,7 @@
"useMusicFolderText": "Fldlzr ofz Mzlfic Flzlz"
},
"editText": "Edf",
"enabledText": "Efweecwef",
"endText": "Enzf",
"enjoyText": "Enfjofjw!",
"epicDescriptionFilterText": "${DESCRIPTION} Ín ípic slúw mztíon.",
@ -1318,6 +1321,8 @@
"runText": "Rúun",
"saveText": "Sávez",
"scanScriptsErrorText": "Error(w) frolic weir ro; cj weowje ici woeijwer.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} dfsf ${NUM} w woeifjw fwjef webd weoifjwoef ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} fwejfwjef weoifjwefffefwwef ${API}.",
"scoreChallengesText": "Scóre Chálléngúz",
"scoreListUnavailableText": "Sczerl lzst unvnslfljblz.",
"scoreText": "Szóre",

View file

@ -39,6 +39,7 @@
"titleText": "Λογαριασμός",
"unlinkAccountsInstructionsText": "Επιλέξτε έναν λογαριασμό για αποδέσμευση",
"unlinkAccountsText": "Αποδέσμευση Λογαριασμών",
"unlinkLegacyV1AccountsText": "Αποδέσμευση Παλιών (V1) Λογαριασμών",
"v2LinkInstructionsText": "Χρησημοποιήστε αυτόν τον σύνδεσμο για να δημιουργήσετε έναν λογαριασμό ή για να συνδεθείτε.",
"viaAccount": "(μέσω λογαριασμού ${NAME})",
"youAreSignedInAsText": "Είστε συνδεδεμένοι ως:"
@ -1027,6 +1028,7 @@
"maxConnectionsText": "Μέγιστος Αριθμός Συνδέσεων",
"maxPartySizeText": "Μέγιστος Αριθμός Συγκέντρωσης",
"maxPlayersText": "Μέγιστος Αριθμός Παικτών",
"merchText": "Εμπόρευμα!",
"modeArcadeText": "Λειτουργία \"Arcade\"",
"modeClassicText": "Κλασσική λειτουργία",
"modeDemoText": "Δοκιμαστική λειτουργία",
@ -1125,7 +1127,11 @@
"pleaseWaitText": "Παρακαλώ περιμένετε...",
"pluginClassLoadErrorText": "Σφάλμα φορτώνοντας πρόσθετο '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Σφάλμα επερξεγάζοντας πρόσθετο '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "συνδέω Ρυθμίσεις",
"pluginsAutoEnableNewText": "Αυτόματη ενεργοποίηση νέων προσθηκών",
"pluginsDetectedText": "Νέα πρόσθετο/α εντοπίστηκαν. Επανεκκινήστε την εφαρμογή για να τα ενεργοποιήσετε, ή διαμορφώστε τα στις ρυθμίσεις.",
"pluginsDisableAllText": "Απενεργοποίηση όλων των προσθηκών",
"pluginsEnableAllText": "Ενεργοποίηση όλων των προσθέτων",
"pluginsRemovedText": "${NUM} πρόσθετο/α δεν εντοπίζονται πια.",
"pluginsText": "Πρόσθετα",
"practiceText": "Πρακτική",
@ -1218,7 +1224,7 @@
"revertText": "Επαναφορά",
"runText": "Τρέξιμο",
"saveText": "Αποθήκευση",
"scanScriptsErrorText": "Σφάλματα σάρωσης σάρωσης; δείτε το αρχείο καταγραφής για λεπτομέρειες.",
"scanScriptsErrorText": "Σφάλμα(α) κατά τη σάρωση σεναρίων. Δείτε το αρχείο καταγραφής για λεπτομέρειες.",
"scoreChallengesText": "Προκλήσεις Βαθμολογίας",
"scoreListUnavailableText": "Λίστα βαθμολογίας μη διαθέσιμη.",
"scoreText": "Βαθμολογία",
@ -1262,6 +1268,7 @@
"netTestingText": "Έλεγχος Δικτύου",
"resetText": "Επαναφορά",
"showBombTrajectoriesText": "Εμφάνιση Πορείας Βόμβας",
"showInGamePingText": "Εμφάνιση Καθυστέρησης Εντός-Παιχνιδιού",
"showPlayerNamesText": "Προβολή Ονομάτων Παικτών",
"showUserModsText": "Προβολή Φακέλου Πακέτων Τροποποίησης",
"titleText": "Σύνθετες",
@ -1532,6 +1539,7 @@
"Italian": "Ιταλικά",
"Japanese": "Ιαπωνέζικα",
"Korean": "Κορεάτικα",
"Malay": "Μαλεσιακά",
"Persian": "Πέρσικα",
"Polish": "Πολωνικά",
"Portuguese": "Πορτογαλικά",

View file

@ -43,6 +43,7 @@
"titleText": "खाता",
"unlinkAccountsInstructionsText": "अनलिंक करने के लिए एक खाता चुनें",
"unlinkAccountsText": "खाते अनलिंक करें",
"unlinkLegacyV1AccountsText": "लैगेसी (V1) खाते को एनलिंक करे",
"v2LinkInstructionsText": "खाता बनाने या साइन इन करने के लिए इस लिंक का उपयोग करें।",
"viaAccount": "(खाता ${NAME} के माध्यम से)",
"youAreSignedInAsText": "आप इस खाते से साइनड इन हो: "
@ -1031,6 +1032,7 @@
"maxConnectionsText": "अधिकतम कनेक्शन",
"maxPartySizeText": "अधिकतम पार्टी का आकार",
"maxPlayersText": "अधिकतम खिलाड़ी",
"merchText": "मर्च!",
"modeArcadeText": "आर्केड मोड",
"modeClassicText": "क्लासिक मोड",
"modeDemoText": "डेमो मोड",
@ -1130,7 +1132,11 @@
"pleaseWaitText": "कृपया प्रतीक्षा करें...",
"pluginClassLoadErrorText": "प्लगइन क्लास '${PLUGIN}' लोड करने में त्रुटि: ${ERROR}",
"pluginInitErrorText": "प्लगइन '${PLUGIN}' शुरुआत करने में त्रुटि: ${ERROR}",
"pluginSettingsText": "प्लगइन सेटिंग्स",
"pluginsAutoEnableNewText": "ऑटो सक्षम नया प्लगइन",
"pluginsDetectedText": "नए प्लगइन्स पता चले। उन्हें सक्रिय करने के लिए पुनरारंभ करें, या उन्हें सेटिंग्स में कॉन्फ़िगर करें।",
"pluginsDisableAllText": "सभी प्लगइन्स को अक्षम करें",
"pluginsEnableAllText": "सभी प्लगइन्स सक्षम करें",
"pluginsRemovedText": "${NUM} प्लगइन्स अब नहीं मिले।",
"pluginsText": "प्लगइन्स",
"practiceText": "अभ्यास",
@ -1222,7 +1228,7 @@
"revertText": "पूर्व स्तिथि में लायें",
"runText": "दोडें",
"saveText": "सुरक्षित करें",
"scanScriptsErrorText": "स्क्रिप्ट्स को स्कैन करने में त्रुटि; विवरण के लिए लॉग देखें।",
"scanScriptsErrorText": "स्क्रिप्ट्स स्कैन करने में गलती; विवरण के लिए लॉग देखें।",
"scoreChallengesText": "अंकों कि चुनौतियाँ",
"scoreListUnavailableText": "अंकों कि सूचि अभी उपस्थित नहीं है",
"scoreText": "अंक",
@ -1266,6 +1272,7 @@
"netTestingText": "नेटवर्क पर परीक्षण",
"resetText": "रीसेट",
"showBombTrajectoriesText": "बोम्ब का पथ दिखाएँ",
"showInGamePingText": "गेम पिंग में दिखाएं",
"showPlayerNamesText": "खिलाड़ी का नाम दिखाएँ",
"showUserModsText": "परिवर्तनों का फोल्डर दिखाएँ",
"titleText": "उन्नत",
@ -1536,6 +1543,7 @@
"Italian": "इतालवी",
"Japanese": "जापानी",
"Korean": "कोरियाई",
"Malay": "मलय",
"Persian": "फ़ारसी",
"Polish": "पोलिश",
"Portuguese": "पुर्तगाली",

View file

@ -9,10 +9,11 @@
"changeOncePerSeasonError": "Várj a következő szezonig, hogy ezt megint megváltoztasd (${NUM} nap)",
"customName": "Egyedi név",
"deviceSpecificAccountText": "Csak erről az eszközről lehet elérni ezt a profilt: ${NAME}",
"googlePlayGamesAccountSwitchText": "Ha másik Google fiókot használnál, használd a Google Játékok alkalmazást.",
"linkAccountsEnterCodeText": "Írd Be A Kódot",
"linkAccountsGenerateCodeText": "Kód Generálása",
"linkAccountsInfoText": "(vidd át előrehaladásodat akár több eszközre is)",
"linkAccountsInstructionsNewText": "Két fiók összekapcsolásához először hozzon létre egy kódot\nés írja be a második kódot. Adatok a\na második számlát majd megosztják egymással.\n(Az első fiókból származó adatok elveszhetnek)\n\nÖsszesen akár ${COUNT} fiókot is összekapcsolhat.\n\nFONTOS: csak az Ön tulajdonában lévő fiókokat kapcsolja össze;\nHa kapcsolatba lépsz a barátok fiókjaival, akkor nem fogsz\negyszerre tud online játszani.",
"linkAccountsInstructionsNewText": "Két fiók összekapcsolásához az első fiókon hozz létre egy kódot\nés írd be a második fiókba. Az adatok a\na második fiókon majd megosztják egymással.\n(Az első fiókból származó adatok elveszhetnek)\n\nÖsszesen akár ${COUNT} fiókot is összekapcsolhat.\n\nFONTOS:\nCsak a tulajdonodban lévő fiókokat kapcsold össze;\nHa összekapcsolsz egyet az egyik barátodéval, nem fogtok tudni egyszerre online játszani.",
"linkAccountsInstructionsText": "Hogy párosíts két profilt, generálj egy kódot\naz egyiken majd írd be a kapott kódot a másikon.\nAz előrehaladás és a megvásárolt dolgok is párosításra kerülnek .\nÖsszesen ${COUNT} profilt tudsz összehangolni.\n\nFONTOS:Csak olyan profilt csatlakoztass ami a tiéd!\nHogyha profilt csatlakoztatsz a barátaiddal\nakkor nem fogsz tudni játszani azonos időben!\n\nLégy óvatos!Ezt a lépést nem lehet visszavonni!",
"linkAccountsText": "Profilok Párosítása",
"linkedAccountsText": "Párosított Profilok:",
@ -43,9 +44,10 @@
"titleText": "Felhasználó",
"unlinkAccountsInstructionsText": "Válassz ki egy fiókot a leválasztáshoz",
"unlinkAccountsText": "Fiókok leválasztása",
"v2LinkInstructionsText": "Használja ezt a linket fiók létrehozásához vagy bejelentkezéshez.",
"unlinkLegacyV1AccountsText": "(V1) fiókok lecsatolása",
"v2LinkInstructionsText": "Használd ezt a linket fiók létrehozásához vagy bejelentkezéshez.",
"viaAccount": "(számlán keresztül ${NAME})",
"youAreSignedInAsText": "Be vagy jelentkezve, mint:"
"youAreSignedInAsText": "Eként vagy bejelentkezve:"
},
"achievementChallengesText": "Teljesítmény kihívások",
"achievementText": "Teljesítmény",
@ -187,7 +189,7 @@
"Pro Football Victory": {
"description": "Nyerd meg a játékot",
"descriptionComplete": "Megnyerted a játékot",
"descriptionFull": "Nyerdmeg a játékot a(z) ${LEVEL} pályán",
"descriptionFull": "Nyerd meg a játékot a(z) ${LEVEL} pályán",
"descriptionFullComplete": "Megnyerted a játékot a(z) ${LEVEL} pályán",
"name": "${LEVEL} Győzelem"
},
@ -254,7 +256,7 @@
},
"Stayin' Alive": {
"description": "Nyerj halál nélkül",
"descriptionComplete": "Nyerj anélkül hogy meghalnál.",
"descriptionComplete": "Nyertél anélkül, hogy meghalnál.",
"descriptionFull": "Nyerd meg a ${LEVEL} pályát halál nélkül",
"descriptionFullComplete": "${LEVEL} pálya megnyerve halál nélkül",
"name": "Maradj életben!"
@ -336,6 +338,7 @@
"getMoreGamesText": "Több Játékmód...",
"titleText": "Játék Hozzáadása"
},
"allText": "Minden",
"allowText": "Engedélyezés",
"alreadySignedInText": "A fiókoddal be vagy jelentkezve egy másik eszközről;\nkérlek cserélj fiókot vagy zárd be a játékot \na másik eszközön és próbáld újra",
"apiVersionErrorText": "Nem lehet betölteni a ${NAME} modult jelenlegi verzió:${VERSION_USED}; szükséges verió:${VERSION_REQUIRED}.",
@ -435,7 +438,7 @@
"keyboard2NoteText": "A legtöbb billentyűzet csak pár gombnyomást érzékel egyszerre,\nszóval jobb ha használtok két játékos esetén jobb, \nhogy ha egy második billentyűzetet is használtok.\nFontos, hogy ebben az esetben is be kell állítani \naz egyéni vezérlést."
},
"configTouchscreenWindow": {
"actionControlScaleText": "Akció Panel Átmérőja",
"actionControlScaleText": "Akció Panel Átmérője",
"actionsText": "Akciók",
"buttonsText": "gombok",
"dragControlsText": "<tartsd lenyomva a paneleket ,hogy elmozgathasd>",
@ -549,7 +552,9 @@
"deleteText": "Törlés",
"demoText": "Demo",
"denyText": "Megtagad",
"deprecatedText": "Elavult",
"desktopResText": "Asztali Felbontás",
"deviceAccountUpgradeText": "Hé!\nEgy eszközfiókkal vagy bejelentkezve (${NAME}). Egy jövőbeli frissítésben az ezeket az eszközfiókokat eltávolítjuk.\nFejleszd fiókod V2-es fiókra ha meg szeretnéd tartani a haladásod és a többi cuccaidat.\n.",
"difficultyEasyText": "Könnyű",
"difficultyHardOnlyText": "Csak Nehéz Mód",
"difficultyHardText": "Nehéz",
@ -558,6 +563,7 @@
"disableRemoteAppConnectionsText": "Irányító Alkalmazások Letiltása",
"disableXInputDescriptionText": "Engedélyezi ,hogy 4-nél több kontroller is csatlakozhasson ,viszont nem biztos a hibátlan működés.",
"disableXInputText": "XInput kikapcsolása",
"disabledText": "Kikapcsolva",
"doneText": "Elvégezve",
"drawText": "Döntetlen",
"duplicateText": "Másolás",
@ -582,7 +588,7 @@
"checkingAvailabilityText": "\"${NAME}\" név ellenőrzése...",
"colorText": "szín",
"getMoreCharactersText": "Több Karakter Szerzése...",
"getMoreIconsText": "Szerezz több ikont...",
"getMoreIconsText": "Több ikon szerzése...",
"globalProfileInfoText": "A teljes körű játékos profilok garantálják az egyedi \nnevet a játékban, és feloldják az ikonokat is.",
"globalProfileText": "(teljes körű profil)",
"highlightText": "fénypont",
@ -600,7 +606,7 @@
},
"editSoundtrackWindow": {
"cantDeleteDefaultText": "Nem törölheted az alap betétdalt.",
"cantEditDefaultText": "Nem lehet szerkeszteni az alap betétdalt. Duplázd meg vagy csinálj egy újat.",
"cantEditDefaultText": "Nem lehet szerkeszteni az alap betétdalt. Duplikáld, vagy csinálj egy újat.",
"cantOverwriteDefaultText": "Nem lehet felülírni az alap betétdalt",
"cantSaveAlreadyExistsText": "Egy betétdal már létezik ilyen névvel!",
"defaultGameMusicText": "<alap játék zene>",
@ -626,12 +632,13 @@
"useMusicFolderText": "Zene Fájlok Mappája"
},
"editText": "Szerkesztés",
"enabledText": "Bekapcsolva",
"endText": "Befejezés",
"enjoyText": "Jó Játékot!",
"epicDescriptionFilterText": "${DESCRIPTION} A hatalmas lassú mozgásban",
"epicNameFilterText": "Hatalmas ${NAME}",
"errorAccessDeniedText": "hozzáférés megtagadva",
"errorDeviceTimeIncorrectText": "Az eszközöd rossz időt mutat ennyi órával:${HOURS}.\nEz okozhat problémákat is.\nKérjük ellenőrizze az időt és idő-zónát a beállításokban.",
"errorDeviceTimeIncorrectText": "Az eszközöd rossz időt mutat ennyi órával:${HOURS}.\nEz okozhat problémákat is.\nKérjük ellenőrizd az időt és idő-zónát a beállításokban.",
"errorOutOfDiskSpaceText": "Kifogyott a szabadhelyből",
"errorSecureConnectionFailText": "Nem lehet kapcsolatot létrehozni a biztonságos felhővel;Az internet funkcionálása talán elbukik.",
"errorText": "Hiba",
@ -849,7 +856,7 @@
"jumpInfoText": "- Ugrás -\nUgorj keresztül kis hasadásokon,\nhogy távolabbra dobj dolgokat, és\nhogy sürgesd az öröm érzetét.",
"orPunchingSomethingText": "Vagy megütni valamit, ledobni egy hegyről, és felrobbantani a lefele úton egy ragadós bombával.",
"pickUpInfoText": "- Felvétel -\nRagadd meg a zászlót, ellenfelet,\nvagy akármi mást ami nincs rögzítve.\nNyomd meg még egyszer az eldobáshoz.",
"powerupBombDescriptionText": "Hagyja, hogy egyszerre három\nbombát is el tudj dobni.",
"powerupBombDescriptionText": "Ettől három bombát\nis el fogsz tudni dobni.",
"powerupBombNameText": "Tripla-Bomba",
"powerupCurseDescriptionText": "Talán ezeket elakarod kerülni.\n...vagy nem?",
"powerupCurseNameText": "Átok",
@ -1033,6 +1040,7 @@
"maxConnectionsText": "Max. Eszközök",
"maxPartySizeText": "Maximum Parti Méret",
"maxPlayersText": "Max. Játékosok",
"merchText": "Termékek!",
"modeArcadeText": "Árkád mód",
"modeClassicText": "Klasszikus mód",
"modeDemoText": "Demó mód",
@ -1073,6 +1081,7 @@
"notSignedInErrorText": "Be kell jelentkezned a művelethez.",
"notSignedInGooglePlayErrorText": "Be kell jelentkezned Google Play-el a művelethez.",
"notSignedInText": "nem vagy bejelentkezve",
"notUsingAccountText": "Megjegyzés: a ${SERVICE} fiók figyelmen kívül hagyása.\n Ha használni szeretné, lépjen a \"Fiók -> Bejelentkezés a ${SERVICE} segítségével\".",
"nothingIsSelectedErrorText": "Nem választottál ki semmit!",
"numberText": "#${NUMBER}",
"offText": "Ki",
@ -1131,7 +1140,11 @@
"pleaseWaitText": "Kérljek várj...",
"pluginClassLoadErrorText": "Nem sikerült egy hoozáadást betölteni '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Nem sikerült elkezdeni az egyik hozzáadást '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "Plugin beállítások",
"pluginsAutoEnableNewText": "Új Pluginok auto. bekapcs.",
"pluginsDetectedText": "Új hozzáadások érzékelve. Indítsa újra az alkalmazást az aktiváláshoz, vagy szerkesztés őket a beállításokban",
"pluginsDisableAllText": "Összes plugin kikapcsolása",
"pluginsEnableAllText": "Összes plugin bekapcsolása",
"pluginsRemovedText": "${NUM} hozzáadás(ok) mostmár nem találhatóak",
"pluginsText": "Pluginok",
"practiceText": "Gyakorlás",
@ -1223,7 +1236,9 @@
"revertText": "Visszateker",
"runText": "Futás",
"saveText": "Mentés",
"scanScriptsErrorText": "Hiba a szkriptek szkennelésében; részletek a naplóban.",
"scanScriptsErrorText": "Hiba a szkriptek szkennelésében. részletek a naplóban.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} és ${NUM} modult api ${API}-ra kell frissítened, hogy működjenek",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH}-t api ${API}-ra kell frissítened hogy működjenek.",
"scoreChallengesText": "Pontszám Kihívások",
"scoreListUnavailableText": "A pontszám lista nem elérhető.",
"scoreText": "Pont",
@ -1268,6 +1283,7 @@
"netTestingText": "Hálózat Tesztelése",
"resetText": "Visszaállítás",
"showBombTrajectoriesText": "Bomba Pályájának Mutatása",
"showInGamePingText": "Ping mutatása játékban",
"showPlayerNamesText": "Játékos Név Mutatása",
"showUserModsText": "Mod Mappák Mutatása",
"titleText": "Haladó",
@ -1541,6 +1557,7 @@
"Italian": "Olasz",
"Japanese": "Japán",
"Korean": "Koreai",
"Malay": "Maláj",
"Persian": "Perzsa",
"Polish": "Lengyel",
"Portuguese": "Portugál",
@ -1824,6 +1841,7 @@
"usesExternalControllerText": "Ez a játék egy külső vezérlőt használ bemenet gyanánt.",
"usingItunesText": "Itunes használása a zenéhez...",
"usingItunesTurnRepeatAndShuffleOnText": "Kérlek bizonyosodj meg arról, hogy a keverés BE van kapcsolva és az ismétlés MINDEN-re van állítva az iTunes-on.",
"v2AccountLinkingInfoText": "Hogy V2-es fiókot kapcsolj, menj a 'fiók kezelése' gombra.",
"validatingTestBuildText": "Teszt Szerkezet Érvényesítése...",
"victoryText": "Győzelem!",
"voteDelayText": "Még nem indíthatsz szavazást újabb ${NUMBER} másodpercig",
@ -1856,6 +1874,7 @@
},
"waveText": "Hullám",
"wellSureText": "Rendben!",
"whatIsThisText": "Ez meg micsoda?",
"wiimoteLicenseWindow": {
"titleText": "DarwiinRemote Szerzői jog"
},

View file

@ -334,6 +334,7 @@
"getMoreGamesText": "Game Lain...",
"titleText": "Tambah Game"
},
"allText": "Semua",
"allowText": "Izinkan",
"alreadySignedInText": "Akunmu telah masuk di perangkat lain;\nSilakan beralih akun atau menutup permainanmu \ndi perangkat lain dan coba lagi.",
"apiVersionErrorText": "Modul ${NAME} gagal dimuat; Menarget api-version ${VERSION_USED}; kami membutuhkan ${VERSION_REQUIRED}.",
@ -558,6 +559,7 @@
"disableRemoteAppConnectionsText": "Matikan Koneksi App-Remot",
"disableXInputDescriptionText": "Izinkan lebih dari 4 pengontrol tapi mungkin agak lemot.",
"disableXInputText": "Blokir XInput",
"disabledText": "Dimatikan",
"doneText": "Selesai",
"drawText": "Seri",
"duplicateText": "Duplikat",
@ -625,6 +627,7 @@
"useMusicFolderText": "berkas dari Data Musik"
},
"editText": "Edit",
"enabledText": "Dinyalakan",
"endText": "Akhiri",
"enjoyText": "Nikmati!",
"epicDescriptionFilterText": "${DESCRIPTION} dalam slow-motion yang epik.",
@ -1221,7 +1224,9 @@
"revertText": "Kembali",
"runText": "Lari",
"saveText": "Simpan",
"scanScriptsErrorText": "Galat saat memindai skrip; lihat log untuk detailnya.",
"scanScriptsErrorText": "Kesalahan saat memindai skrip; lihat log untuk detailnya.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} dan ${NUM} modul lain perlu di perbaharui untuk api ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} perlu di perbaharui untuk api ${API}.",
"scoreChallengesText": "Tantangan Skor",
"scoreListUnavailableText": "Daftar skor tidak ada",
"scoreText": "Skor",

View file

@ -45,7 +45,7 @@
"titleText": "Account",
"unlinkAccountsInstructionsText": "Seleziona un account da scollegare",
"unlinkAccountsText": "Scollega Account",
"unlinkLegacyV1AccountsText": "Desvincular cuentas heredadas (V1)",
"unlinkLegacyV1AccountsText": "Scollega gli account legacy (V1)",
"v2LinkInstructionsText": "Usa questo link per creare un account o accedere.",
"viaAccount": "(tramite ${NAME})",
"youAreLoggedInAsText": "Accesso effettuato come:",
@ -340,6 +340,7 @@
"getMoreGamesText": "Ottieni Giochi...",
"titleText": "Aggiungi Partita"
},
"allText": "Tutto",
"allowText": "Consenti",
"alreadySignedInText": "Il tuo account è collegato da un altro dispositivo;\ncambia account o chiudi il gioco nel tuo altro\ndispositivo e riprova.",
"apiVersionErrorText": "Impossibile caricare il modulo ${NAME}; sono installate le API versione ${VERSION_USED}; è richiesta la ${VERSION_REQUIRED}.",
@ -578,6 +579,7 @@
"disableRemoteAppConnectionsText": "Disattiva connessione remota all'app",
"disableXInputDescriptionText": "Permette l'uso di più di 4 pulsantiere, ma potrebbe anche non funzionare.",
"disableXInputText": "Disabilita XInput",
"disabledText": "DISABILITATO",
"doneText": "Fatto",
"drawText": "Pareggio",
"duplicateText": "Duplicato",
@ -651,6 +653,7 @@
"useMusicFolderText": "Cartella di Musica"
},
"editText": "Modifica",
"enabledText": "Abilitato",
"endText": "Fine",
"enjoyText": "Buon Divertimento!",
"epicDescriptionFilterText": "${DESCRIPTION} a rallentatore leggendario.",
@ -1072,7 +1075,7 @@
"maxConnectionsText": "Connessioni massime",
"maxPartySizeText": "Dimensione massima gruppo",
"maxPlayersText": "Giocatori massimi",
"merchText": "Mercancía!",
"merchText": "Magliette!",
"modeArcadeText": "Modalità Arcade",
"modeClassicText": "Modalità Classica",
"modeDemoText": "Modalità Demo",
@ -1178,7 +1181,11 @@
"pleaseWaitText": "Attendi...",
"pluginClassLoadErrorText": "Errore nel caricamento di plugin classe '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Errore inizializzazione plugin '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "Impostazioni plugin",
"pluginsAutoEnableNewText": "Auto abilitazione nuovi plugins",
"pluginsDetectedText": "nuovo/i plugin rilevato. Riavvia per attivarli, o configurali nelle impostazioni.",
"pluginsDisableAllText": "Disabilita tutti i plugins",
"pluginsEnableAllText": "Abilita tutti i plugins",
"pluginsRemovedText": "${NUM} plugin non trovati.",
"pluginsText": "Plugin",
"practiceText": "Allenamento",
@ -1273,7 +1280,9 @@
"revertText": "Ritorna",
"runText": "Corri",
"saveText": "Salva",
"scanScriptsErrorText": "Errore/i nella lettura degli script, guardare il log per i dettagli.",
"scanScriptsErrorText": "Errore/i nella lettura degli script. guardare il log per i dettagli.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} e ${NUM} altri moduli necessitano di essere aggiornati per la api ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} necessita di essere aggiornato per la api ${API}.",
"scoreChallengesText": "Punteggi sfida",
"scoreListUnavailableText": "Lista punteggi non disponibile.",
"scoreText": "Punteggio",
@ -1318,6 +1327,7 @@
"netTestingText": "Collaudo Rete",
"resetText": "Reset",
"showBombTrajectoriesText": "Mostra le traiettorie delle bombe",
"showInGamePingText": "Mostra il Ping in gioco",
"showPlayerNamesText": "Mostra i nomi dei giocatori",
"showUserModsText": "Apri cartella personalizzazioni",
"titleText": "Avanzato",

View file

@ -1124,7 +1124,11 @@
"pleaseWaitText": "잠시만 기다려 주십시오...",
"pluginClassLoadErrorText": "플러그인(${PLUGIN})을 불러오는 도중에 오류가 생겼습니다. 오류 : ${ERROR}",
"pluginInitErrorText": "플러그인(${PLUGIN})을 실행하는 도중에 오류가 생겼습니다. 오류 : ${ERROR}",
"pluginSettingsText": "플러그인 설정",
"pluginsAutoEnableNewText": "새 플러그인 자동 적용",
"pluginsDetectedText": "새로운 플러그인이 감지되었습니다. 게임을 재시작 하거나 설정을 바꿔 주십시오.",
"pluginsDisableAllText": "모든 플러그인 해제하기",
"pluginsEnableAllText": "모든 플러그인 적용하기",
"pluginsRemovedText": "${NUM} 플러그인을 더 이상 찾을 수 없습니다.",
"pluginsText": "플러그인",
"practiceText": "연습",
@ -1215,7 +1219,7 @@
"revertText": "되돌리기",
"runText": "달리기",
"saveText": "저장",
"scanScriptsErrorText": "스크립트를 검색하는 중 오류가 발생했습니다. 자세한 내용은 로그를 참조하십시오.",
"scanScriptsErrorText": "스크립트(들)을 검색하는 중 오류가 발생하였습니다. 자세한 내용은 로그를 확인하십시오.",
"scoreChallengesText": "점수 챌린지",
"scoreListUnavailableText": "점수 목록을 이용할 수 없습니다.",
"scoreText": "점수",
@ -1227,7 +1231,7 @@
"scoreWasText": "(이전: ${COUNT})",
"selectText": "선택",
"seriesWinLine1PlayerText": "님이 시리즈에서",
"seriesWinLine1TeamText": "이 시리즈에서",
"seriesWinLine1TeamText": "이 시리즈에서",
"seriesWinLine1Text": "님이 시리즈에서",
"seriesWinLine2Text": "승리했습니다!",
"settingsWindow": {
@ -1259,6 +1263,7 @@
"netTestingText": "네트워크 테스트",
"resetText": "재설정",
"showBombTrajectoriesText": "폭탄 궤적 표시",
"showInGamePingText": "인게임 핑 보이기",
"showPlayerNamesText": "플레이어 이름 표시",
"showUserModsText": "모드 폴더 표시",
"titleText": "고급",
@ -1281,11 +1286,11 @@
"soundtrackTypeNames": {
"CharSelect": "캐릭터 선택",
"Chosen One": "선택된 자",
"Epic": "에픽 모드 게임",
"Epic": "에픽 모드 게임",
"Epic Race": "에픽 레이스",
"FlagCatcher": "깃발 탈환",
"FlagCatcher": "깃발 잡기",
"Flying": "행복한 생각",
"Football": "축구",
"Football": "미식 축구",
"ForwardMarch": "전진",
"GrandRomp": "정복",
"Hockey": "하키",
@ -1294,7 +1299,7 @@
"Menu": "메인 메뉴",
"Onslaught": "맹습",
"Race": "레이스",
"Scary": "킹 오브 더 힐",
"Scary": "언덕의 왕",
"Scores": "점수 화면",
"Survival": "제거",
"ToTheDeath": "데스 매치",
@ -1406,7 +1411,7 @@
"Spaz": "스파즈",
"Taobao Mascot": "타오바오 마스코트",
"Todd McBurton": "토드 맥버튼",
"Zoe": "조",
"Zoe": "조",
"Zola": "졸라"
},
"coopLevelNames": {
@ -1760,18 +1765,18 @@
"cpuBenchmarkText": "말도 안되는 속도로 튜토리얼을 실행 중(우선 CPU 속도를 테스트합니다)",
"phrase01Text": "안녕하세요!",
"phrase02Text": "${APP_NAME}에 환영합니다!",
"phrase03Text": "캐릭터를 컨트롤하는 팁을 몇 가지 알려드릴 게요.",
"phrase04Text": "${APP_NAME}의 많은 것이 물리학에 바탕을 두고 있어요.",
"phrase03Text": "캐릭터를 조작하는 팁을 몇 가지 알려드릴게요.",
"phrase04Text": "${APP_NAME}의 많은 것이 '물리학'에 바탕을 두고 있어요.",
"phrase05Text": "예를 들어, 펀치를 날릴 때...",
"phrase06Text": "...대미지는 주먹의 속도에 기반하죠.",
"phrase07Text": "보셨죠? 움직이지 않으니 ${NAME} 님에게 거의 피해를 안 줘요.",
"phrase08Text": "이제 점프 및 회전을 해서 스피드를 더 올려보세요.",
"phrase08Text": "이제 점프와 회전을 해서 스피드를 더 올려볼게요.",
"phrase09Text": "네, 훨씬 더 낫군요.",
"phrase10Text": "달리는 것도 도움이 돼요.",
"phrase11Text": "달리려면 아무 버튼이나 길게 누르세요.",
"phrase12Text": "멋진 펀치를 날리려면 달리고 회전해보세요.",
"phrase13Text": "어이쿠, 저 ${NAME} 님에게 미안하군요.",
"phrase14Text": "깃발이나... 또는 ${NAME} 님 같은 물체를 집을 수 있어요.",
"phrase13Text": "이런, ${NAME} 님에게 미안하군요.",
"phrase14Text": "깃발이나... 또는 ${NAME} 님 같은 물체를 들어올릴 수 있어요.",
"phrase15Text": "마지막으로 폭탄이 있군요.",
"phrase16Text": "폭탄을 던지려면 연습이 필요해요.",
"phrase17Text": "윽! 멋지게 던지지 못했군요.",
@ -1792,7 +1797,7 @@
"randomName3Text": "빌",
"randomName4Text": "척",
"randomName5Text": "필",
"skipConfirmText": "정말로 튜토리얼을 건너뛰세요? 눌러서 확인하세요.",
"skipConfirmText": "정말로 튜토리얼을 건너뛸건가요? 다시 눌러서 확인하세요.",
"skipVoteCountText": "${COUNT}/${TOTAL} 건너뜀",
"skippingText": "튜토리얼을 건너뛰는 중...",
"toSkipPressAnythingText": "(튜토리얼을 건너뛰려면 아무거나 누르세요)"

View file

@ -47,10 +47,10 @@
"achievementText": "Pencapaian",
"achievements": {
"Boom Goes the Dynamite": {
"description": "Pukul 3 musuh dengan TNT",
"descriptionComplete": "Memukul 3 musuh dengan TNT",
"descriptionFull": "Terajang 3 musuh dengan TNT di ${LEVEL}",
"descriptionFullComplete": "Penyepak 3 musuh dengan TNT di ${LEVEL}",
"description": "Bunuh 3 orang jahat dengan TNT",
"descriptionComplete": "Membunuh 3 orang jahat dengan TNT",
"descriptionFull": "Bunuh 3 orang jahat dengan TNT di ${LEVEL}",
"descriptionFullComplete": "Membunuh 3 musuh dengan TNT di ${LEVEL}",
"name": "Letupan Dinamit"
},
"Boxer": {
@ -58,7 +58,7 @@
"descriptionComplete": "Memenangi tanpa menggunakan apa-apa bom",
"descriptionFull": "Selesaikan ${LEVEL} tanpa menggunakan apa-apa bom",
"descriptionFullComplete": "Menyelesaikan ${LEVEL} tanpa menggunakan apa-apa bom",
"name": "Burung apa, burung puyuh"
"name": "Peninju"
},
"Dual Wielding": {
"descriptionFull": "Sambungkan 2 alat kawalan (perkakasan atau aplikasi)",
@ -78,7 +78,7 @@
"name": "Free Loader"
},
"Gold Miner": {
"description": "Lempang 6 musuh dengan periuk api",
"description": "Bunuh 6 orang jahat dengan periuk-api",
"descriptionComplete": "Menerajangi 6 musuh dengan periuk api",
"descriptionFull": "Lempang 6 musuh dengan periuk api di ${LEVEL}",
"descriptionFullComplete": "Terlempang 6 musuh dengan periuk api di ${LEVEL}",
@ -270,9 +270,9 @@
"name": "Pelempang Super"
},
"TNT Terror": {
"description": "Letupkan 6 orang jahat dengan TNT",
"descriptionComplete": "6 orang jahat telah diletupkan dengan TNT",
"descriptionFull": "Letupkan 6 orang jahat dengan TNT di ${LEVEL}",
"description": "Bunuh 6 orang jahat dengan TNT",
"descriptionComplete": "Membunuh 6 orang jahat dengan TNT",
"descriptionFull": "Bunuh 6 orang jahat dengan TNT di ${LEVEL}",
"descriptionFullComplete": "6 orang jahat telah diletupkan dengan TNT di ${LEVEL}",
"name": "Ta an ta"
},
@ -292,7 +292,7 @@
"description": "Hentikan setiap orang jahat",
"descriptionComplete": "Telah berjaya mengentikan setiap orang jahat",
"descriptionFull": "Hentikan setiap orang jahat di ${LEVEL}",
"descriptionFullComplete": "Berjaya menghentikan setiap orang jahat di ${LEVEL}",
"descriptionFullComplete": "Menghentikan setiap orang jahat di ${LEVEL}",
"name": "Dinding"
},
"Uber Football Shutout": {
@ -652,9 +652,9 @@
"fireTVRemoteWarningText": "* Untuk pengalaman yang lebih baik,\ngunakan Game Controllers atau pasang\naplikasi '${REMOTE_APP_NAME}' pada\ntelefon atau tablet anda.",
"firstToFinalText": "Yang pertama untuk ${COUNT} pusingan akhir",
"firstToSeriesText": "Siri Pertama kepada-${COUNT}.",
"fiveKillText": "KENTUT BERLIMA!!!",
"fiveKillText": "MEMBUNUH LIMA!!!",
"flawlessWaveText": "Pusingan Sempurna!",
"fourKillText": "KENTUT BERAMAI-RAMAI!!!",
"fourKillText": "MEBUNUH EMPAT!!!",
"friendScoresUnavailableText": "Skor rakan tidak tersedia.",
"gameCenterText": "GameCenter",
"gameCircleText": "GameCircle",
@ -942,29 +942,29 @@
"keyboardChangeInstructionsText": "Tekan dua kali \"spacebar\" untuk menukar papan kekunci.",
"keyboardNoOthersAvailableText": "Tiada papan kekunci lain tersedia.",
"keyboardSwitchText": "Menukar papan kekunci kepada \"${NAME}\".",
"kickOccurredText": "${NAME} telah diterajang.",
"kickQuestionText": "Tendang ${NAME}?",
"kickText": "Terajang",
"kickVoteCantKickAdminsText": "Admin tidak boleh ditendang.",
"kickVoteCantKickSelfText": "Anda tidak boleh menendang diri sendiri.",
"kickOccurredText": "${NAME} telah dikeluarkan.",
"kickQuestionText": "Keluarkan ${NAME}?",
"kickText": "Keluarkan",
"kickVoteCantKickAdminsText": "Admin tidak boleh dikeluarkan.",
"kickVoteCantKickSelfText": "Anda tidak boleh mengeluarkan diri sendiri.",
"kickVoteFailedNotEnoughVotersText": "Tidak cukup pemain untuk undian.",
"kickVoteFailedText": "Undi sepakan gagal.",
"kickVoteStartedText": "Undian sepakan telah dimulakan untuk ${NAME}.",
"kickVoteText": "Undi untuk Menendang",
"kickVotingDisabledText": "Undian sepakan dilumpuhkan.",
"kickVoteFailedText": "Undian mengeluarkan gagal.",
"kickVoteStartedText": "Undian mengeluarkan telah dimulakan untuk ${NAME}.",
"kickVoteText": "Undi untuk Mengeluarkan",
"kickVotingDisabledText": "Undian mengeluarkan dilumpuhkan.",
"kickWithChatText": "Taip ${YES} dalam sembang untuk ya dan ${NO} untuk tidak.",
"killsTallyText": "${COUNT} meninggal",
"killsText": "Meninggal",
"killsTallyText": "${COUNT} membunuh",
"killsText": "Membunuh",
"kioskWindow": {
"easyText": "Senang",
"epicModeText": "Mod Epik",
"epicModeText": "Mode Epik",
"fullMenuText": "Menu Penuh",
"hardText": "Susah",
"mediumText": "Sederhana",
"singlePlayerExamplesText": "Contoh Pemain Tunggal / Koperasi",
"versusExamplesText": "Contoh Perbandingan"
},
"languageSetText": "Bahasa ditetapkan ke \"${LANGUAGE}\"",
"languageSetText": "Bahasa sekarang \"${LANGUAGE}\"",
"lapNumberText": "Pusingan ${CURRENT}/${TOTAL}",
"lastGamesText": "( ${COUNT} permainan terakhir)",
"leaderboardsText": "Papan pendahulu",
@ -1027,22 +1027,22 @@
"modeClassicText": "Mod Klasik",
"modeDemoText": "Demo Mode",
"mostValuablePlayerText": "Pemain yang amat berharga",
"mostViolatedPlayerText": "Pemain yang Amat Melanggar",
"mostViolatedPlayerText": "Pemain Paling Banyak Mati",
"mostViolentPlayerText": "Pemain Paling Ganas",
"moveText": "Bergerak",
"multiKillText": "${COUNT}-Meninggal!!",
"multiKillText": "${COUNT}-Membunuh!!",
"multiPlayerCountText": "${COUNT} pemain",
"mustInviteFriendsText": "Nota: anda mesti menjemput rakan masuk\npanel \"${GATHER}\" atau lampirkan\npengawal untuk bermain berbilang pemain.",
"nameBetrayedText": "${NAME} mengkhianati ${VICTIM}.",
"nameDiedText": "${NAME} ninggal.",
"nameKilledText": "${NAME} meng ninggal ${VICTIM}.",
"nameDiedText": "${NAME} mati.",
"nameKilledText": "${NAME} membunuhkan ${VICTIM}.",
"nameNotEmptyText": "Nama tidak boleh kosong!",
"nameScoresText": "Markah ${NAME}!",
"nameSuicideKidFriendlyText": "${NAME} ter ninggal.",
"nameSuicideText": "${NAME} mening gal.",
"nameSuicideKidFriendlyText": "${NAME} secara tidak sengaja mati.",
"nameSuicideText": "${NAME} membunuh diri.",
"nameText": "Nama",
"nativeText": "Asal",
"newPersonalBestText": "Markah sendiri baharu!",
"newPersonalBestText": "Terbaik peribadi baru!",
"newTestBuildAvailableText": "Binaan ujian yang lebih baharu tersedia! (${VERSION} bina ${BUILD}).\nDapatkannya di ${ADDRESS}",
"newText": "Baru",
"newVersionAvailableText": "Versi ${APP_NAME} yang lebih baharu tersedia! (${VERSION})",
@ -1121,7 +1121,11 @@
"pleaseWaitText": "Sila tunggu...",
"pluginClassLoadErrorText": "Ralat memuatkan kelas pemalam '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Ralat semasa memulakan pemalam '${PLUGIN}': ${ERROR}",
"pluginsDetectedText": "Pemalam baharu dikesan. Mulakan semula untuk mengaktifkannya, atau konfigurasikannya dalam tetapan.",
"pluginSettingsText": "Tetapan Pemalam",
"pluginsAutoEnableNewText": "Auto Dayakan Pemalam Baru",
"pluginsDetectedText": "Pemalam(s) baharu dikesan. Mulakan semula untuk mengaktifkannya, atau konfigurasikannya dalam tetapan.",
"pluginsDisableAllText": "Nyahdayakan Semua Pemalam",
"pluginsEnableAllText": "Dayakan Semua Pemalam",
"pluginsRemovedText": "${NUM} pemalam tidak ditemui lagi.",
"pluginsText": "Bahan Tambahan",
"practiceText": "Latihan",
@ -1212,7 +1216,7 @@
"revertText": "Kembalikan",
"runText": "Lari",
"saveText": "Simpan",
"scanScriptsErrorText": "Ralat mengimbas skrip; lihat log untuk butiran.",
"scanScriptsErrorText": "Ralat(s) mengimbas skrip; Lihat log untuk butiran.",
"scoreChallengesText": "Cabaran Skor",
"scoreListUnavailableText": "Senarai skor tidak tersedia.",
"scoreText": "Markah",
@ -1256,6 +1260,7 @@
"netTestingText": "Ujian Rangkaian",
"resetText": "Tetap Semula",
"showBombTrajectoriesText": "Tunjukkan Trajektori Bom",
"showInGamePingText": "Tunjukkan Ping Dalam Permainan",
"showPlayerNamesText": "Tunjukkan Nama Pemain",
"showUserModsText": "Tunjukkan Pelipat Mod",
"titleText": "Lanjutan",
@ -1354,12 +1359,12 @@
"testBuildValidateErrorText": "Tidak dapat mengesahkan binaan ujian. (tiada sambungan net?)",
"testBuildValidatedText": "Binaan Ujian Disahkan; Sting aku yahoo!",
"thankYouText": "Terima kasih atas sokongan anda! Nikmati permainan!!",
"threeKillText": "PELEPASAN GAS TIGA KALI!!",
"threeKillText": "PEMBUNUHAN TIGA KALI GANDA!!",
"timeBonusText": "Bonus Masa",
"timeElapsedText": "Masa Berlalu",
"timeExpiredText": "Masa Tamat",
"timeSuffixDaysText": "${COUNT}h",
"timeSuffixHoursText": "${COUNT}j",
"timeSuffixDaysText": "${COUNT}d",
"timeSuffixHoursText": "${COUNT}h",
"timeSuffixMinutesText": "${COUNT}m",
"timeSuffixSecondsText": "${COUNT}s",
"tipText": "Tip",
@ -1425,7 +1430,7 @@
"Uber Runaround": "Lari padang Urban"
},
"gameDescriptions": {
"Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Jadilah orang yang terpilih untuk masa yang lama untuk menang.\nLawan untuk terpilih.",
"Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Jadilah orang yang terpilih untuk masa yang lama untuk menang.\nBunuh orang terpilih untuk menjadinya.",
"Bomb as many targets as you can.": "Bom seberapa banyak sasaran yang anda boleh.",
"Carry the flag for ${ARG1} seconds.": "Bawa bendera selama ${ARG1} saat.",
"Carry the flag for a set length of time.": "Bawa bendera untuk jangka masa yang ditetapkan.",
@ -1436,12 +1441,12 @@
"Gather eggs!": "Kumpul tolo!",
"Get the flag to the enemy end zone.": "Dapatkan bendera ke zon hujung musuh.",
"How fast can you defeat the ninjas?": "Seberapa pantas anda boleh mengalahkan ninja?",
"Kill a set number of enemies to win.": "Sepak segerombolan musuh untuk memenangi.",
"Last one standing wins.": "Kedudukan terakhir menang.",
"Last remaining alive wins.": "Kemenangan terakhir yang masih ada.",
"Last team standing wins.": "Kedudukan pasukan terakhir menang.",
"Prevent enemies from reaching the exit.": "Elakkan musuh daripada sampai ke pintu keluar.",
"Reach the enemy flag to score.": "Sampai ke bendera musuh untuk menerima mata.",
"Kill a set number of enemies to win.": "Bunuh beberapa set musuh untuk menang.",
"Last one standing wins.": "Yang terakhir bertahan menang.",
"Last remaining alive wins.": "Yang tinggal terakhir hidup menang.",
"Last team standing wins.": "Pasukan terakhir bertahan menang.",
"Prevent enemies from reaching the exit.": "Menghalang musuh daripada sampai ke pintu keluar.",
"Reach the enemy flag to score.": "Sentuh bendera musuh untuk menjaringkan gol.",
"Return the enemy flag to score.": "Kembalikan bendera musuh untuk menerima mata.",
"Run ${ARG1} laps.": "Telah berlari ${ARG1} pusingan.",
"Run ${ARG1} laps. Your entire team has to finish.": "Lari pusingan ${ARG1}. Mesti semua ahli pasukan sudah selesai.",
@ -1463,9 +1468,9 @@
"Touch the enemy flag ${ARG1} times.": "Sentuh bendera musuh sebanyak ${ARG1} kali.",
"Touch the enemy flag.": "Sentuh bendera musuh.",
"carry the flag for ${ARG1} seconds": "membawa bendera selama ${ARG1} saat",
"kill ${ARG1} enemies": "lempang musuh ${ARG1}",
"last one standing wins": "yang terakhir menang",
"last team standing wins": "pasukan terakhir berdiri menang",
"kill ${ARG1} enemies": "Bunuh ${ARG1} musuh",
"last one standing wins": "yang terakhir bertahan menang",
"last team standing wins": "pasukan terakhir bertahan menang",
"return ${ARG1} flags": "kembalikan bendera ${ARG1}.",
"return 1 flag": "pulangkan 1 bendera",
"run ${ARG1} laps": "pusingan ke ${ARG1} larian",
@ -1793,10 +1798,10 @@
"skippingText": "ponteng tutorial...",
"toSkipPressAnythingText": "(ketik atau tekan apa-apa untuk melangkau tutorial)"
},
"twoKillText": "KENTUT BERGANDA!",
"twoKillText": "PEMBUNUHAN BERGANDA!",
"unavailableText": "tidak ada",
"unconfiguredControllerDetectedText": "Pengawal tidak dikonfigurasikan dikesan:",
"unlockThisInTheStoreText": "Mangga mesti dibuka kunci di kedai.",
"unlockThisInTheStoreText": "Ini mesti dibuka kunci di kedai.",
"unlockThisProfilesText": "Untuk membuat lebih daripada ${NUM} profil, anda memerlukan:",
"unlockThisText": "Untuk membuka kunci ini, anda memerlukan:",
"unsupportedHardwareText": "Maaf, perkakasan ini tidak disokong oleh binaan permainan ini.",
@ -1859,7 +1864,7 @@
},
"winsPlayerText": "${NAME} Menang!",
"winsTeamText": "${NAME} Menang!",
"winsText": "${NAME} Monang!",
"winsText": "${NAME} Menang!",
"workspaceSyncErrorText": "Ralat menyegerakkan ${WORKSPACE}. Lihat log untuk butiran.",
"workspaceSyncReuseText": "Tidak dapat menyegerakkan ${WORKSPACE}. Menggunakan semula versi disegerakkan sebelumnya.",
"worldScoresUnavailableText": "Markah dunia tidak tersedia.",

View file

@ -1,14 +1,14 @@
{
"accountSettingsWindow": {
"accountNameRules": "نام نمی‌تواند اموجی (شکلک) یا نویسه‌ های ویژه داشته باشد",
"accountNameRules": "نام حساب نمی‌تونه ایموجی (شکلک) یا نویسه‌ های ویژه داشته باشه",
"accountProfileText": "(مشخصات حساب)",
"accountsText": "پروفایل ها",
"accountsText": "حساب های کاربری",
"achievementProgressText": "${TOTAL}/${COUNT} :دستاوردها",
"campaignProgressText": "${PROGRESS} :[سخت] پیشروی در بازی اصلی",
"changeOncePerSeason": ".فقط یک‌بار در هر فصل می‌توانید این مورد را تغییر دهید",
"changeOncePerSeasonError": "(روز تا فصل بعد‎ ${NUM}) برای تغییر این گزینه باید تا فصل بعد صبر کنید",
"changeOncePerSeason": ".فقط یه بار در هر فصل می‌تونی این مورد رو تغییر بدی",
"changeOncePerSeasonError": "(روز تا فصل بعد‎ ${NUM}) برای تغییر این گزینه باید تا فصل بعد صبر کنی",
"customName": "نام سفارشی",
"googlePlayGamesAccountSwitchText": "اگه میخوای اکانت گوگلت رو استفاده کنی\nاستفاده کن اکانت گوگل پلی بازی های دیگت رو",
"googlePlayGamesAccountSwitchText": "،اگه میخوای از اکانت گوگل متفاوتی استفاده کنی\nبرای تعویض از گوگل پلی گیمز استفاده کن",
"linkAccountsEnterCodeText": "کد را وارد کنید",
"linkAccountsGenerateCodeText": "ایجاد کد",
"linkAccountsInfoText": "(به اشتراک گذاری پیشروی بین دستگاه‌های مختلف)",
@ -16,22 +16,22 @@
"linkAccountsInstructionsText": "برای اتصال دو حساب، در یکی از\nآن ها کدی ایجاد کرده \nو آن را در دیگری وارد کنید.\nپیشرفت ها و موجودی ترکیب خواهد شد.\nحساب را وصل کنید ${COUNT} شما می توانید.\n!توجه : فقط حساب هایی را وصل کنید که برای\n شماست\nاگر شما حساب دیگری را وصل کنید، شما توانایی این را ندارید که در یک زمان بازی کنید!\nاین عمل برگشت پذیر نیست، پس \nدقت کنید!",
"linkAccountsText": "متصل کردن حساب ها",
"linkedAccountsText": ":حساب های متصل شده",
"manageAccountText": "تنظیمات حساب کاربری",
"manageAccountText": "تنظیمات حساب",
"nameChangeConfirm": "تغییر کند؟‎ ${NAME} آیا نام شما به",
"resetProgressConfirmNoAchievementsText": "همهٔ پیشروی‌های شما در بخش همکاری و بالاترین امتیازات\nشما پاک خواهد شد. (به استثنای بلیت‌های شما)\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟",
"resetProgressConfirmText": "همهٔ پیشروی‌ها در بخش همکاری، دستاوردها\n.و امتیازات بالای شما پاک خواهد شد\n(به استثنای بلیت‌های شما)\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟",
"resetProgressConfirmNoAchievementsText": "همهٔ پیشروی‌های شما در بخش همکاری و امتیازات\nشما پاک خواهد شد. (به استثنای بلیت‌های شما)\nاین کار برگشت‌پذیر نیست. آیا مطمئنید؟",
"resetProgressConfirmText": "همهٔ پیشروی‌ها در بخش همکاری، دستاوردها\n.و امتیازات بالای شما پاک خواهد شد\n(به استثنای بلیت‌های شما)\nاین کار برگشت‌ پذیر نیست. آیا مطمئنید؟",
"resetProgressText": "بازنشانی پیشروی",
"setAccountName": "تنظیم نام حساب",
"setAccountName": "تنظیم نام اکانت",
"setAccountNameDesc": "نامی که می‌خواهید برای این حساب نمایش داده شود را انتخاب کنید\nمیتوانید از یکی از نام‌های حساب‌های وصل‌شده استفاده کنید\nیا یک نام جدید بسازید",
"signInInfoText": "به حسابتان وصل شوید تا بلیت جمع کنید، آنلاین رقابت کنید \n.و پیشرفت خود را با دیگران به اشتراک بگذارید",
"signInInfoText": "به حسابتان وصل شوید تا بلیت جمع کنید، آنلاین رقابت کنید \n.و پیشرفت خود را در دستگاه ها به اشتراک بگذارید",
"signInText": "ورود به حساب",
"signInWithDeviceInfoText": "(یک حساب خودکار فقط از این دستگاه در دسترس می‌باشد)",
"signInWithDeviceText": "وصل شدن با حساب دستگاه",
"signInWithDeviceText": "وصل شدن با اکانت دستگاه",
"signInWithGameCircleText": "وصل شدن از طریق حوزهٔ بازی",
"signInWithGooglePlayText": "ورود با حساب بازی‌های گوگل",
"signInWithGooglePlayText": "ورود با اکانت گوگل پلی",
"signInWithTestAccountInfoText": "(حساب میراثی؛ از حساب‌های دستگاه برای پیشروی استفاده می‌کند)",
"signInWithTestAccountText": "ورود با حساب آزمایشی",
"signInWithV2InfoText": "یک حساب کاربری که بر روی تمام سیستم عامل ها کار می کند",
"signInWithV2InfoText": "یک اکانت که روی همه سیستم عامل ها کار میکنه",
"signInWithV2Text": "ورود به سیستم با حساب بمب اسکواد",
"signOutText": "خروج از حساب",
"signingInText": "در حال اتصال…",
@ -43,16 +43,16 @@
"unlinkLegacyV1AccountsText": "لغو پیوند حساب‌های قدیمی (V1)",
"v2LinkInstructionsText": "استفاده از این لینک برای ایجاد یک حساب کاربری و یا ورود به سیستم.",
"viaAccount": "(${NAME} از طریق حساب)",
"youAreSignedInAsText": ":با این حساب وصل شده‌اید"
"youAreSignedInAsText": ":با این اکانت وصل شدی"
},
"achievementChallengesText": "چالش‌های دستاورددار",
"achievementChallengesText": "چالش‌های دستاورد دار",
"achievementText": "دستاورد",
"achievements": {
"Boom Goes the Dynamite": {
"description": ".نابود کن TNT سه حریف را با",
"descriptionComplete": "!نابود کردی TNT سه حریف را با",
"descriptionFull": "از بین ببر TNT با ${LEVEL} سه حریف را در",
"descriptionFullComplete": "از بین بردی TNT با ${LEVEL} سه حریف را در",
"descriptionComplete": "!ترکوندی TNT سه نفر رو با",
"descriptionFull": "از بین ببر TNT با ${LEVEL} سه نفر رو توی",
"descriptionFullComplete": "از بین بردی TNT با ${LEVEL} سه نفر رو توی",
"name": "!ترکوندی"
},
"Boxer": {
@ -60,18 +60,18 @@
"descriptionComplete": "بدون استفاده از بمب برنده شدی",
"descriptionFull": "را بدون استفاده از هیچ بمبی کامل کن ${LEVEL} مرحلهٔ",
"descriptionFullComplete": "را بدون استفاده از بمب کامل کردی ${LEVEL} مرحلهٔ",
"name": "مشت‌زن"
"name": "بوکسر"
},
"Dual Wielding": {
"descriptionFull": "(‏دو دستهٔ بازی وصل کن (سخت‌افزاری یا نرم‌افزاری",
"descriptionFullComplete": "(دو دستهٔ بازی وصل کردی (سخت‌افزار یا نرم‌افزار",
"name": "دوگانه اداره کردن"
"descriptionFull": "(‏دو دستهٔ به بازی وصل کن (سخت‌افزاری یا نرم‌افزاری",
"descriptionFullComplete": "(دو دستهٔ به بازی وصل کردی (سخت‌افزار یا نرم‌افزار",
"name": "دوتایی"
},
"Flawless Victory": {
"description": "بدون ضربه خوردن برنده شو",
"descriptionComplete": "بدون ضربه خوردن برنده شدی",
"descriptionFull": "را بدون ضربه خوردن برنده شو ${LEVEL} مرحلهٔ",
"descriptionFullComplete": ا بدون ضربه خوردن برنده شدی ${LEVEL} مرحلهٔ",
"description": "بدون هیچ آسیبی برنده شو",
"descriptionComplete": "بدون هیچ آسیبی برنده شدی",
"descriptionFull": "را بدون هیچ آسیبی برنده شو ${LEVEL} مرحلهٔ",
"descriptionFullComplete": و بدون هیچ آسیبی برنده شدی ${LEVEL} مرحلهٔ",
"name": "پیروزی بی‌نقص"
},
"Free Loader": {
@ -84,7 +84,7 @@
"descriptionComplete": "شش حریف را با مین زمینی نابود کردی",
"descriptionFull": "با مین زمینی از بین ببر ${LEVEL} شش حریف را در مرحلهٔ",
"descriptionFullComplete": "با مین زمینی نابود کردی ${LEVEL} شش حریف را در مرحلهٔ",
"name": "مین‌گذار حرفه‌ای"
"name": "مین‌گذار طلایی"
},
"Got the Moves": {
"description": "بدون استفاده از مشت یا بمب برنده شو",
@ -94,7 +94,7 @@
"name": "عجب حرکتی"
},
"In Control": {
"descriptionFull": "(یک دستهٔ بازی وصل کن (سخت‌افزاری یا نرم‌افزاری",
"descriptionFull": "(یک دستهٔ به بازی وصل کن (سخت‌افزاری یا نرم‌افزاری",
"descriptionFullComplete": "(یک دستهٔ بازی وصل کردی (سخت‌افزار یا نرم‌افزار",
"name": "تحت کنترل"
},
@ -103,7 +103,7 @@
"descriptionComplete": "۱۰۰۰ امتیاز گرفتی‏",
"descriptionFull": "۱۰۰۰ امتیاز بگیر ${LEVEL} در مرحلهٔ",
"descriptionFullComplete": "۱۰۰۰ امتیاز گرفتی‏ ${LEVEL} در مرحلهٔ",
"name": "${LEVEL} سَرور"
"name": "${LEVEL} خدا"
},
"Last Stand Master": {
"description": "‏۲۵۰ امتیاز بگیر",
@ -124,13 +124,13 @@
"descriptionComplete": "سه حریف را با مین زمینی از بین بردی",
"descriptionFull": "با مین از بین ببر ${LEVEL} سه حریف را در مرحلهٔ",
"descriptionFullComplete": "با مین از بین بردی ${LEVEL} سه حریف را در مرحلهٔ",
"name": "بازی با مین"
"name": "بازی مین"
},
"Off You Go Then": {
"description": "سه حریف رو از زمین بنداز بیرون",
"descriptionComplete": "سه حریف رو از نقشه انداختی پایین",
"descriptionFull": "از نقشه بنداز پایین${LEVEL}سه حریف رو در مرحله ی",
"descriptionFullComplete": "از نقشه انداختی پایین ${LEVEL} سه حریف رو در مرحله ی",
"description": "سه تا حریف از نقشه بنداز بیرون",
"descriptionComplete": "سه تا حریف رو از نقشه انداختی بیرون",
"descriptionFull": "بنداز پایین ${LEVEL} سه حریف رو از نقشه در مرحله",
"descriptionFullComplete": "از نقشه انداختی پایین ${LEVEL} سه حریف رو در مرحله",
"name": "حالا میتونی بری"
},
"Onslaught God": {
@ -142,16 +142,16 @@
},
"Onslaught Master": {
"description": "پونصد امتیاز بگیر",
"descriptionComplete": ونصد امتیاز گرفتی",
"descriptionFull": "بگیر ${LEVEL} پونصد امتیاز در مرحله ی",
"descriptionFullComplete": "گرفتی ${LEVEL} پونصد امتیاز در مرحله ی",
"descriptionComplete": انصد امتیاز گرفتی",
"descriptionFull": "بگیر ${LEVEL} پانصد امتیاز در مرحله ی",
"descriptionFullComplete": "گرفتی ${LEVEL} پانصد امتیاز در مرحله ی",
"name": "${LEVEL} استاد"
},
"Onslaught Training Victory": {
"description": "تمام موج ها را بگذران",
"descriptionComplete": "تمام موج ها را گذراندی",
"descriptionFull": "بگذران ${LEVEL} تمام موج ها رو در مرحله ی",
"descriptionFullComplete": "گذراندی ${LEVEL} تمام موج ها رو در مرحله ی",
"description": "همه موج ها رو رد کن",
"descriptionComplete": "همه موج ها رو رد کردی",
"descriptionFull": "رد کن ${LEVEL} همه موج ها رو تو مرحله",
"descriptionFullComplete": "رد کردی ${LEVEL} همه موج ها رو توی مرحله",
"name": "${LEVEL} پیروزی"
},
"Onslaught Wizard": {
@ -162,16 +162,16 @@
"name": "${LEVEL} جادوگر"
},
"Precision Bombing": {
"description": "بدون گرفتن هیچ جعبه ای برنده شو",
"descriptionComplete": "بدون گرفتن هیچ جعبه ای برنده شدی",
"descriptionFull": "رو بدون گرفتن جعبه برنده شو ${LEVEL} مرحله ی",
"descriptionFullComplete": "رو بدون گرفتن جعبه برنده شدی ${LEVEL} مرحله ی",
"name": "بمب اندازی دقیق"
"description": "بدون گرفتن هیچ قدرتی برنده شو",
"descriptionComplete": "بدون گرفتن هیچ قدرتی برنده شدی",
"descriptionFull": "رو بدون گرفتن قدرتی برنده شو ${LEVEL} مرحله",
"descriptionFullComplete": "رو بدون گرفتن قدرتی برنده شدی ${LEVEL} مرحله",
"name": "بمب باران دقیق"
},
"Pro Boxer": {
"description": "بدون استفاده از هر بمبی برنده شو",
"descriptionComplete": "بدون استفاده از هر بمبی برنده شدی",
"descriptionFull": "رو بدون استفاده از هر بمبی تمام کن ${LEVEL} مرحله ی",
"description": "بدون استفاده از هیچ بمبی برنده شو",
"descriptionComplete": "بدون استفاده از هیچ بمبی برنده شدی",
"descriptionFull": "رو بدون استفاده از هیچ بمبی تمام کن ${LEVEL} مرحله ی",
"descriptionFullComplete": "رو بدون استفاده از هر بمبی تمام کردی ${LEVEL} مرحله",
"name": "مشت‌زن حرفه‌ای"
},
@ -334,6 +334,7 @@
"getMoreGamesText": "...بازی های بیشتر",
"titleText": "افزودن بازی"
},
"allText": "همه",
"allowText": "اجازه دادن",
"alreadySignedInText": "این حساب کاربری توسط یک دستگاه دیگر در حال استفاده می باشد.\nلطفا از حساب کاربری دیگری استفاده کنید یا بازی را \nدر بقیه دستگاه هایتان ببندید و دوباره امتحان کنید.",
"apiVersionErrorText": "نیاز داریم ${VERSION_REQUIRED} است. به ورژن ${VERSION_USED} بالا نمی آید. هدفش ${NAME} مدل",
@ -376,7 +377,7 @@
"configureTouchText": "تنظیمات صفحه لمسی",
"ps3Text": "PS3 دسته",
"titleText": "دسته ها",
"wiimotesText": "Wii دسته",
"wiimotesText": "ها Wiimote",
"xbox360Text": "Xbox 360 دسته"
},
"configGamepadSelectWindow": {
@ -387,7 +388,7 @@
"configGamepadWindow": {
"advancedText": "پیشرفته",
"advancedTitleText": "تنظیمات پیشرفته ی دسته",
"analogStickDeadZoneDescriptionText": "این گزینه را فعال کنید اگر بازیکن شما بی خودی حرکت میکند",
"analogStickDeadZoneDescriptionText": "(این گزینه را فعال کنید اگر بازیکن شما بی خودی تکان میخورد)",
"analogStickDeadZoneText": "دکمه ی آنالوگ منطقه ی مرگ و میر",
"appliesToAllText": "(بر همه دسته ها از این نوع اعمال میشود)",
"autoRecalibrateDescriptionText": "(این گزینه را فعال کنید اگر بازیکن شما با تمام سرعت نمیدود)",
@ -560,6 +561,7 @@
"disableRemoteAppConnectionsText": "غیر فعال کردن ارتباطات از راه دور برنامه",
"disableXInputDescriptionText": "اجازه می‌دهد به بیش از 4 کنترل کننده اما ممکن است کار نکند.",
"disableXInputText": "غیرفعال کردن ورودی ایکس",
"disabledText": "غیر فعال شده",
"doneText": "انجام شد",
"drawText": "برابر",
"duplicateText": "تکراری",
@ -627,6 +629,7 @@
"useMusicFolderText": "پوشه ی فایل های موسیقی"
},
"editText": "ویرایش",
"enabledText": "فعال شده",
"endText": "پایان",
"enjoyText": "لذت ببرید",
"epicDescriptionFilterText": "در حماسهٔ حرکت آهسته ${DESCRIPTION}",
@ -1220,7 +1223,9 @@
"revertText": "بازگشت",
"runText": "دویدن",
"saveText": "ذخیره",
"scanScriptsErrorText": "اسکریپت ها در حال بررسی خطا ها است؛ برای جزئیات لوگ را ببینید",
"scanScriptsErrorText": "اسکریپت ها در حال بررسی خطا ها است؛ برای جزئیات لاگ را ببینید",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} و ${NUM} ماژول(های) دیگر باید برای api ${API} به‌روزرسانی شوند.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} باید برای api ${API} به‌روزرسانی شود.",
"scoreChallengesText": "امتیاز چالش",
"scoreListUnavailableText": ".لیست امتیازات در دسترس نیست",
"scoreText": "امتیاز",
@ -1268,7 +1273,7 @@
"showPlayerNamesText": "نمایش نام بازیکنان",
"showUserModsText": "نمایش پوشهٔ سبک بازی‌ها",
"titleText": "پیشرفته",
"translationEditorButtonText": "${APP_NAME} ویرایشگر زبان",
"translationEditorButtonText": "ویرایشگر زبان ${APP_NAME}",
"translationFetchErrorText": "وضعیت ترجمه در دسترس نیست",
"translationFetchingStatusText": "چک کردن وضعیت ترجمه ...",
"translationInformMe": "!وقتی زبان من به‌روزرسانی نیاز داشت، خبرم کن",
@ -1488,7 +1493,7 @@
"score a touchdown": "امتیاز یک پرش",
"secure all ${ARG1} flags": "پرچم ${ARG1}مال خودکردن همه",
"secure the flag for ${ARG1} seconds": "ثانیه ${ARG1} حفاظت از پرچم برای",
"touch ${ARG1} flags": "پرچم ${ARG1}لمس",
"touch ${ARG1} flags": "پرچم ${ARG1} لمس",
"touch 1 flag": "لمس 1 پرچم"
},
"gameNames": {
@ -1497,13 +1502,13 @@
"Chosen One": "فرد منتخب",
"Conquest": "قدرت نمایی",
"Death Match": "نبرد مرگبار",
"Easter Egg Hunt": "شکار تخم‌مرغ عید پاک",
"Easter Egg Hunt": "شکار ایستر اگ",
"Elimination": "استقامت",
"Football": "فوتبال آمریکایی",
"Hockey": "هاکی",
"Keep Away": "دور نگه داشتن",
"King of the Hill": "پادشاه تپه",
"Meteor Shower": "بمباران",
"Meteor Shower": "حمام بمب",
"Ninja Fight": "نبرد با نینجاها",
"Onslaught": "مبارزه",
"Race": "مسابقهٔ دو",
@ -1563,17 +1568,17 @@
},
"mapsNames": {
"Big G": "بزرگ G",
"Bridgit": "بریدگیت",
"Bridgit": "پل میانی",
"Courtyard": "حیاط",
"Crag Castle": "قلعه پرتگاه",
"Doom Shroom": "رستاخیز",
"Football Stadium": "استادیوم فوتبال",
"Happy Thoughts": "پرواز",
"Happy Thoughts": "رویای شیرین",
"Hockey Stadium": "استادیوم هاکی",
"Lake Frigid": "یخبندان",
"Lake Frigid": "دریاچه یخ زده",
"Monkey Face": "صورت میمون",
"Rampage": "خشم",
"Roundabout": "میدان",
"Roundabout": "میدان نبرد",
"Step Right Up": "پایدار",
"The Pad": "رینگ",
"Tip Top": "تیپ تاپ",
@ -1684,20 +1689,20 @@
"Flag Idle Return Time": "پرچم زمان بازگشت بیدرنگ",
"Flag Touch Return Time": "زمان بازگشت لمس پرچم",
"Hold Time": "زمان نگه داشتن",
"Kills to Win Per Player": "هرکی بیشتر نابود کنه",
"Kills to Win Per Player": "تعداد کشته برای پیروز شدن",
"Laps": "دور ها",
"Lives Per Player": "تعداد جان برای بازیکن",
"Long": "طولانی",
"Longer": "خیلی طولانی",
"Mine Spawning": "مین گذاری",
"Mine Spawning": "کار گذاری مین",
"No Mines": "بدون مین",
"None": "هيچ",
"Normal": "معمولی",
"Pro Mode": "حالت حرفه ای",
"Respawn Times": "زمان برگشت بازیکن مرده",
"Respawn Times": "مدت زمان دوباره زنده شدن",
"Score to Win": "امتیاز بگیر تا برنده شی",
"Short": "کوتاه",
"Shorter": "کوتاه تر",
"Shorter": "خیلی کوتاه",
"Solo Mode": "حالت انفرادی",
"Target Count": "تعداد هدف",
"Time Limit": "محدودیت زمانی"
@ -1708,18 +1713,18 @@
"Warning to ${NAME}: turbo / button-spamming knocks you out.": "هشدار به ${NAME}: توربو/اسپم دادن شما را مسدود میکند"
},
"teamNames": {
"Bad Guys": "تیم حریف",
"Bad Guys": "آدم بد ها",
"Blue": "آبی",
"Good Guys": "تیم خودی",
"Good Guys": "آدم خوب ها",
"Red": "قرمز"
},
"tips": {
"A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "یه مشت جهشی پرشی چرخشی با زمان بندی درست ، با یه ضربه حریف رو نابود میکنه\n! از این حرکتا بزن بعدش برا دوستات تعریف کن",
"Always remember to floss.": "حرفه‌ای باش، بَرنده باش..",
"Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "برای خودت و دوستات نمایه بساز تا مجبور نشی\n.از «بازیکنان تصادفی» خودِ بازی استفاده کنی",
"A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "یه مشت جهشی-پرشی-چرخشی با زمان بندی درست، با یه ضربه حریف رو نابود میکنه\nاز این حرکتا بزن بعدش برا دوستات تعریف کن",
"Always remember to floss.": "...حرفه ای باش، برنده باش",
"Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "برای خودت و دوستات پروفایل بساز تا مجبور نشی\n.از اسم های شانسی خودِ بازی استفاده کنی",
"Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "جعبه ی مرگ تو رو تبدیل به یه بمب ساعتی می کنه\nاگه می خوای زنده بمونی باید سریع یه جعبه درمان بگیری",
"Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "تمام کارکتر های بازی دارای توانایی های یکسانی هستند بنابراین شما فقط کافیه\nنزدیکترین کارکتر به شخصیت خودتون رو انتخاب و پیکربندی کنید",
"Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "فکر میکنی با گرفتن ضد ضربه شکست ناپذیر میشی ؟ اگه از زمین پرت بشی پایین چی ؟",
"Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "فکر میکنی با گرفتن شیلد شکست ناپذیر میشی ؟ اگه از زمین پرت بشی پایین چی ؟",
"Don't run all the time. Really. You will fall off cliffs.": "تمام وقت درطول بازی با سرعت حرکت نکنید ممکنه از صخره پرت بشید",
"Don't spin for too long; you'll become dizzy and fall.": "زیاد به دور خودت نچرخ؛ سرگیجه می‌گیری و می‌افتی.",
"Hold any button to run. (Trigger buttons work well if you have them)": "هر دکمه رو با زدن روش کار میکنه همه دکمه ها بدرستی کار میکنه اگه صحیح زده بشن",
@ -1757,7 +1762,7 @@
"You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "شما می تونید مشت های خودتون رو به جهت مشخصی وارد کنید با چرخیدن به چپ و راست\nاین کار برای پرت کردن دشمنان از لبه ی زمین به پایین یا امتیاز گرفت در هاکی موثره",
"You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "با دیدن رنگ جرقه ی بمب میشه فهمید چه موقع منفجر میشه\n!!!! زرد ... نارنجی ... قرمز ... بوم",
"You can throw bombs higher if you jump just before throwing.": "شما می‌تونید بمب‌هاتون رو دورتر پرتاب کنید اگه همزمان با یه پرش به موقع باشه",
"You take damage when you whack your head on things,\nso try to not whack your head on things.": "شما آسیب می بینید زمانی که سرتون به چیزی برخورد میکنه پس بیشر احتیاط کنید\nزمانی هم که چیزی به سمتتون پرتاب میشه",
"You take damage when you whack your head on things,\nso try to not whack your head on things.": "اگه سرت به جایی برخورد کنه آسیب میبینی،\n .پس سعی کن سرت به جایی نخوره",
"Your punches do much more damage if you are running or spinning.": "مشت هاتون موثر تر خواهند بود اگر هنگام حرکت سریع و یا چرخش وارد بشن"
}
},
@ -1767,71 +1772,71 @@
"tutorial": {
"cpuBenchmarkText": "آموزش اجرای بهتر بازی در بدترین وضعیت سرعت بازی در درجه اول تست سرعت پردازنده",
"phrase01Text": "!سلام جیگر",
"phrase02Text": "! خوش آمدی ${APP_NAME} به",
"phrase03Text": ". قبل از شروع ، یک سری آموزش ها هست که باید ببینی",
"phrase04Text": "متکی به اعمال فیزیکی اند ${APP_NAME} چیزای زیادی در",
"phrase05Text": "... مثلا وقتی با مشت میفتی به جون یه نفر",
"phrase06Text": "! این جوری حتی خون از دماغش نمیاد",
"phrase07Text": "... چجوری برات دلقک بازی در میاره ${NAME} نگاه کن",
"phrase08Text": ".باید حالشو بگیری ! پرش و چرخش قدرت مشت رو بیشتر می کنه",
"phrase09Text": "! آهان ! حالا شد",
"phrase02Text": "به ${APP_NAME} خوش اومدی!",
"phrase03Text": "اینا چندتا آموزش برای کنترل شخصیتت هستن:",
"phrase04Text": ".بر پایه فیزیک هستن ${APP_NAME} بیشتر چیز ها توی",
"phrase05Text": "...مثلا وقتی که مشت میزنی",
"phrase06Text": ".آسیب ها بر اساس سرعت حرکت مشتت هستن",
"phrase07Text": "...چجوری برات دلقک بازی در میاره ${NAME} نگاه کن",
"phrase08Text": ".باید حالشو بگیری! حالا باید بپری و بچرخی تا سرعت بگیری",
"phrase09Text": ".آهان، حالا بهتر شد",
"phrase10Text": ".دویدن هم موثره",
"phrase11Text": "برای دویدن باید یه دکمه ی دلخواه رو فشار بدی و نگه داری",
"phrase12Text": "! دویدن و چرخیدن باعث میشه که فکش بیاد پایین",
"phrase13Text": "اومد پایین ؟ ${NAME} دیدی چطوری فک",
"phrase14Text": "${NAME} خیلی چیزها رو میشه بلند کرد و پرت کرد . یعنی پرچم یا بازیکنهای دیگه مثل",
"phrase15Text": "! حالا وقت بمبارون کردنه",
"phrase16Text": "بمب انداختن یه کم تمرین لازم داره",
"phrase17Text": "این چه طرز بمب انداختنه ؟",
"phrase18Text": "اگه حرکت کنی بمب دورتر پرت میشه",
"phrase19Text": "اگه بپری بمب بیشتر پرت میشه",
"phrase20Text": "! اگه به صورت شلاقی بمب پرت کنی که دیگه هیچی ... نمی دونی تا کجا میره",
"phrase21Text": "این که چه موقع پرتش کنی خیلی مهمه",
"phrase22Text": "!!! بوم",
"phrase23Text": "قبل از انداختن بمب یه کم نگهش دار ... تا به محض این که به هدف رسید بترکه",
"phrase24Text": "باریکلا ! به این میگن انفجار",
"phrase25Text": "دیدی اصلا سخت نبود ؟",
"phrase26Text": "حالا دیگه مثل یه ببر قوی شدی",
"phrase11Text": "برای دویدن یه دکمه رو نگه دار و حرکت کن.",
"phrase12Text": "اگه میخوای یه مشت خفن بزنی که فکّش بیاد پایین، باید بدویی و بچرخی.",
"phrase13Text": ".${NAME} اوخ، بابت اینکه فکّت اومد پایین ببخشید",
"phrase14Text": ".${NAME} خیلی چیزها رو میشه برداشت و پرتاب کرد. مثل پرچم... یا",
"phrase15Text": "حالا وقتشه، وقت بمب هاست.",
"phrase16Text": "بمب انداختن یه کم تمرین لازم داره.",
"phrase17Text": "اوخ اوخ! اصلا پرتاب خوبی نبود.",
"phrase18Text": "حرکت کردن باعث میشه تا بتونی دورتر پرتاب کنی.",
"phrase19Text": "پریدن باعث میشه تا بمب بیشتر ارتفاع بگیره.",
"phrase20Text": "اگه موقع پرتاب بچرخی که بیشتر پرت میشه ولی ممکنه ندونی کجا فرود میاد.",
"phrase21Text": "زمانبندی برای پرتاب بمب میتونه چالشی باشه.",
"phrase22Text": "لعنتی.",
"phrase23Text": "قبل از انداختن بمب یکم صبر کن تا فیتیله‌ش بسوزه و بعد پرتابش کن.",
"phrase24Text": "هورا! پخته شد.",
"phrase25Text": "خب، اینم از همه چیز هایی که باید بدونی.",
"phrase26Text": "حالا مثل یه ببر همه رو نابود کن.",
"phrase27Text": "این آموزش ها رو به یاد داشته باش، و مطمئن باش که زنده برمی‌گردی!",
"phrase28Text": "! ببینم چند مرده حلاجی پهلوون",
"phrase29Text": "! خدا قوت",
"randomName1Text": "فرد",
"randomName2Text": "هری",
"randomName3Text": یل",
"randomName4Text": "چاک",
"randomName5Text": "فیل",
"skipConfirmText": ".واقعا از آموزش رد می‌شی ؟ هر کلیدی رو بزن تا رد بشیم",
"phrase28Text": "خب... شاید زنده برگردی...",
"phrase29Text": "به هر حال موفق باشی.",
"randomName1Text": "فریدون",
"randomName2Text": "حشمت",
"randomName3Text": رزو",
"randomName4Text": "حیدر",
"randomName5Text": "سیروس",
"skipConfirmText": ".واقعا میخوای از آموزش رد بشی؟ هر کلیدی رو بزن تا رد بشیم",
"skipVoteCountText": "نفر خواستار رد شدن از آموزش هستند ${TOTAL} نفر از ${COUNT}",
"skippingText": "از آموزش می گذریم",
"toSkipPressAnythingText": "هر کلیدی را بزنید تا از آموزش خارج شوید"
"skippingText": "رد شدن از آموزش...",
"toSkipPressAnythingText": "(هر کلیدی را بزنید تا از آموزش خارج شوید)"
},
"twoKillText": "نابودی دونفر همزمان",
"unavailableText": "چیزی در دسترس نیست",
"twoKillText": "کشتن همزمان دونفر",
"unavailableText": "در دسترس نیست",
"unconfiguredControllerDetectedText": ":کنترول پیکربندی نشده شناسایی شد",
"unlockThisInTheStoreText": ". این مورد باید در فروشگاه باز شود",
"unlockThisProfilesText": "برای ایجاد بیش از ${NUM} پروفال٫ احتیاج به این موارد دارید:",
"unlockThisText": ": برا باز کردن قفل این شما نیاز دارید که",
"unsupportedHardwareText": "با عرض پوزش، این سخت افزار توسط این ساخت بازی پشتیبانی نمی شود.",
"upFirstText": "برای بار اول :",
"upFirstText": "برای بار اول:",
"upNextText": "${COUNT} بعدی در بازی",
"updatingAccountText": "... در حال به‌روزرسانی حساب",
"upgradeText": "ارتقا",
"upgradeToPlayText": "بازی را خریداری کنید تا این گزینه فعال شود ${PRO} نسخه ی",
"upgradeToPlayText": "بازی را از فروشگاه خریداری کنید تا این قابلیت فعال شود. ${PRO} نسخه ی",
"useDefaultText": "استفاده از پیش فرض",
"usesExternalControllerText": "این بازی از یک کنترلر خارجی برای ورودی استفاده می کند.",
"usingItunesText": "استفاده از برنامه ی موسیقی برای موسیقی متن",
"usingItunesText": "استفاده از برنامه ی موسیقی برای موسیقی متن...",
"usingItunesTurnRepeatAndShuffleOnText": "مطمین شید که شافل روشن است و تکرار کنید همه رو در آیتونز",
"v2AccountLinkingInfoText": "برای پیوند دادن حساب‌های V2، از دکمه «مدیریت حساب» استفاده کنید.",
"validatingTestBuildText": "... در حال بررسی حالت آزمایشی",
"victoryText": "! برنده شدی",
"victoryText": "پیروز شدی!",
"voteDelayText": ".ثانیه رای گیری کنید ${NUMBER} شما نمیتوانید به مدت",
"voteInProgressText": ".یک رای گیری در حال انجام است",
"votedAlreadyText": ".شما رای داده اید",
"votesNeededText": ".رای نیاز است ${NUMBER}",
"vsText": "علیه",
"waitingForHostText": "ادامه بدهد ${HOST} صبر می کنیم تا",
"vsText": "در برابر",
"waitingForHostText": "(ادامه بدهد ${HOST} صبر کنید تا)",
"waitingForPlayersText": "...انتظار برای پیوستن بازیکنان",
"waitingInLineText": "در صف انتظار(پارتی تکمیل است) ...",
"waitingInLineText": "در صف انتظار (پارتی تکمیل است) ...",
"watchAVideoText": "یک ویدئو ببینید",
"watchAnAdText": "تبلیغ ببین",
"watchWindow": {
@ -1868,7 +1873,7 @@
"listenText": "گوش بده",
"macInstructionsText": "اطمینان حاصل کنید که رشته خود خاموش است و بلوتوث را فعال کنید\nدر مک خود را، و سپس دکمه \"گوش دهید\". پشتیبانی Wiimote می توانید\nیک کمی پوسته پوسته، بنابراین شما ممکن است باید سعی کنید چند بار\nقبل از شما یک اتصال.\nبلوتوث باید به 7 دستگاه های متصل رسیدگی کردن،\nهر چند مسافت پیموده شده شما ممکن است متفاوت باشد.\n\nBombSquad پشتیبانی از Wiimotes اصلی، Nunchuks،\nو کنترل کلاسیک.\nجدیدتر رشته از راه دور علاوه در حال حاضر بیش از حد کار\nاما با فایل پیوست است.",
"thanksText": "تشکر از تیم ناظر\nبرای ایجاد این امکان",
"titleText": "Wiimote Setup"
"titleText": "Wiimote راه اندازی"
},
"winsPlayerText": "${NAME} برنده شد",
"winsTeamText": "${NAME} برنده شد",
@ -1879,7 +1884,7 @@
"worldsBestScoresText": "بهترین امتیازهای جهانی",
"worldsBestTimesText": "بهترین زمان های جهانی",
"xbox360ControllersWindow": {
"getDriverText": "درایور",
"getDriverText": "دریافت درایور",
"macInstructions2Text": "برای استفاده از کنترلرها به صورت بی سیم، شما همچنین باید گیرنده را دریافت کنید\nXbox 360 Wireless Controller for Windows می آید.\nیک گیرنده به شما اجازه می دهد تا تا 4 کنترل کننده را وصل کنید.\n\nمهم: گیرنده های شخص ثالث با این راننده کار نخواهند کرد؛\nاطمینان حاصل کنید که گیرنده شما \"مایکروسافت\" را در آن می گوید، نه \"XBOX 360\".\nمایکروسافت این را به طور جداگانه به فروش نمی رساند، بنابراین شما باید آن را دریافت کنید\nیک همراه با کنترلر و یا دیگری جستجو بی.\n\nاگر این مفید را پیدا کنید، لطفا کمک مالی به آن بدهید\nتوسعه دهنده راننده در سایت خود.",
"macInstructionsText": "برای استفاده از کنترلر Xbox 360، باید نصب کنید\nدرایور Mac موجود در لینک زیر است.\nبا کنترلر های سیمی و بی سیم کار می کند.",
"macInstructionsTextScale": 0.8,

View file

@ -339,6 +339,7 @@
"getMoreGamesText": "Więcej rozgrywek...",
"titleText": "Dodaj grę"
},
"allText": "Wszystko",
"allowText": "Zezwól",
"alreadySignedInText": "Twoje konto jest zalogowane z innego urządzenia;\nproszę zmienić konta lub zamknąć grę na innych\nurządzeniach i spróbować ponownie.",
"apiVersionErrorText": "Nie mogę załadować modułu ${NAME}; wersja używana - ${VERSION_USED}; wymagana - ${VERSION_REQUIRED}.",
@ -577,6 +578,7 @@
"disableRemoteAppConnectionsText": "Wyłącz łączenia aplikacji BS-Remote",
"disableXInputDescriptionText": "Pozwala na podłączenie 4 kontrolerów, ale może nie działać.",
"disableXInputText": "Wyłącz XInput",
"disabledText": "Wyłączone",
"doneText": "Gotowe",
"drawText": "Remis",
"duplicateText": "Duplikuj",
@ -649,6 +651,7 @@
"useMusicFolderText": "Katalog plików muzycznych"
},
"editText": "Edytuj",
"enabledText": "Włączone",
"endText": "Koniec",
"enjoyText": "Miłej zabawy!",
"epicDescriptionFilterText": "${DESCRIPTION} Epickie zwolnione tempo.",
@ -1279,7 +1282,7 @@
"runBoldText": "URUCHOM",
"runText": "Uruchom",
"saveText": "Zapisz",
"scanScriptsErrorText": "Błąd w skanowaniu skryptów; sprawdź konsolę dla szczegółów",
"scanScriptsErrorText": "Błąd w skanowaniu skryptów; Sprawdź konsolę dla szczegółów",
"scoreChallengesText": "Wyzwania Punktowe",
"scoreListUnavailableText": "Lista wyników niedostępna.",
"scoreText": "Wynik",

View file

@ -339,6 +339,7 @@
"getMoreGamesText": "Mais jogos...",
"titleText": "Adicionar jogo"
},
"allText": "Tudo",
"allowText": "Permitir",
"alreadySignedInText": "A conta tem sessão iniciada em outro dispositivo;\nMude de conta ou feche o jogo no seu\noutro dispositivo e tente novamente.",
"apiVersionErrorText": "Não é possível carregar o módulo ${NAME}; ele é destinado à versão ${VERSION_USED}; exigimos a ${VERSION_REQUIRED}.",
@ -586,6 +587,7 @@
"disableRemoteAppConnectionsText": "Desativar conexões do aplicativo BombSquad Remote",
"disableXInputDescriptionText": "Permite mais de 4 controles mas pode não funcionar bem.",
"disableXInputText": "Desativar XInput",
"disabledText": "Desabilitado",
"doneText": "Concluído",
"drawText": "Empate",
"duplicateText": "Duplicar",
@ -659,6 +661,7 @@
"useMusicFolderText": "Pasta de arquivos de música"
},
"editText": "Editar",
"enabledText": "Abilitado",
"endText": "Fim",
"enjoyText": "Aproveite!",
"epicDescriptionFilterText": "${DESCRIPTION} em câmera lenta épica.",
@ -1300,7 +1303,9 @@
"revertText": "Reverter",
"runText": "Correr",
"saveText": "Salvar",
"scanScriptsErrorText": "Erro ao ler scripts; verifica o Log para mais informações",
"scanScriptsErrorText": "Erro(s) de verificação de scripts; consulte o registro para obter mais detalhes.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} e ${NUM} e outro(s) módulo(s) precisam de atualizações paro o api ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} precisa ser atualizado para api${API}.",
"scoreChallengesText": "Desafios de Pontuação",
"scoreListUnavailableText": "Lista de pontuação indisponível.",
"scoreText": "Pontuação",
@ -1480,16 +1485,16 @@
"Agent Johnson": "Agente Johnson",
"B-9000": "B-9000",
"Bernard": "Bernardo",
"Bones": "Bones",
"Bones": "Ossos",
"Butch": "Butch",
"Easter Bunny": "Coelho de Páscoa",
"Easter Bunny": "Coelho da Páscoa",
"Flopsy": "Flopsy",
"Frosty": "Frosty",
"Gretel": "Gretel",
"Grumbledorf": "Grumblodor",
"Grumbledorf": "Grumboldor",
"Jack Morgan": "Jack Morgan",
"Kronk": "Kronk",
"Lee": "Sotavento",
"Lee": "Lee",
"Lucky": "Lucky",
"Mel": "Mel",
"Middle-Man": "Homenzinho",
@ -1498,7 +1503,7 @@
"Pixel": "Pixel",
"Sammy Slam": "Sammy Slam",
"Santa Claus": "Papai Noel",
"Snake Shadow": "Serpente sombria",
"Snake Shadow": "Serpente Sombria",
"Spaz": "Spaz",
"Taobao Mascot": "Mascote da Taobao",
"Todd": "Teddy",

View file

@ -7,12 +7,12 @@
"campaignProgressText": "Прогресс кампании [Сложный режим]: ${PROGRESS}",
"changeOncePerSeason": "Вы можете изменить это только раз в сезон.",
"changeOncePerSeasonError": "Вы должны подождать до следующего сезона, чтобы изменить это снова (${NUM} дней)",
"customName": "Имя аккаунта",
"customName": "имя пользователя",
"deviceSpecificAccountText": "Сейчас используется аккаунт имениустройства: ${NAME}",
"googlePlayGamesAccountSwitchText": "Если хотите сменить внутриигровой аккаунт Google, используйте приложение Google Play.",
"linkAccountsEnterCodeText": "Введите код",
"linkAccountsGenerateCodeText": "Сгенерировать код",
"linkAccountsInfoText": "(делиться достижениями с другими платформами)",
"linkAccountsInfoText": "(поделитесь достижениями с другими платформами)",
"linkAccountsInstructionsNewText": "Чтобы связать два аккаунта, сгенерируйте код на первом\nи введите этот код на втором. Данные из\nвторого аккаунта будут распределены между ними.\n(Данные из первого будут потеряны)\n\nВы можете связать ${COUNT} аккаунтов.\n\nВАЖНО: связывайте только собственные аккаунты;\nЕсли вы свяжетесь с аккаунтами друзей, вы не сможете\nодновременно играть онлайн.",
"linkAccountsInstructionsText": "Для связки двух аккаунтов, создайте код на одном\nиз них и введите код на другом.\nПрогресс и инвентарь будут объединены.\nВы можете связать до ${COUNT} аккаунтов.",
"linkAccountsText": "Связать акаунты",
@ -23,7 +23,7 @@
"resetProgressConfirmNoAchievementsText": "Это сбросит весь ваш кооперативный прогресс\nи локальные рекорды (но не билеты).\nЭтот процесс необратим. Вы уверены?",
"resetProgressConfirmText": "Это сбросит весь ваш кооперативный\nпрогресс, достижения и локальные рекорды\n(кроме билетов). Этот процесс необратим.\nВы уверены?",
"resetProgressText": "Сбросить прогресс",
"setAccountName": "Задать имя аккаунта",
"setAccountName": "Напишите имя аккаунта",
"setAccountNameDesc": "Выберите имя для отображения своего аккаунта.\nВы можете использовать имя одного из ваших связанных аккаунтов или создать уникальное имя аккаунта.",
"signInInfoText": "Войдите в аккаунт, чтобы собирать билеты, \nсоревноваться онлайн и делиться успехами.",
"signInText": "Войти",
@ -55,10 +55,10 @@
"achievementText": "Достижение",
"achievements": {
"Boom Goes the Dynamite": {
"description": "Убейте 3 негодяев с помощью TNT",
"description": "Убейте 3 плохих парней с помощью TNT",
"descriptionComplete": "С помощью TNT убито 3 негодяев",
"descriptionFull": "Убейте 3 негодяев с помощью TNT на уровне ${LEVEL}",
"descriptionFullComplete": "3 негодяя убито с помощью TNT на уровне ${LEVEL}",
"descriptionFullComplete": "3 плохих парней убито с помощью TNT на уровне ${LEVEL}",
"name": "Динамит делает “БУМ”!"
},
"Boxer": {
@ -127,16 +127,16 @@
},
"Mine Games": {
"description": "Убейте 3 плохих парней с помощью мин",
"descriptionComplete": "С помощью мин убито 3 негодяя",
"descriptionComplete": "С помощью мин убито 3 плохих парней",
"descriptionFull": "Убейте 3 негодяев с помощью мин на уровне ${LEVEL}",
"descriptionFullComplete": "С помощью мин убито 3 негодяя на уровне ${LEVEL}",
"name": "Игры с минами"
},
"Off You Go Then": {
"description": "Сбросьте 3 негодяев с карты",
"descriptionComplete": "С карты сброшено 3 негодяя",
"descriptionFull": "Сбросьте 3 негодяев с карты на уровне ${LEVEL}",
"descriptionFullComplete": "3 негодяя сброшено с карты на уровне ${LEVEL}",
"description": "Сбросьте 3 плохих парней с карты",
"descriptionComplete": "С карты сброшено 3 плохих парней",
"descriptionFull": "Сбросьте 3 плохих парней с карты на уровне ${LEVEL}",
"descriptionFullComplete": "3 плохих парней сброшено с карты на уровне ${LEVEL}",
"name": "Пора учится летать"
},
"Onslaught God": {
@ -340,6 +340,7 @@
"getMoreGamesText": "Еще игры",
"titleText": "Добавить игру"
},
"allText": "Все",
"allowText": "Разрешить",
"alreadySignedInText": "С вашего аккаунта играют на другом устройстве;\nпожалуйста зайдите с другого аккаунта или закройте\nигру на другом устройстве и попытайтесь снова.",
"apiVersionErrorText": "Невозможно загрузить модуль ${NAME}; он предназначен для API версии ${VERSION_USED}; здесь требуется версия ${VERSION_REQUIRED}.",
@ -391,7 +392,7 @@
},
"configGamepadSelectWindow": {
"androidNoteText": "Внимание: поддержка геймпада различается в зависимости от устройства и версии Android.",
"pressAnyButtonText": "Нажмите любую кнопку на геймпаде,\n которую хотите настроить...",
"pressAnyButtonText": "Нажмите любую кнопку на геймпаде,\n Что-бы настроить геймпад...",
"titleText": "Настроить геймпад"
},
"configGamepadWindow": {
@ -408,7 +409,7 @@
"extraStartButtonText": "Настроить дополнительную кнопку \"Start\"",
"ifNothingHappensTryAnalogText": "Если ничего не происходит, попробуйте вместо этого присвоить аналоговому стику.",
"ifNothingHappensTryDpadText": "Если ничего не происходит, попробуйте вместо этого присвоить D-Pad.",
"ignoreCompletelyDescriptionText": "(запретить геймпаду воздействовать на игру, или меню)",
"ignoreCompletelyDescriptionText": "(запретить геймпаду управлять на игрой, или менюшкой)",
"ignoreCompletelyText": "Игнорировать полностью",
"ignoredButton1Text": "Игнорируемая кнопка 1",
"ignoredButton2Text": "Игнорируемая кнопка 2",
@ -580,6 +581,7 @@
"disableRemoteAppConnectionsText": "Отключить соединения RemoteApp",
"disableXInputDescriptionText": "Позволяет подключение более 4 контроллеров, но может не очень хорошо работать.",
"disableXInputText": "Отключить XInput",
"disabledText": "Отключено",
"doneText": "Готово",
"drawText": "Ничья",
"duplicateText": "Дублировать",
@ -653,6 +655,7 @@
"useMusicFolderText": "Папка с музыкой"
},
"editText": "Редактировать",
"enabledText": "Включено",
"endText": "Конец",
"enjoyText": "Удачи!",
"epicDescriptionFilterText": "${DESCRIPTION} в эпическом замедленном действии.",
@ -1281,7 +1284,9 @@
"revertText": "Восстановить",
"runText": "Бежать",
"saveText": "Сохранить",
"scanScriptsErrorText": "Ошибка(и) сканирования скриптов; посмотри лог для подробностей.",
"scanScriptsErrorText": "Ошибка(и) сканирования скриптов. Загляни в логи для подробностей.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} и ${NUM} других мод(ов) нужно обновить до ${API}",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} Нужно обновить до ${API}",
"scoreChallengesText": "Медали за очки",
"scoreListUnavailableText": "Список очков недоступен.",
"scoreText": "Очки",
@ -1501,13 +1506,13 @@
"${GAME} Training": "${GAME}: тренировка",
"Infinite ${GAME}": "Бесконечный уровень ${GAME}",
"Infinite Onslaught": "Бесконечная атака",
"Infinite Runaround": "Бесконечная беготня",
"Infinite Runaround": "Бесконечный побег",
"Onslaught": "Бесконечная атака",
"Onslaught Training": "Атака: тренировка",
"Pro ${GAME}": "${GAME} профи",
"Pro Football": "Регби профи",
"Pro Onslaught": "Атака профи",
"Pro Runaround": "Беготня профи",
"Pro Runaround": "Побег профи",
"Rookie ${GAME}": "${GAME} для новичков",
"Rookie Football": "Регби для новичков",
"Rookie Onslaught": "Атака для новичков",
@ -1516,7 +1521,7 @@
"Uber ${GAME}": "Убер ${GAME}",
"Uber Football": "Убер регби",
"Uber Onslaught": "Убер атака",
"Uber Runaround": "Убер беготня"
"Uber Runaround": "Убер побег"
},
"gameDescriptions": {
"Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Чтобы победить, стань избранным на некоторое время.\nЧтобы стать избранным, убей избранного.",
@ -1590,7 +1595,7 @@
"Ninja Fight": "Бой с ниндзя",
"Onslaught": "Атака",
"Race": "Гонка",
"Runaround": "Обход",
"Runaround": "Побег",
"Target Practice": "Стрельба по мишеням",
"The Last Stand": "Последний рубеж"
},
@ -1968,7 +1973,7 @@
"winsText": "${NAME} выиграл!",
"workspaceSyncErrorText": "Ошибка при попытке синхронизации ${WORKSPACE}. Посмотрите лог для информации.",
"workspaceSyncReuseText": "Не получается синхронизировать ${WORKSPACE}. Используется прошлая синхронизация.",
"worldScoresUnavailableText": "Мировые результаты недоступны.",
"worldScoresUnavailableText": "Мировые рекорды не доступны",
"worldsBestScoresText": "Лучшие в мире очки",
"worldsBestTimesText": "Лучшее в мире время",
"xbox360ControllersWindow": {

View file

@ -8,6 +8,7 @@
"changeOncePerSeason": "Toto môžete zmeniť len raz za sezónu.",
"changeOncePerSeasonError": "Musíte počkať do ďalšej sezóny aby ste mohli toto znova zmeniť (${NUM} days)",
"customName": "Vlastný názov",
"googlePlayGamesAccountSwitchText": "Ak chcete použiť iný účet Google,\nna jeho výmenu použite aplikáciu hry Google Play.",
"linkAccountsEnterCodeText": "Vložte kód",
"linkAccountsGenerateCodeText": "Vygenerovať kód",
"linkAccountsInfoText": "(zdielajte postup medzi rôznymi platformami)",
@ -42,6 +43,7 @@
"titleText": "Konto",
"unlinkAccountsInstructionsText": "Vyberte účet, s ktorým chcete zrušiť prepojenie",
"unlinkAccountsText": "Zrušiť prepojenie účtov",
"unlinkLegacyV1AccountsText": "Odpojiť Staré (V1) Účty",
"v2LinkInstructionsText": "Pomocou tohto odkazu si vytvorte účet alebo sa prihláste.",
"viaAccount": "(cez účet ${NAME})",
"youAreLoggedInAsText": "Si prihlásený ako:",
@ -336,6 +338,7 @@
"getMoreGamesText": "Viac Hier...",
"titleText": "Pridať Hru"
},
"allText": "Všetko",
"allowText": "Povol",
"alreadySignedInText": "Tvoj účet je prihlásený z iného zariadenia;\nprosím prepni si účty alebo ukonči hru na\ntvojich ostatných zariadeniach a skús to znovu.",
"apiVersionErrorText": "Nemožno načítať modul ${NAME}; používa api-verziu ${VERSION_USED}; my potrebujeme ${VERSION_REQUIRED}.",
@ -549,7 +552,9 @@
"deleteText": "Vymazať",
"demoText": "Demo",
"denyText": "odmietnuť",
"deprecatedText": "Zastaralé",
"desktopResText": "Desktop Res",
"deviceAccountUpgradeText": "Upozornenie:\nSte pripojený v účte (${NAME}) typu zariarenie.\nÚčty takého typu budú odstránené v budúcej aktualizácii.\nAktualizujte to na V2 Účet keď chcete zachovať váš pokrok.",
"difficultyEasyText": "Jednoduchá",
"difficultyHardOnlyText": "Len Ťažký Mód",
"difficultyHardText": "Ťažké",
@ -1024,6 +1029,7 @@
"maxConnectionsText": "Maximum Pripojení",
"maxPartySizeText": "Maximálna Veľkosť Párty",
"maxPlayersText": "Maximum Hráčov",
"merchText": "Merch!",
"modeArcadeText": "Arkádový režim",
"modeClassicText": "Klasický režim",
"modeDemoText": "Demo režim",
@ -1063,6 +1069,7 @@
"notSignedInErrorText": "Ak toto chceš urobiť, musíš sa prihlásiť.",
"notSignedInGooglePlayErrorText": "Ak chceš toto urobiť, musíš sa prihlásiť do Google Play.",
"notSignedInText": "nie si prihlásený",
"notUsingAccountText": "Poznámka: ignoruje sa ${SERVICE} účet.\nChoďte na 'Účet -> Prihlásiť sa s ${SERVICE}' pokiaľ to chcete použiť.",
"nothingIsSelectedErrorText": "Nič nie je vybraté!",
"numberText": "#${NUMBER}",
"offText": "Vypnúť",
@ -1121,7 +1128,11 @@
"pleaseWaitText": "Prosím počkaj...",
"pluginClassLoadErrorText": "Chyba pri načítaní triedy doplnku '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Chyba pri iniciovaní doplnku '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "Nastavenia Pluginov",
"pluginsAutoEnableNewText": "Automaticky Aktivovať Nové Pluginy",
"pluginsDetectedText": "Bol zistený nový doplnok(ky). Reštartujte aby sa aktivovali, alebo ich nakonfigurte v nastaveniach.",
"pluginsDisableAllText": "Deaktivovať Všetky Pluginy",
"pluginsEnableAllText": "Aktivovať Všetky Pluginy",
"pluginsRemovedText": "${NUM} doplnok(ky) nebol najdený.",
"pluginsText": "Pluginy",
"practiceText": "Tréning",
@ -1212,7 +1223,7 @@
"revertText": "Späť",
"runText": "Bežať",
"saveText": "Uložiť",
"scanScriptsErrorText": "Error pri skenovaní skriptov; pozri zápis pre detaily.",
"scanScriptsErrorText": "Chyba pri skenovaní skriptov. Pozri zápis pre detaily.",
"scoreChallengesText": "Challenge pre Skóre",
"scoreListUnavailableText": "List pre skóre je nedostupné.",
"scoreText": "Skóre",
@ -1256,6 +1267,7 @@
"netTestingText": "Testovanie Internetu",
"resetText": "Resetovať",
"showBombTrajectoriesText": "Ukázovať Trajektóriu Bomby",
"showInGamePingText": "Ukázať Ping v Hre",
"showPlayerNamesText": "Ukazovať Mená Hráčov",
"showUserModsText": "Ukázať Zložku pre Módy",
"titleText": "Pokročilé",
@ -1526,6 +1538,7 @@
"Italian": "Taliančina",
"Japanese": "Japončina",
"Korean": "Kórejčina",
"Malay": "Malajčina",
"Persian": "Perzština",
"Polish": "Poľština",
"Portuguese": "Portugálčina",
@ -1807,6 +1820,7 @@
"useDefaultText": "Použiť Štandartné",
"usesExternalControllerText": "Táto hra používa ako vstup externý ovládač.",
"usingItunesText": "Používam Music App ako soundtrack...",
"v2AccountLinkingInfoText": "Na prepojenie V2 účtov, použi tlačidlo 'Spravovať Účet'.",
"validatingTestBuildText": "Overujem Testovaciu Verziu...",
"victoryText": "Výhra!",
"voteDelayText": "Nemôžeš začať ďalšie hlasovanie v podobe ${NUMBER} sekúnd",
@ -1839,6 +1853,7 @@
},
"waveText": "Vlna",
"wellSureText": "Jasné!",
"whatIsThisText": "Toto je čo?",
"wiimoteLicenseWindow": {
"titleText": "DarwiinRemote Copyright"
},

File diff suppressed because it is too large Load diff

View file

@ -332,6 +332,7 @@
"getMoreGamesText": "மேலும் விளையாட்டுகளைப் பெறுங்கள்...",
"titleText": "விளையாட்டைச் சேர்"
},
"allText": "அனைத்து",
"allowText": "அனுமதி",
"alreadySignedInText": "உங்கள் கணக்கு மற்றொரு சாதனத்திலிருந்து உள்நுழைந்துள்ளது;\nதயவுசெய்து கணக்குகளை மாற்றவும் அல்லது விளையாட்டை மூடவும்\nபிற சாதனங்கள் மற்றும் மீண்டும் முயற்சிக்கவும்.",
"apiVersionErrorText": "${NAME} தொகுதியை ஏற்ற முடியவில்லை; இது api-version ${VERSION_USED} ஐ குறிவைக்கிறது; எங்களுக்கு ${VERSION_REQUIRED} தேவைப்படுகிறது.",
@ -558,6 +559,7 @@
"disableRemoteAppConnectionsText": "ரிமோட்-ஆப் இணைப்புகளை முடக்கு",
"disableXInputDescriptionText": "4 க்கும் மேற்பட்ட கட்டுப்பாட்டாளர்களை அனுமதிக்கிறது ஆனால் வேலை செய்யாமல் போகலாம்.",
"disableXInputText": "XInput ஐ முடக்கு",
"disabledText": "முடக்கப்பட்ட எழுத்து",
"doneText": "முடிந்தது",
"drawText": "டிரா",
"duplicateText": "நகல்எடுத்தல்",
@ -625,6 +627,7 @@
"useMusicFolderText": "இசை கோப்புகளின் கோப்புறை"
},
"editText": "மாற்று",
"enabledText": "செயல்படுத்த",
"endText": "முற்று",
"enjoyText": "மகிழ்!",
"epicDescriptionFilterText": "${DESCRIPTION} காவிய மெதுவான இயக்கத்தில்.",
@ -1124,7 +1127,11 @@
"pleaseWaitText": "தயவுசெய்து காத்திருங்கள்...",
"pluginClassLoadErrorText": "செருகுநிரல் வகுப்பை ஏற்றுவதில் பிழை '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "'${PLUGIN}' செருகுநிரலைத் தொடங்குவதில் பிழை: ${ERROR}",
"pluginSettingsText": "செருகுநிரல் அமைப்புகள்",
"pluginsAutoEnableNewText": "புதிய செருகுநிரல்களை தானாக இயக்கவும்",
"pluginsDetectedText": "புதிய செருகுநிரல்(கள்) கண்டறியப்பட்டது. அவற்றைச் செயல்படுத்த மீண்டும் தொடங்கவும் அல்லது அமைப்புகளில் உள்ளமைக்கவும்.",
"pluginsDisableAllText": "அனைத்து செருகுநிரல்களையும் முடக்கு",
"pluginsEnableAllText": "அனைத்து செருகுநிரல்களையும் இயக்கு",
"pluginsRemovedText": "${NUM} செருகுநிரல்(கள்) இனி காணப்படவில்லை.",
"pluginsText": "செருகுநிரல்கள்",
"practiceText": "பயிற்சி",
@ -1217,7 +1224,9 @@
"revertText": "பின்செல்",
"runText": "ஓடு",
"saveText": "சேமி",
"scanScriptsErrorText": "ஸ்கிரிப்ட்களை ஸ்கேன் செய்வதில் பிழை (கள்); விவரங்களுக்கு பதிவைப் பார்க்கவும்.",
"scanScriptsErrorText": "ஸ்கிரிப்ட்களை ஸ்கேன் செய்வதில் பிழை(கள்). விவரங்களுக்கு பதிவைப் பார்க்கவும்.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} மற்றும் ${NUM} பிற மாடுல்(கள்) APIக்காக புதுப்பிக்க படவேண்டும் ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} Api காக புதுப்பிக்க படவேண்டும் ${API}.",
"scoreChallengesText": "ஸ்கோர் சவால்கள்",
"scoreListUnavailableText": "மதிப்பெண் பட்டியல் கிடைக்கவில்லை.",
"scoreText": "மதிப்பெண் பெரு",
@ -1261,6 +1270,7 @@
"netTestingText": "நெட்வொர்க் சோதனை",
"resetText": "மீட்டு",
"showBombTrajectoriesText": "வெடிகுண்டு பாதைகளைக் காட்டு",
"showInGamePingText": "இன்-கேம் பிங்கைக் காட்டு",
"showPlayerNamesText": "பிளேயர் பெயர்களைக் காட்டு",
"showUserModsText": "மோட்ஸ் கோப்புறையைக் காட்டு",
"titleText": "மேம்பட்ட அமைப்புகள்",

View file

@ -11,7 +11,7 @@
"linkAccountsEnterCodeText": "ใส่รหัส",
"linkAccountsGenerateCodeText": "สร้างรหัส",
"linkAccountsInfoText": "(ใช้ความคืบหน้าร่วมกันกับแพลตฟอร์มอื่นๆ)",
"linkAccountsInstructionsNewText": "หากต้องการเชื่อมโยงสองบัญชีให้สร้างรหัสในบัญชีแรกและป้อนรหัสนั้นในวินาที ข้อมูลจากบัญชีที่สองจะถูกแชร์ระหว่างทั้งสอง(ข้อมูลจากบัญชีแรกจะหายไป): ${COUNT} ** .",
"linkAccountsInstructionsNewText": "หากต้องการเชื่อมโยงสองบัญชี ให้สร้างรหัสในบัญชีแรก\nและป้อนรหัสนั้นในบัญชีที่สอง ข้อมูลจาก\nบัญชีที่สองจะถูกแชร์ระหว่างทั้งสอง\n(ข้อมูลจากบัญชีแรกจะหายไป)\n\nคุณสามารถเชื่อมโยงได้ถึง ${COUNT} บัญชี\n\nข้อสำคัญ: เชื่อมโยงบัญชีที่คุณเป็นเจ้าของเท่านั้น\nหากคุณเชื่อมโยงกับบัญชีของเพื่อน คุณจะไม่ทำ\nสามารถเล่นออนไลน์ได้ในเวลาเดียวกัน",
"linkAccountsInstructionsText": "เพื่อที่จะผูกทั้งสองบัญชีเข้าด้วยกัน จะต้องสร้างรหัสรหัสหนึ่ง\nแล้วจะต้องใส่รหัสในบัญที่คุณต้องการจะเชื่อมโยงเข้าด้วยกัน\nความคืบหน้าและสิ่งของในคลังของทั้งสองบัญชีจะถูกรวมกัน\nคุณสามารถเชื่อมโยงได้ทั้งหมด ${COUNT} บัญชี\n\nระวัง! หลังจากผูกบัญชีแล้วจะไม่สามารถยกเลิกได้!",
"linkAccountsText": "ผูกบัญชี",
"linkedAccountsText": "บัญชีที่เชื่อมโยงแล้ว",
@ -21,7 +21,7 @@
"resetProgressConfirmText": "การทำสิ่งนี้จะรีเซ็ตความคืบหน้าในโหมด co-op,\nความสำเร็จและคะแนนดีที่สุดในอุปกรณ์นี้\n(แต่จะไม่รีเซ็ตตั๋วของคุณ) การทำสิ่งนี้จะ\nไม่สามารถยกเลิกได้! คุณแน่ใจหรือไม่?",
"resetProgressText": "รีเซ็ตความคืบหน้า",
"setAccountName": "ตั้งชื่อบัญชี",
"setAccountNameDesc": "เลือกชื่อที่จะแสดงสำหรับบัญชีของคุณคุณสามารถใช้ชื่อจากหนึ่งในการเชื่อมโยงของคุณบัญชีหรือสร้างชื่อที่กำหนดเองที่ไม่ซ้ำกัน:{Thanakorn}",
"setAccountNameDesc": "เลือกชื่อที่จะแสดงสำหรับบัญชีของคุณ\nคุณสามารถใช้ชื่อจากหนึ่งในบัญชีที่เชื่อมโยงของคุณ\nหรือสร้างชื่อที่กำหนดเองที่ไม่ซ้ำใคร",
"signInInfoText": "เข้าสู่ระบบเพื่อเก็บตั๋วในการเล่นแบบออนไลน์,\nและแบ่งปันความคืบหน้าของคุณกับอุปกรณ์อื่นๆ",
"signInText": "ลงชื่อเข้าใช้",
"signInWithDeviceInfoText": "(บัญชีอัตโนมัติที่ใช้ได้เฉพาะในอุปกรณ์นี้)",
@ -39,6 +39,7 @@
"titleText": "บัญชี",
"unlinkAccountsInstructionsText": "เลือกบัญชีที่จะยกเลิกการเชื่อมโยง",
"unlinkAccountsText": "ยกเลิกการเชื่อมโยงบัญชี",
"unlinkLegacyV1AccountsText": "ยกเลิกการเชื่อมโยงบัญชีแบบเก่า (V1)",
"v2LinkInstructionsText": "ใช้ลิงก์นี้เพื่อสร้างบัญชีหรือลงชื่อเข้าใช้",
"viaAccount": "ผ่านบัญชี ${NAME}",
"youAreSignedInAsText": "คุณลงชื่อเข้าใช้ในบัญชี:"
@ -1022,6 +1023,7 @@
"maxConnectionsText": "จำนวนผู้ที่เชื่อมต่อได้สูงสุด",
"maxPartySizeText": "จำนวนคนในปาร์ตี้สูงสุด",
"maxPlayersText": "ผู้เล่นที่เล่นได้สูงสุด",
"merchText": "สินค้า!",
"modeArcadeText": "โหมดอาเขต",
"modeClassicText": "โหมดคลาสสิก",
"modeDemoText": "โหมดสาธิต",
@ -1029,7 +1031,7 @@
"mostViolatedPlayerText": "ผู้เล่นที่ฆ่าน้อยที่สุด",
"mostViolentPlayerText": "ผู้เล่นที่ฆ่ามากที่สุด",
"moveText": "เคลื่อนไหว",
"multiKillText": "ฆ่า ${COUNT}!!!",
"multiKillText": "ฆ่า ${COUNT} คน!!!",
"multiPlayerCountText": "ผู้เล่น ${COUNT} คน",
"mustInviteFriendsText": "หมายเหตุ: คุณต้องเชิญเพื่อนใน\nแผง \"${GATHER}\" หรือไฟล์แนบ\nตัวควบคุมเพื่อเล่นหลายคน",
"nameBetrayedText": "${NAME} หักหลัง ${VICTIM}",
@ -1120,7 +1122,11 @@
"pleaseWaitText": "โปรดรอ...",
"pluginClassLoadErrorText": "เกิดข้อผิดพลาดในการโหลดคลาสปลั๊กอิน '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "เกิดข้อผิดพลาดในการเริ่มต้นปลั๊กอิน '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "การตั้งค่าปลั๊กอิน",
"pluginsAutoEnableNewText": "เปิดใช้งานปลั๊กอินใหม่โดยอัตโนมัติ",
"pluginsDetectedText": "ตรวจพบปลั๊กอินใหม่ รีสตาร์ทเกมเพื่อเปิดใช้งาน หรือกำหนดค่าได้ในการตั้งค่า",
"pluginsDisableAllText": "ปิดใช้งานปลั๊กอินทั้งหมด",
"pluginsEnableAllText": "เปิดใช้งานปลั๊กอินทั้งหมด",
"pluginsRemovedText": "ไม่พบปลั๊กอิน ${NUM} รายการอีกต่อไป",
"pluginsText": "ปลั๊กอิน",
"practiceText": "ฝึกฝน",
@ -1211,7 +1217,7 @@
"revertText": "ย้อนกลับ",
"runText": "วิ่ง",
"saveText": "บันทึก",
"scanScriptsErrorText": "ข้อผิดพลาดในการสแกนสคริปต์; ดูบันทึกสำหรับรายละเอียด",
"scanScriptsErrorText": "เกิดข้อผิดพลาดในการสแกนสคริปต์ ดูบันทึกสำหรับรายละเอียด",
"scoreChallengesText": "คะแนนความท้าทาย",
"scoreListUnavailableText": "ไม่มีรายการคะแนน",
"scoreText": "คะแนน",
@ -1255,6 +1261,7 @@
"netTestingText": "การทดสอบเครือข่าย",
"resetText": "รีเซ็ต",
"showBombTrajectoriesText": "แสดงวิถีลูกระเบิด",
"showInGamePingText": "แสดง Ping ในเกม",
"showPlayerNamesText": "แสดงชื่อผู้เล่น",
"showUserModsText": "แสดงโฟลเดอร์ Mods",
"titleText": "ขั้นสูง",
@ -1525,6 +1532,7 @@
"Italian": "ภาษาอิตาลี",
"Japanese": "ภาษาญี่ปุ่น",
"Korean": "ภาษาเกาหลี",
"Malay": "ภาษามาเลเซีย",
"Persian": "ภาษาเปอร์เซีย",
"Polish": "ภาษาโปแลนด์",
"Portuguese": "ภาษาโปรตุเกส",

View file

@ -334,6 +334,7 @@
"getMoreGamesText": "Daha Çok Oyun...",
"titleText": "Oyun Ekle"
},
"allText": "Hepsi",
"allowText": "Kabul Et",
"alreadySignedInText": "Başka bir cihazda hesabına giriş yapılmış;\nlütfen hesapları değiştir ya da diğer cihazlardaki\noyunu kapat ve tekrar dene.",
"apiVersionErrorText": "Modul yüklenemiyor ${NAME}; hedef api-versiyon ${VERSION_USED}; ihtiyacımız olan ${VERSION_REQUIRED}.",
@ -559,6 +560,7 @@
"disableRemoteAppConnectionsText": "Remote-App Bağlantılarını Engelle",
"disableXInputDescriptionText": "4 kontrolcüden fazla kullanılabilir fakat iyi çalışmayabilir.",
"disableXInputText": "XInput etkisizleştir",
"disabledText": "Kullanılmıyor",
"doneText": "Tamam",
"drawText": "Beraberlik",
"duplicateText": "Kopyala",
@ -626,6 +628,7 @@
"useMusicFolderText": "Müzik Dosyaları Klasörü"
},
"editText": "Düzenle",
"enabledText": "Onaylanmış",
"endText": "Bitir",
"enjoyText": "Keyfini Çıkar!",
"epicDescriptionFilterText": "${DESCRIPTION} epik ağırçekim.",
@ -1219,7 +1222,9 @@
"revertText": "Eski Haline Döndür",
"runText": "Koş",
"saveText": "Kaydet",
"scanScriptsErrorText": "Betikleri tararken hata oluştu; detaylar için logları kontrol edin.",
"scanScriptsErrorText": "Betik(ler) taranırken hata oluştu. Detaylar için logları kontrol edin.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} ve ${NUM} diğer modül(ler) api ${API} için güncellenmelidir.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} api ${API} için güncellenmelidir.",
"scoreChallengesText": "Mücadele Skoru",
"scoreListUnavailableText": "Skor listesi mevcut değil.",
"scoreText": "Skor",

View file

@ -336,6 +336,7 @@
"getMoreGamesText": "Ще ігри...",
"titleText": "Додати гру"
},
"allText": "Все",
"allowText": "Дозволити",
"alreadySignedInText": "На вашому акаунті грають на іншому пристрої;\nбудь ласка зайдіть з іншого акаунта або закрийте гру на\nіншому пристрої та спробуйте знову.",
"apiVersionErrorText": "Неможливо завантажити модуль ${NAME}; він призначений для API версії ${VERSION_USED}; потрібна версія ${VERSION_REQUIRED}.",
@ -560,6 +561,7 @@
"disableRemoteAppConnectionsText": "Відключення з'єднання RemoteApp",
"disableXInputDescriptionText": "Підключення більше 4 контролерів, але може не працювати.",
"disableXInputText": "Відключити XInput",
"disabledText": "Виключено",
"doneText": "Готово",
"drawText": "Нічия",
"duplicateText": "Дублювати",
@ -627,6 +629,7 @@
"useMusicFolderText": "Тека з музикою"
},
"editText": "Редагувати",
"enabledText": "Включено",
"endText": "Кінець",
"enjoyText": "Успіхів!",
"epicDescriptionFilterText": "${DESCRIPTION} в епічному сповільненій дії.",
@ -1221,6 +1224,8 @@
"runText": "Бігти",
"saveText": "Зберегти",
"scanScriptsErrorText": "Помилка(и) сканування скриптів; дивіться лог для деталей.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} і ${NUM} інших модулів потрібно оновити для api ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} потрібно оновити для api ${API}.",
"scoreChallengesText": "Медалі за очки",
"scoreListUnavailableText": "Список очок недоступний.",
"scoreText": "Очки",

View file

@ -38,6 +38,7 @@
"titleText": "Account",
"unlinkAccountsInstructionsText": "Sełesiona un account da descołegar",
"unlinkAccountsText": "Descołega account",
"unlinkLegacyV1AccountsText": "Descołega i account veci (V1)",
"v2LinkInstructionsText": "Acedi o dòpara 'sto link par crear un account.",
"viaAccount": "(doparando ${NAME})",
"youAreSignedInAsText": "Te zugarè cofà:"
@ -331,6 +332,7 @@
"getMoreGamesText": "Otien pì łevełi...",
"titleText": "Zonta zugo"
},
"allText": "Tuto",
"allowText": "Parmeti",
"alreadySignedInText": "El to account el ze in dòparo inte nantro\ndispozidivo: canbia account o sara sù el zugo\ninte chełaltro to dispozidivo e proa danovo.",
"apiVersionErrorText": "Inposìbiłe cargar el mòduło ${NAME}, el se refarise a ła varsion ${VERSION_USED}. Serve invese ła ${VERSION_REQUIRED}.",
@ -493,7 +495,7 @@
"toRankedText": "par ndar sù de pozision",
"totalText": "totałe",
"tournamentInfoText": "Conpeti co cheł'altri zugadori par\nndar sù de puntejo inte ła to łega.\n\nCo'l tornèo el fenirà, i zugadori pì\nbrai i vegnarà reconpensài co i premi.",
"welcome1Text": "Benrivài inte ła ${LEAGUE}. A te połi mejorar ła to\npozision vadagnando stełe inte i łevełi, conpletando\ni obietivi o vinsendo i trofèi inte i tornèi.",
"welcome1Text": "Benrivài inte ła ${LEAGUE}. Te połi mejorar ła to\npozision vadagnando stełe inte i łevełi, conpletando\ni obietivi o vinsendo i trofèi inte i tornèi.",
"welcome2Text": "Fazendo racuante atividà de 'sto tipo te połi anca vadagnar biłieti.\nI biłieti i połe èsar doparài par dezblocar parsonaji novi, łevełi e\nminizughi ma anca par ndar rento a tornèi o ver funsion in pì.",
"yourPowerRankingText": "Ła to pozision:"
},
@ -555,6 +557,7 @@
"disableRemoteAppConnectionsText": "Dezativa conesion co BombSquad Remote",
"disableXInputDescriptionText": "Dòpara pì de 4 controładori (ma co'l riscio che no i funsione ben).",
"disableXInputText": "Dezativa XInput",
"disabledText": "Dezativà",
"doneText": "Fato",
"drawText": "Pata",
"duplicateText": "Zdopia",
@ -622,6 +625,7 @@
"useMusicFolderText": "Carteła de file muzegałi"
},
"editText": "Muda",
"enabledText": "Ativà",
"endText": "Moła",
"enjoyText": "Profìtaghine e gòdateła!",
"epicDescriptionFilterText": "${DESCRIPTION} in movensa camoma.",
@ -711,7 +715,7 @@
"getFriendInviteCodeText": "Jènara còdaze de invido",
"googlePlayDescriptionText": "Invida zugadori de Google Play inte'l to grupo:",
"googlePlayInviteText": "Invida",
"googlePlayReInviteText": "Se A te mandi un invido novo el/i ${COUNT} zugador(i) de\nGoogle Play inte'l to grupo el/i vegnarà desconetesto/i.\nPar tegnerlo/i in grupo màndaghe anca a łù/łori l'invido novo.",
"googlePlayReInviteText": "Se te mandi un invido novo el/i ${COUNT} zugador(i) de\nGoogle Play inte'l to grupo el/i vegnarà desconetesto/i.\nPar tegnerlo/i in grupo màndaghe anca a łù/łori l'invido novo.",
"googlePlaySeeInvitesText": "Mostra invidi",
"googlePlayText": "Google Play",
"googlePlayVersionOnlyText": "(soło inte ła varsion Android / Google Play)",
@ -745,7 +749,7 @@
"partyInviteDeclineText": "Miga deso",
"partyInviteGooglePlayExtraText": "(varda el paneło 'Google Play' inte ła fenestra 'Crea grupo')",
"partyInviteIgnoreText": "Ignora",
"partyInviteText": "A te ze rivà un invido de ${NAME}\npar zontarte inte'l só grupo!",
"partyInviteText": "Te ze rivà un invido de ${NAME}\npar zontarte inte'l só grupo!",
"partyNameText": "Nome grupo",
"partyServerRunningText": "Server pa'l grupo ativo.",
"partySizeText": "grandesa",
@ -777,7 +781,7 @@
"wifiDirectText": "Wifi direto",
"worksBetweenAllPlatformsText": "(el funsiona intrà tute łe piataforme)",
"worksWithGooglePlayDevicesText": "(el funsiona co tuti i dispozidivi co ła varsion del zugo de Google Play par Android)",
"youHaveBeenSentAPromoCodeText": "A te ze stà mandà un còdaze promosionałe de ${APP_NAME}:"
"youHaveBeenSentAPromoCodeText": "Te ze stà mandà un còdaze promosionałe de ${APP_NAME}:"
},
"getTicketsWindow": {
"freeText": "GRATIS!",
@ -799,8 +803,8 @@
"unavailableTemporarilyText": "'Sta funsion no ła ze miga disponìbiłe par deso: proa danovo pì tardi.",
"unavailableText": "Ne despiaze, 'sta funsion no ła ze miga disponìbiłe.",
"versionTooOldText": "Ne despiaze, 'sta varsion ła ze masa vecia: ajorna el zugo co cheła nova.",
"youHaveShortText": "A te ghè ${COUNT}",
"youHaveText": "A te ghè ${COUNT} biłieti"
"youHaveShortText": "Te ghè ${COUNT}",
"youHaveText": "Te ghè ${COUNT} biłieti"
},
"googleMultiplayerDiscontinuedText": "Me despiaze, el sarviso multizugador de Google no'l ze miga pì disponìbiłe.\nA sò drio łaorar a un renpiaso pì in presa che se połe.\nIntanto proa n'antro mètodo de conesion.\n-Eric",
"googlePlayPurchasesNotAvailableText": "Łe cronpe vecie no łe ze miga disponìbiłi.\nPodarìa èsarghe bezogno de ajornar l'apl Google Play.",
@ -860,10 +864,10 @@
"powerupsSubtitleText": "Par forsa, gnaun zugo el sarìe conpleto sensa potensiadori:",
"powerupsText": "Potensiadori",
"punchInfoText": "- Crogno -\nPì che te te movi ràpidamente,\npì i to crogni i farà małe, donca\ncori, salta e và torno cofà un mato.",
"runInfoText": "- Corsa -\nTien strucà CALSÌASE boton par córar. I botoni de testa o i griłeti nałòzeghi i ze i pì adati se\nA te łi ghè. Corendo A te rivarè prima inte i posti ma sarà pì dura voltar, donca ocio a łe crode.",
"runInfoText": "- Corsa -\nTien strucà CALSÌASE boton par córar. I botoni de testa o i griłeti nałòzeghi i ze i pì adati se\nte łi ghè. Corendo te rivarè prima inte i posti ma sarà pì dura voltar, donca ocio a łe crode.",
"someDaysText": "In serti dì A se gà soło voja de tirarghe crogni a calcosa. O de farla saltar par aria.",
"titleText": "Istrusion de ${APP_NAME}",
"toGetTheMostText": "Par tirar fora el mejo da 'sto zugo A te serve:",
"toGetTheMostText": "Par tirar fora el mejo da 'sto zugo te serve:",
"welcomeText": "Benrivài so ${APP_NAME}!"
},
"holdAnyButtonText": "<tien strucà un boton calsìase>",
@ -880,8 +884,8 @@
"buttonText": "boton",
"cantKickHostError": "A no te połi miga parar vìa l'ospitador.",
"chatBlockedText": "${NAME} ze stà tajà fora da ła chat par ${TIME} segondi.",
"connectedToGameText": "A te te si zontà so '${NAME}'",
"connectedToPartyText": "A te te si zontà so'l grupo de ${NAME}!",
"connectedToGameText": "Te te si zontà so '${NAME}'",
"connectedToPartyText": "Te te si zontà so'l grupo de ${NAME}!",
"connectingToPartyText": "Conesion...",
"connectionFailedHostAlreadyInPartyText": "Conesion fałìa: l'ospitador el ze inte n'antro grupo.",
"connectionFailedPartyFullText": "Conesion fałìa: el grupo el ze pien.",
@ -913,9 +917,9 @@
"keyboardText": "Botonera",
"kickIdlePlayersKickedText": "Ze stà parà fora ${NAME} par masa sonera.",
"kickIdlePlayersWarning1Text": "Se ła só sonera ła sèvita, ${NAME} vegnarà parà fora tenpo ${COUNT} segondi.",
"kickIdlePlayersWarning2Text": "(A te połi dezativarlo so Inpostasion > Avansàe)",
"leftGameText": "A te si ndà fora da '${NAME}'.",
"leftPartyText": "A te si ndà fora da'l grupo de ${NAME}.",
"kickIdlePlayersWarning2Text": "(Te połi dezativarlo so Inpostasion > Avansàe)",
"leftGameText": "Te si ndà fora da '${NAME}'.",
"leftPartyText": "Te si ndà fora da'l grupo de ${NAME}.",
"noMusicFilesInFolderText": "Ła carteła no ła gà rento gnaun file muzegałe.",
"playerJoinedPartyText": "${NAME} l'se gà zontà inte'l grupo!",
"playerLeftPartyText": "${NAME} gà mołà el grupo!",
@ -979,13 +983,13 @@
"seasonEndsHoursText": "Ła stajon ła fenirà tenpo ${NUMBER} ore.",
"seasonEndsMinutesText": "Ła stajon ła fenirà tenpo ${NUMBER} menuti.",
"seasonText": "Stajon ${NUMBER}",
"tournamentLeagueText": "A te ghè da rivar inte ła łega ${NAME} par zugar inte 'sto tornèo.",
"tournamentLeagueText": "Par zugar inte 'sto tornèo te ghè da rivar inte ła łega ${NAME}.",
"trophyCountsResetText": "Par ła stajon che ła vien el puntejo\nde i trofèi el se zerarà."
},
"levelBestScoresText": "I punteji mejo so ${LEVEL}",
"levelBestTimesText": "I tenpi mejo so ${LEVEL}",
"levelIsLockedText": "${LEVEL} el ze blocà.",
"levelMustBeCompletedFirstText": "Prima A te ghè da conpletar ${LEVEL}.",
"levelMustBeCompletedFirstText": "Prima te ghè da conpletar ${LEVEL}.",
"levelText": "Łeveło ${NUMBER}",
"levelUnlockedText": "Łeveło dezblocà!",
"livesBonusText": "Vite bonus",
@ -1021,6 +1025,7 @@
"maxConnectionsText": "Łìmite conesion",
"maxPartySizeText": "Łìmite grandesa grupo",
"maxPlayersText": "Łìmite zugadori",
"merchText": "Marcansìa BombSquad!",
"modeArcadeText": "Modałidà arcade",
"modeClassicText": "Modałidà clàsega",
"modeDemoText": "Modałidà demo",
@ -1119,7 +1124,11 @@
"pleaseWaitText": "Speta n'àtemo...",
"pluginClassLoadErrorText": "Eror de cargamento de ła clase de estension '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Eror de inisiałizasion de l'estension '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "Inpostasion estension",
"pluginsAutoEnableNewText": "Ativa in automàtego łe estension nove",
"pluginsDetectedText": "Estension nove rełevàe. Retaca el zugo par ativarle, o configùrełe so łe inpostasion.",
"pluginsDisableAllText": "Dezativa tute łe estension",
"pluginsEnableAllText": "Ativa tute łe estension",
"pluginsRemovedText": "Estension miga catàe: ${NUM}",
"pluginsText": "Estension",
"practiceText": "Pràtega",
@ -1210,7 +1219,9 @@
"revertText": "Anuła",
"runText": "Cori",
"saveText": "Salva",
"scanScriptsErrorText": "Tirando sù i script A se gà catà erori: varda el rejistro eventi par i detaji.",
"scanScriptsErrorText": "Eror de scansion de i script: varda el rejistro eventi par i detaji.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} e ${NUM} n'antro/i mòduło/i el/i gà èsar ajornà/i par l'api ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} el gà èsar ajornà par l'api ${API}.",
"scoreChallengesText": "Puntejo sfide",
"scoreListUnavailableText": "Łista de puntejo mìa disponìbiłe.",
"scoreText": "Puntejo",
@ -1240,7 +1251,7 @@
"benchmarksText": "Prestasion & Proe soto sforso",
"disableCameraGyroscopeMotionText": "Dezativa movimento de ła prospetiva łigada a'l jiroscopio",
"disableCameraShakeText": "Dezativa i zgorlamenti de ła videocàmara",
"disableThisNotice": "(A te połi dezativar 'sta notìfega inte łe inpostasion avansàe)",
"disableThisNotice": "(Te połi dezativar 'sta notìfega inte łe inpostasion avansàe)",
"enablePackageModsDescriptionText": "(l'ativasion de ła capasidà de modifegasion ła dezativa el zugo in rede)",
"enablePackageModsText": "Ativa pacheti mod łogałi",
"enterPromoCodeText": "Insarisi còdaze",
@ -1254,6 +1265,7 @@
"netTestingText": "Proa de rede",
"resetText": "Reinposta",
"showBombTrajectoriesText": "Mostra trajetore bonbe",
"showInGamePingText": "Mostra łatensa de'l zugo",
"showPlayerNamesText": "Mostra nomi zugadori",
"showUserModsText": "Mostra carteła modifegasion",
"titleText": "Avansàe",
@ -1424,7 +1436,7 @@
},
"gameDescriptions": {
"Be the chosen one for a length of time to win.\nKill the chosen one to become it.": "Copa l'ełeto par ciapar el só posto!\nPar vìnsar resta l'ełeto par un serto tenpo.",
"Bomb as many targets as you can.": "Bonbarda tuti i sentri che A te pol!",
"Bomb as many targets as you can.": "Bonbarda tuti i sentri che te połi!",
"Carry the flag for ${ARG1} seconds.": "Tiente ła bandiera par ${ARG1} segondi.",
"Carry the flag for a set length of time.": "Tiente ła bandiera par un serto tenpo.",
"Crush ${ARG1} of your enemies.": "Copa ${ARG1} nemighi.",
@ -1524,6 +1536,7 @@
"Italian": "Itałian",
"Japanese": "Japoneze",
"Korean": "Corean",
"Malay": "Maleze",
"Persian": "Persian",
"Polish": "Połaco",
"Portuguese": "Portogheze",
@ -1603,7 +1616,7 @@
"Invalid purchase.": "Cronpa mìa vàłida.",
"Invalid tournament entry; score will be ignored.": "Entrada inte'l tornèo mìa vàłida: el puntejo el vegnarà ignorà.",
"Item unlocked!": "Ojeto dezblocà!",
"LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "COŁEGAMENTO REFUDÀ. ${ACCOUNT} el contien dati\ninportanti che i ndarà PERDESTI.\nSe te vołi A te połi cołegarli in òrdane raverso\n(e pèrdar a'l só posto i dati de 'STO account cuà).",
"LINKING DENIED. ${ACCOUNT} contains\nsignificant data that would ALL BE LOST.\nYou can link in the opposite order if you'd like\n(and lose THIS account's data instead)": "COŁEGAMENTO REFUDÀ. ${ACCOUNT} el contien dati\ninportanti che i ndarà PERDESTI.\nSe te vołi te połi cołegarli in òrdane raverso\n(e pèrdar a'l só posto i dati de 'STO account cuà).",
"Link account ${ACCOUNT} to this account?\nAll existing data on ${ACCOUNT} will be lost.\nThis can not be undone. Are you sure?": "Vutu dabon cołegar l'account ${ACCOUNT} a 'sto account?\nTuti i dati so ${ACCOUNT} i ndarà perdesti.\n'Sta asion no ła połe pì èsar anułada: vutu ndar vanti?",
"Max number of playlists reached.": "Nùmaro màsemo de łiste de scolto pasà.",
"Max number of profiles reached.": "Nùmaro màsemo de profiłi pasà.",
@ -1632,7 +1645,7 @@
"WARNING: complaints of hacking have been issued against your account.\nAccounts found to be hacking will be banned. Please play fair.": "AVERTENSA: el to account el ze stà segnałà par el dòparo de truchi.\nI zugaduri catài a doparar truchi i vegnarà blocài. Zuga da gałantomo.",
"Would you like to link your device account to this one?\n\nYour device account is ${ACCOUNT1}\nThis account is ${ACCOUNT2}\n\nThis will allow you to keep your existing progress.\nWarning: this cannot be undone!\n": "Ghetu caro cołegar el to account łogałe co 'sto cuà?\n\nEl to account łogałe el ze ${ACCOUNT1}\n'Sto account el ze ${ACCOUNT2}\n\n'Sta oparasion ła te parmetarà de mantegner i to progresi ezistenti.\nOcio: 'sta asion no ła połe pì èsar anułada!",
"You already own this!": "Dezà cronpà!",
"You can join in ${COUNT} seconds.": "A te połi zontarte tenpo ${COUNT} segondi.",
"You can join in ${COUNT} seconds.": "Te połi zontarte tenpo ${COUNT} segondi.",
"You don't have enough tickets for this!": "A no te ghè miga biłieti che basta par cronparlo!",
"You don't own that.": "Gnancora cronpà!",
"You got ${COUNT} tickets!": "A te ghè otegnesto ${COUNT} biłieti!",
@ -1702,9 +1715,9 @@
"A perfectly timed running-jumping-spin-punch can kill in a single hit\nand earn you lifelong respect from your friends.": "Co'l justo tenpo de corsa, salto e rodasion, un crogno el połe copar inte un\ncolpo soło e farte vadagnar el respeto de i to amighi par tuta ła vida.",
"Always remember to floss.": "Recòrdate senpre de doparar el fiło intardentałe.",
"Create player profiles for yourself and your friends with\nyour preferred names and appearances instead of using random ones.": "Invese de doparàrghine de fati a cazo, par ti e i to\namighi crea profiłi zugador co nomi e parense parsonałizàe.",
"Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Łe case małedision łe te transforma inte na bonba a tenpo.\nA te połi curarte soło tołendo in presa un pacheto sałude.",
"Curse boxes turn you into a ticking time bomb.\nThe only cure is to quickly grab a health-pack.": "Łe case małedision łe te transforma inte na bonba a tenpo.\nTe połi curarte soło tołendo in presa un pacheto sałude.",
"Despite their looks, all characters' abilities are identical,\nso just pick whichever one you most closely resemble.": "Anca se drio ła siera A no par, łe abiłidà de tuti i parsonaji\nłe ze conpagne, donca tote sù cheło che'l te połe somejar de pì.",
"Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Mai far masa i gałeti co'l scudo nerjètego: A te połi uncora farte trar baso da na croda.",
"Don't get too cocky with that energy shield; you can still get yourself thrown off a cliff.": "Mai far masa i gałeti co'l scudo nerjètego: te połi uncora farte trar baso da na croda.",
"Don't run all the time. Really. You will fall off cliffs.": "No stà córar tuto el tenpo. Dabon. Te fenirè zó par na croda.",
"Don't spin for too long; you'll become dizzy and fall.": "No stà ndar torno par masa tenpo: te vegnarà na storniroła e te cascarè.",
"Hold any button to run. (Trigger buttons work well if you have them)": "Tien strucà un boton calsìase par córar. (I griłeti nałòzeghi i ze i pì adati, se A te łi ghè)",
@ -1719,14 +1732,14 @@
"If you've got lots of players coming and going, turn on 'auto-kick-idle-players'\nunder settings in case anyone forgets to leave the game.": "Se te te cati tanti zugadori che và e vien, e inte'l cazo che calchedun el se dezménteghe de\nmołar el zugo, ativa ła funsion automàtega 'Para fora zugadori in sonera' inte łe inpostasion.",
"If your device gets too warm or you'd like to conserve battery power,\nturn down \"Visuals\" or \"Resolution\" in Settings->Graphics": "Se'l to dispozidivo el taca scotar o se te ghè caro sparagnar batarìa,\ncała ła \"Prospetiva\" o ła \"Resołusion\" so Inpostasion > Gràfega",
"If your framerate is choppy, try turning down resolution\nor visuals in the game's graphics settings.": "Se el zugo el và a scati, proa całar ła resołusion\no ła prospetiva inte l'inpostasion gràfega.",
"In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Par far ponto so 'Brinca ła bandiera', A te ghè da portar ła bandiera fin so ła to\nbaze. Se cheł'altra scuadra ła ze drio far ponto, A te połi fermarla anca robàndogheła.",
"In Capture-the-Flag, your own flag must be at your base to score, If the other\nteam is about to score, stealing their flag can be a good way to stop them.": "Par far ponto so 'Brinca ła bandiera', te ghè da portar ła bandiera fin so ła tó\nbaze. Se cheł'altra scuadra ła ze drio far ponto, te połi fermarla anca robàndogheła.",
"In hockey, you'll maintain more speed if you turn gradually.": "Inte l'hockey, voltando gradualmente A te mantien alta ła vełosidà.",
"It's easier to win with a friend or two helping.": "A ze pì fàsiłe vìnsar se un amigo o do i te dà na man.",
"Jump just as you're throwing to get bombs up to the highest levels.": "Co A te si drio tirar na bonba, salta par farla rivar pì alta posìbiłe.",
"Land-mines are a good way to stop speedy enemies.": "Łe mine łe ze fantàsteghe par fermar i nemighi pì ràpidi.",
"Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "A te połi łevar sù e tirar racuante robe, anca cheł'altri zugadori. Trar zó da na croda\ni to nemighi ła połe èsar na stratejìa efisente che ła połe cavarte anca calche spisa.",
"Many things can be picked up and thrown, including other players. Tossing\nyour enemies off cliffs can be an effective and emotionally fulfilling strategy.": "Te połi łevar sù e tirar racuante robe, anca cheł'altri zugadori. Trar zó da na croda\ni tó nemighi ła połe èsar na stratejìa efisente che ła połe cavarte anca calche spisa.",
"No, you can't get up on the ledge. You have to throw bombs.": "Nò, A no te połi mìa montar so'l bordo. A te ghè da tirar bonbe.",
"Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "I zugadori i połe zontarse e ndar vìa inte'l medo de ła majornasa de łe\npartìe. Ti A te połi anca tacar e destacar un controłador a'l voło.",
"Players can join and leave in the middle of most games,\nand you can also plug and unplug controllers on the fly.": "I zugadori i połe zontarse e ndar vìa inte'l medo de ła majornasa de łe\npartìe. Ti te połi anca tacar e destacar un controłador a'l voło.",
"Practice using your momentum to throw bombs more accurately.": "Fà pràtega tirardo bonbe corendo par far crèsar ła to presizion.",
"Punches do more damage the faster your fists are moving,\nso try running, jumping, and spinning like crazy.": "Pì vełosi che se move łe to man, pì dano i farà i to\ncrogni! Donca proa córar, saltar e ndar torno cofà un mato.",
"Run back and forth before throwing a bomb\nto 'whiplash' it and throw it farther.": "Prima de tirar na bonba cori prima indrìo e daspò in\nvanti par darghe na \"scuriatada\" e trarla pì distante.",
@ -1739,9 +1752,9 @@
"Try tricking enemies into killing eachother or running off cliffs.": "Frega i to nemighi parché i se cope infrà de łori o i cora zó par na croda.",
"Use the pick-up button to grab the flag < ${PICKUP} >": "Dòpara el boton 'łeva sù' par brincar ła bandiera < ${PICKUP} >",
"Whip back and forth to get more distance on your throws..": "Cori prima indrìo e daspò in vanti par rivar pì distante co i to tiri...",
"You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "A te połi 'mirar' i to crogni ndando torno par drita o sanca. A torna\ncòmodo par trar baso i cataràdeghi da łe crode o par far ponto so l'hockey.",
"You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "A te połi capir el tenpo de esplozion de na bonba drio el cołor\nde łe fałive de ła micia: zało.. naranson.. roso.. e BUM!!",
"You can throw bombs higher if you jump just before throwing.": "A te połi tirar łe bonbe pì alte, se te salti pena prima de tirarle.",
"You can 'aim' your punches by spinning left or right.\nThis is useful for knocking bad guys off edges or scoring in hockey.": "Te połi 'mirar' i tó crogni ndando torno par drita o sanca. Na comodidà\npar trar baso i cataràdeghi da łe crode o par far ponto so l'hockey.",
"You can judge when a bomb is going to explode based on the\ncolor of sparks from its fuse: yellow..orange..red..BOOM.": "Te połi capir el tenpo de esplozion de na bonba drio el cołor\nde łe fałive de ła micia: zało.. naranson.. roso.. e BUM!!",
"You can throw bombs higher if you jump just before throwing.": "Se te salti pena prima de tirarle te trè łe bonbe pì alte.",
"You take damage when you whack your head on things,\nso try to not whack your head on things.": "Se A te bati ła testa da calche parte A te te fè małe,\ndonca proa a no zbàtar da gnauna parte.",
"Your punches do much more damage if you are running or spinning.": "I to crogni i fà pì małe se A te si drio córar o ndar torno."
}
@ -1764,7 +1777,7 @@
"phrase11Text": "Tien strucà un boton CALSÌASE par córar.",
"phrase12Text": "Par crogni uncora pì fisi, proa córar e ndar torno INSENBRE.",
"phrase13Text": "Orpo! Colpa mia ${NAME}.",
"phrase14Text": "A te połi łevar sù e tirar robe cofà łe bandiere o anca cofà... ${NAME}.",
"phrase14Text": "Te połi łevar sù e tirar robe cofà bandiere, ojeti o anca... ${NAME}.",
"phrase15Text": "In ùltema, A ghe ze łe bonbe.",
"phrase16Text": "A serve pràtega par tirar ben łe bonbe.",
"phrase17Text": "Òstrega! Un tiro miga masa beło...",
@ -1864,7 +1877,7 @@
"worldsBestTimesText": "I tenpi mejo de'l mondo",
"xbox360ControllersWindow": {
"getDriverText": "Descarga el driver",
"macInstructions2Text": "Par doparar sensa fiło i controładori, A te serve anca el resevidor\nche'l riva co l''Xbox 360 Wireless Controller par Windows'.\nUn resevidor el te parmete de conétar fin a 4 controładori.\n\nInportante: i resevidori de terse parti no i funsionarà miga co 'sto driver;\nsegùrate che'l to resevidor el sipia 'Microsoft' e miga 'XBOX 360'.\nŁa Microsoft no łi vende pì destacài, donca te servirà par forsa cheło\nvendesto insebre co'l controłador, o senò, proa sercar so Ebay.\n\nSe te cati ùtiłe el driver, ciapa in considerasion de farghe na\ndonasion a'l só dezviłupador so 'sto sito.",
"macInstructions2Text": "Par doparar sensa fiło i controładori, te serve anca el resevidor\nche'l riva co l''Xbox 360 Wireless Controller par Windows'.\nUn resevidor el te parmete de conétar fin a 4 controładori.\n\nInportante: i resevidori de terse parti no i funsionarà miga co 'sto driver;\nsegùrate che'l to resevidor el sipia 'Microsoft' e miga 'XBOX 360'.\nŁa Microsoft no łi vende pì destacài, donca te servirà par forsa cheło\nvendesto insebre co'l controłador, o senò, proa sercar so Ebay.\n\nSe te cati ùtiłe el driver, ciapa in considerasion de farghe na\ndonasion a'l só dezviłupador so 'sto sito.",
"macInstructionsText": "Per doparar i controładori co'l fiło de ła Xbox 360, te ghè\nda instałar el driver Mac disponìbiłe so'l link cuà soto.\nEl funsiona co anbo i controładori, co'l fiło o sensa.",
"ouyaInstructionsText": "Par doparar so Bombsquad un controłador de l'Xbox 360 co'l fiło,\ntàcheło sù inte ła porta USB del to dispozidivo. Te połi anca\ntacar sù pì controładori insenbre doparando un hub USB.\n\nPar doparar i controładori sensa fiło invese, te serve un resevidor\nde segnałe. Te połi catarlo, o rento ła scàtoła \"Controładori sensa fiło\nXbox 360 par Windows\", o vendesto a parte. Caun resevidor el và tacà so\nna porta USB e el te parmete de conétar fin a 4 controładori.",
"titleText": "Doparar un controłador Xbox 360 co ${APP_NAME}:"

View file

@ -8,6 +8,7 @@
"changeOncePerSeason": "Bạn chỉ có thể thay đổi một lần mỗi mùa.",
"changeOncePerSeasonError": "Bạn có thể đổi nó vào mùa sau (${NUM} days)",
"customName": "Tên tùy chỉnh",
"googlePlayGamesAccountSwitchText": "Nếu bạn muốn sử dụng một tài khoản Google khác,\nhãy sử dụng ứng dụng Google Play Games để đổi.",
"linkAccountsEnterCodeText": "Nhập Mã",
"linkAccountsGenerateCodeText": "Tạo mã",
"linkAccountsInfoText": "(Chia sẽ dữ liệu giữa các máy)",
@ -15,6 +16,7 @@
"linkAccountsInstructionsText": "Để kết nối 2 tài khoản khác nhau, tạo mã ở\nmột máy và nhập mã ở máy còn lại.\nDữ liệu sẽ được liên kết giữa các máy\nBạn có thể kết nối đến ${COUNT} thiết bị.\n\nQUAN TRỌNG: Chỉ kết nối tài khoản của bạn!\nNếu bạn kết nối tài khoản với bạn bè\nbạn không thể chơi cùng một lúc!\n\nNgoài ra: nó không thể hoàn tác, nên hãy cẩn thận!",
"linkAccountsText": "kết nối máy khác",
"linkedAccountsText": "Tài khoản kết nối:",
"manageAccountText": "Quản lý tài khoản",
"nameChangeConfirm": "Đổi tên tài khoản thành ${NAME}?",
"resetProgressConfirmNoAchievementsText": "Việc này sẽ đặt lại toàn bộ dữ liệu của bạn\nngoại trừ số tiền của ban\nđiều này không thể hoàn tác. Chắc chắn?",
"resetProgressConfirmText": "Việc này sẽ đặt lại toàn bộ dữ liệu của bạn\nvà cả huy hiệu\nngoại trừ số tiền của ban\nđiều này không thể hoàn tác. Chắc chắn?",
@ -41,6 +43,7 @@
"titleText": "Tài Khoản",
"unlinkAccountsInstructionsText": "Chọn tài khoản để hủy kết nối",
"unlinkAccountsText": "Hủy kết nối",
"unlinkLegacyV1AccountsText": "Hủy liên kết tài khoản (V1)",
"v2LinkInstructionsText": "Sử dụng liên kết này để tạo tài khoản hoặc đăng nhập.",
"viaAccount": "(qua tài khoản ${NAME})",
"youAreSignedInAsText": "Bạn đang đăng nhập tài khoản:"
@ -334,6 +337,7 @@
"getMoreGamesText": "Thêm các thể loại chơi",
"titleText": "Thêm trận đấu"
},
"allText": "Tất cả",
"allowText": "Cho phép",
"alreadySignedInText": "Tài khoản của bạn đã được đăng nhập trên thiết bị khác;\nhãy đổi tài khoản hoặc đăng xuất khỏi thiết bị khác\nvà thử lại.",
"apiVersionErrorText": "Không thể tải ${NAME}; phiên bản ${VERSION_USED}; yêu cầu ${VERSION_REQUIRED}.",
@ -547,7 +551,9 @@
"deleteText": "Xóa",
"demoText": "Giới thiệu",
"denyText": "Từ chối",
"deprecatedText": "Không thể dùng",
"desktopResText": "Độ phân giải",
"deviceAccountUpgradeText": "Cảnh báo:\nBạn đã đăng nhập với tài khoản thiết bị (${NAME}).\nTài khoản thiết bị sẽ bị xóa trong những cập nhật tương lai.\nNâng cấp lên tài khoản V2 nếu bạn muốn giữ tiến trình.",
"difficultyEasyText": "Dễ",
"difficultyHardOnlyText": "Chỉ chế độ khó",
"difficultyHardText": "Khó",
@ -556,6 +562,7 @@
"disableRemoteAppConnectionsText": "Tắt Trình Điều Khiên",
"disableXInputDescriptionText": "Cho phép trên 4 thiết bị điều khiển nhưng nó có thể hoạt động không tốt",
"disableXInputText": "Ngắt Kết NỐi XInput",
"disabledText": "Vô hiệu hóa",
"doneText": "Xong",
"drawText": "Hòa",
"duplicateText": "Nhân Đôi",
@ -624,6 +631,7 @@
"useMusicFolderText": "Thư mục của files nhạc"
},
"editText": "Sửa",
"enabledText": "Hiển thị",
"endText": "kết thúc",
"enjoyText": "Chúc vui vẻ!",
"epicDescriptionFilterText": "${DESCRIPTION} trong chế độ quay chậm.",
@ -806,6 +814,7 @@
},
"googleMultiplayerDiscontinuedText": "Xin lỗi, dịch vụ Google nhiều người chơi không còn nữa.\nTôi đang cố gắng thay thế nhanh nhất có thể.\nTrong lúc đó, vui lòng thử cách kết nối khác.\n-Eric",
"googlePlayPurchasesNotAvailableText": "Các giao dịch mua trên Google Play không khả dụng.\nBạn có thể cần cập nhật ứng dụng cửa hàng của mình.",
"googlePlayServicesNotAvailableText": "Dịch vụ của Google Play không có sẵn.\nMột số chức năng ứng dụng sẽ bụ vô hiệu hóa.",
"googlePlayText": "Google Trò chơi",
"graphicsSettingsWindow": {
"alwaysText": "Luôn Luôn",
@ -1002,6 +1011,7 @@
"creditsText": "Giới thiệu",
"demoMenuText": "Cài đặt Demo",
"endGameText": "kết thúc game",
"endTestText": "Kết thúc thử nghiệm",
"exitGameText": "Thoat game",
"exitToMenuText": "Quay về Menu?",
"howToPlayText": "Hướng dẫn chơi",
@ -1021,6 +1031,7 @@
"maxConnectionsText": "Kết nối tối đa",
"maxPartySizeText": "Số người trong bữa tiệc tối đa",
"maxPlayersText": "Người chơi tối đa",
"merchText": "Cửa hàng!",
"modeArcadeText": "Chế độ giải trí",
"modeClassicText": "Chế độ cổ điển",
"modeDemoText": "Chế độ thử nghiệm",
@ -1060,6 +1071,7 @@
"notSignedInErrorText": "Bạn phải đăng nhập để làm điều này.",
"notSignedInGooglePlayErrorText": "Bạn phải đăng nhập bằng Google Play để làm điều này.",
"notSignedInText": "chưa đăng nhập",
"notUsingAccountText": "Ghi chú: phớt lờ cái tài khoản ${SERVICE} đi.\nHãy đi đến 'Tài khoản -> Đăng nhập với ${SERVICE}' nếu bạn muốn sử dụng nó.",
"nothingIsSelectedErrorText": "Bạn chưa chọn cái nào!",
"numberText": "#${NUMBER}",
"offText": "Tắt",
@ -1118,7 +1130,11 @@
"pleaseWaitText": "Vui lòng chờ...",
"pluginClassLoadErrorText": "Lỗi khi tải lớp plugin '${PLUGIN}': ${ERROR}",
"pluginInitErrorText": "Lỗi khi nhập plugin '${PLUGIN}': ${ERROR}",
"pluginSettingsText": "Các thiết đặt giác cắm",
"pluginsAutoEnableNewText": "Tự động hiển thị những Giác cắm mới",
"pluginsDetectedText": "Đã phát hiện (các) plugin mới. Khởi động lại để kích hoạt chúng hoặc định cấu hình chúng trong cài đặt.",
"pluginsDisableAllText": "Vô hiệu hóa tất cả các giác cắm",
"pluginsEnableAllText": "Hiển thị tất cả các giác cắm",
"pluginsRemovedText": "Không còn tìm thấy ${NUM} plugin nào nữa.",
"pluginsText": "Cắm",
"practiceText": "Luyện tập",
@ -1209,7 +1225,9 @@
"revertText": "Hủy bỏ",
"runText": "Chạy",
"saveText": "Lưu",
"scanScriptsErrorText": "Lỗi trong lúc quét mã bản thảo; xem bản thông báo cho chi tiết.",
"scanScriptsErrorText": "Lỗi trong lúc quét mã bản thảo. Xem bảng thông báo để biết thêm chi tiết.",
"scanScriptsMultipleModulesNeedUpdatesText": "${PATH} và ${NUM} mô-đun khác cần phải được cập nhật cho api ${API}.",
"scanScriptsSingleModuleNeedsUpdatesText": "${PATH} cần được nâng cấp cho api ${API}",
"scoreChallengesText": "Thử thách Điểm số",
"scoreListUnavailableText": "Danh sách điểm số không có sẵn.",
"scoreText": "Điểm số",
@ -1253,6 +1271,7 @@
"netTestingText": "Kiểm tra mạng",
"resetText": "Cài lại",
"showBombTrajectoriesText": "Hiển thị quỹ đạo của bom",
"showInGamePingText": "Hiển thị Ping trong Game",
"showPlayerNamesText": "Hiển thị tên người chơi",
"showUserModsText": "Hiển thị Thư mục Mod",
"titleText": "Nâng cao",
@ -1523,6 +1542,7 @@
"Italian": "Tiếng Ý",
"Japanese": "Tiếng Nhật",
"Korean": "Tiếng Hàn",
"Malay": "Tiếng Mã Lai",
"Persian": "Tiếng Ba Tư",
"Polish": "Tiếng Polish",
"Portuguese": "Tiếng Bồ Đào Nha",
@ -1804,6 +1824,7 @@
"useDefaultText": "Sử dụng mặc định",
"usesExternalControllerText": "Trò chơi này sử dụng tay cầm bên ngoài cho đầu vào.",
"usingItunesText": "Sử dụng Ứng dụng âm nhạc cho nhạc nền",
"v2AccountLinkingInfoText": "Để đến tài khoản V2, sử dụng nút 'Thiết đặt tài khoản'.",
"validatingTestBuildText": "Kiểm tra xác thực Xây dựng ...",
"victoryText": "Chiến thắng!",
"voteDelayText": "Bạn không thể bắt đầu cuộc bầu chọn khác trong ${NUMBER} giây",
@ -1836,6 +1857,7 @@
},
"waveText": "Vòng",
"wellSureText": "Chắc chắn rồi!",
"whatIsThisText": "Đây là cái gì vậy?",
"wiimoteLicenseWindow": {
"titleText": "DarwiinRemote Bản quyền"
},

View file

@ -53,41 +53,41 @@
"preview_texture": "bridgitPreview",
"terrain_nodes": [
{
"collide_model": "bridgitLevelBottom",
"collision_mesh": "bridgitLevelBottom",
"color_texture": "bridgitLevelColor",
"comment": "Top portion of bridge.",
"materials": ["footing"],
"model": "bridgitLevelTop"
"mesh": "bridgitLevelTop"
},
{
"color_texture": "bridgitLevelColor",
"comment": "Bottom portion of bridge with no lighting effects.",
"lighting": false,
"model": "bridgitLevelBottom"
"mesh": "bridgitLevelBottom"
},
{
"background": true,
"color_texture": "natureBackgroundColor",
"comment": "Visible background.",
"lighting": false,
"model": "natureBackground"
"mesh": "natureBackground"
},
{
"background": true,
"color_texture": "model_bg_tex",
"color_texture": "mesh_bg_tex",
"comment": "360 degree bg for vr.",
"lighting": false,
"model": "bg_vr_fill_model",
"mesh": "bg_vr_fill_mesh",
"vr_only": true
},
{
"bumper": true,
"collide_model": "railing_collide_model",
"collision_mesh": "railing_collide_mesh",
"comment": "Invisible railing to help prevent falls.",
"materials": ["railing"]
},
{
"collide_model": "collide_bg",
"collision_mesh": "collide_bg",
"comment": "Collision shape for bg",
"materials": ["footing", "friction@10", "death"]
}

View file

@ -1 +0,0 @@
c6fb0b975dd95d7c871b26f652ced6b0b9dc9dd42bc61c860782979ef6ec46d4 *D:/a/aiohttp/aiohttp/aiohttp/_cparser.pxd

View file

@ -1 +0,0 @@
0455129b185e981b5b96ac738f31f7c74dc57f1696953cae0083b3f18679fe73 *D:/a/aiohttp/aiohttp/aiohttp/_find_header.pxd

View file

@ -1 +0,0 @@
481f39d4a9ad5a9889d99074e53a68e3ce795640b246d80cb3ce375b3f2415e8 *D:/a/aiohttp/aiohttp/aiohttp/_frozenlist.pyx

View file

@ -1 +0,0 @@
d87779202d197f8613109e35dacbb2ca1b21d64572543bf9838b2d832a362ac7 *D:/a/aiohttp/aiohttp/aiohttp/_helpers.pyi

View file

@ -1 +0,0 @@
b6097b7d987440c4fa7237f88d227c89a3ba0dd403dc638ddbe487e0de7f1138 *D:/a/aiohttp/aiohttp/aiohttp/_helpers.pyx

View file

@ -1 +0,0 @@
83c05185224ad57f133f7fd5d56c331f4f9e101cd52f91237e7b6568b5459e1c *D:/a/aiohttp/aiohttp/aiohttp/_http_parser.pyx

View file

@ -1 +0,0 @@
ac1cdb93ec6b2163b6843d242a8e482ca48ab16fd4f177f5e4800f9ea487db74 *D:/a/aiohttp/aiohttp/aiohttp/_http_writer.pyx

View file

@ -1 +0,0 @@
a3d27bca2f5cdbe8d3063137754917c610d62af456273e4665fc8bb202506b7f *D:/a/aiohttp/aiohttp/aiohttp/_websocket.pyx

View file

@ -1 +0,0 @@
9011bd27ad72982aa252f064ae3b1119599f6a49a4ce4e8a1e665b76044b0996 *D:/a/aiohttp/aiohttp/aiohttp/frozenlist.pyi

View file

@ -1 +0,0 @@
5f2bdc50368865ef87528ae8fd6820c8b35677209c5430b669c8857abedb9e94 *D:/a/aiohttp/aiohttp/aiohttp/hdrs.py

View file

@ -1 +0,0 @@
1273686ce37b6b3150d5f1d28a496f6ebbd07d05273993e2de7ffaa4a1335e83 *D:/a/aiohttp/aiohttp/aiohttp/signals.pyi

View file

@ -1,217 +0,0 @@
__version__ = "3.7.4.post0"
from typing import Tuple
from . import hdrs as hdrs
from .client import (
BaseConnector as BaseConnector,
ClientConnectionError as ClientConnectionError,
ClientConnectorCertificateError as ClientConnectorCertificateError,
ClientConnectorError as ClientConnectorError,
ClientConnectorSSLError as ClientConnectorSSLError,
ClientError as ClientError,
ClientHttpProxyError as ClientHttpProxyError,
ClientOSError as ClientOSError,
ClientPayloadError as ClientPayloadError,
ClientProxyConnectionError as ClientProxyConnectionError,
ClientRequest as ClientRequest,
ClientResponse as ClientResponse,
ClientResponseError as ClientResponseError,
ClientSession as ClientSession,
ClientSSLError as ClientSSLError,
ClientTimeout as ClientTimeout,
ClientWebSocketResponse as ClientWebSocketResponse,
ContentTypeError as ContentTypeError,
Fingerprint as Fingerprint,
InvalidURL as InvalidURL,
NamedPipeConnector as NamedPipeConnector,
RequestInfo as RequestInfo,
ServerConnectionError as ServerConnectionError,
ServerDisconnectedError as ServerDisconnectedError,
ServerFingerprintMismatch as ServerFingerprintMismatch,
ServerTimeoutError as ServerTimeoutError,
TCPConnector as TCPConnector,
TooManyRedirects as TooManyRedirects,
UnixConnector as UnixConnector,
WSServerHandshakeError as WSServerHandshakeError,
request as request,
)
from .cookiejar import CookieJar as CookieJar, DummyCookieJar as DummyCookieJar
from .formdata import FormData as FormData
from .helpers import BasicAuth as BasicAuth, ChainMapProxy as ChainMapProxy
from .http import (
HttpVersion as HttpVersion,
HttpVersion10 as HttpVersion10,
HttpVersion11 as HttpVersion11,
WebSocketError as WebSocketError,
WSCloseCode as WSCloseCode,
WSMessage as WSMessage,
WSMsgType as WSMsgType,
)
from .multipart import (
BadContentDispositionHeader as BadContentDispositionHeader,
BadContentDispositionParam as BadContentDispositionParam,
BodyPartReader as BodyPartReader,
MultipartReader as MultipartReader,
MultipartWriter as MultipartWriter,
content_disposition_filename as content_disposition_filename,
parse_content_disposition as parse_content_disposition,
)
from .payload import (
PAYLOAD_REGISTRY as PAYLOAD_REGISTRY,
AsyncIterablePayload as AsyncIterablePayload,
BufferedReaderPayload as BufferedReaderPayload,
BytesIOPayload as BytesIOPayload,
BytesPayload as BytesPayload,
IOBasePayload as IOBasePayload,
JsonPayload as JsonPayload,
Payload as Payload,
StringIOPayload as StringIOPayload,
StringPayload as StringPayload,
TextIOPayload as TextIOPayload,
get_payload as get_payload,
payload_type as payload_type,
)
from .payload_streamer import streamer as streamer
from .resolver import (
AsyncResolver as AsyncResolver,
DefaultResolver as DefaultResolver,
ThreadedResolver as ThreadedResolver,
)
from .signals import Signal as Signal
from .streams import (
EMPTY_PAYLOAD as EMPTY_PAYLOAD,
DataQueue as DataQueue,
EofStream as EofStream,
FlowControlDataQueue as FlowControlDataQueue,
StreamReader as StreamReader,
)
from .tracing import (
TraceConfig as TraceConfig,
TraceConnectionCreateEndParams as TraceConnectionCreateEndParams,
TraceConnectionCreateStartParams as TraceConnectionCreateStartParams,
TraceConnectionQueuedEndParams as TraceConnectionQueuedEndParams,
TraceConnectionQueuedStartParams as TraceConnectionQueuedStartParams,
TraceConnectionReuseconnParams as TraceConnectionReuseconnParams,
TraceDnsCacheHitParams as TraceDnsCacheHitParams,
TraceDnsCacheMissParams as TraceDnsCacheMissParams,
TraceDnsResolveHostEndParams as TraceDnsResolveHostEndParams,
TraceDnsResolveHostStartParams as TraceDnsResolveHostStartParams,
TraceRequestChunkSentParams as TraceRequestChunkSentParams,
TraceRequestEndParams as TraceRequestEndParams,
TraceRequestExceptionParams as TraceRequestExceptionParams,
TraceRequestRedirectParams as TraceRequestRedirectParams,
TraceRequestStartParams as TraceRequestStartParams,
TraceResponseChunkReceivedParams as TraceResponseChunkReceivedParams,
)
__all__: Tuple[str, ...] = (
"hdrs",
# client
"BaseConnector",
"ClientConnectionError",
"ClientConnectorCertificateError",
"ClientConnectorError",
"ClientConnectorSSLError",
"ClientError",
"ClientHttpProxyError",
"ClientOSError",
"ClientPayloadError",
"ClientProxyConnectionError",
"ClientResponse",
"ClientRequest",
"ClientResponseError",
"ClientSSLError",
"ClientSession",
"ClientTimeout",
"ClientWebSocketResponse",
"ContentTypeError",
"Fingerprint",
"InvalidURL",
"RequestInfo",
"ServerConnectionError",
"ServerDisconnectedError",
"ServerFingerprintMismatch",
"ServerTimeoutError",
"TCPConnector",
"TooManyRedirects",
"UnixConnector",
"NamedPipeConnector",
"WSServerHandshakeError",
"request",
# cookiejar
"CookieJar",
"DummyCookieJar",
# formdata
"FormData",
# helpers
"BasicAuth",
"ChainMapProxy",
# http
"HttpVersion",
"HttpVersion10",
"HttpVersion11",
"WSMsgType",
"WSCloseCode",
"WSMessage",
"WebSocketError",
# multipart
"BadContentDispositionHeader",
"BadContentDispositionParam",
"BodyPartReader",
"MultipartReader",
"MultipartWriter",
"content_disposition_filename",
"parse_content_disposition",
# payload
"AsyncIterablePayload",
"BufferedReaderPayload",
"BytesIOPayload",
"BytesPayload",
"IOBasePayload",
"JsonPayload",
"PAYLOAD_REGISTRY",
"Payload",
"StringIOPayload",
"StringPayload",
"TextIOPayload",
"get_payload",
"payload_type",
# payload_streamer
"streamer",
# resolver
"AsyncResolver",
"DefaultResolver",
"ThreadedResolver",
# signals
"Signal",
"DataQueue",
"EMPTY_PAYLOAD",
"EofStream",
"FlowControlDataQueue",
"StreamReader",
# tracing
"TraceConfig",
"TraceConnectionCreateEndParams",
"TraceConnectionCreateStartParams",
"TraceConnectionQueuedEndParams",
"TraceConnectionQueuedStartParams",
"TraceConnectionReuseconnParams",
"TraceDnsCacheHitParams",
"TraceDnsCacheMissParams",
"TraceDnsResolveHostEndParams",
"TraceDnsResolveHostStartParams",
"TraceRequestChunkSentParams",
"TraceRequestEndParams",
"TraceRequestExceptionParams",
"TraceRequestRedirectParams",
"TraceRequestStartParams",
"TraceResponseChunkReceivedParams",
)
try:
from .worker import GunicornUVLoopWebWorker, GunicornWebWorker
__all__ += ("GunicornWebWorker", "GunicornUVLoopWebWorker")
except ImportError: # pragma: no cover
pass

View file

@ -1,140 +0,0 @@
from libc.stdint cimport uint16_t, uint32_t, uint64_t
cdef extern from "../vendor/http-parser/http_parser.h":
ctypedef int (*http_data_cb) (http_parser*,
const char *at,
size_t length) except -1
ctypedef int (*http_cb) (http_parser*) except -1
struct http_parser:
unsigned int type
unsigned int flags
unsigned int state
unsigned int header_state
unsigned int index
uint32_t nread
uint64_t content_length
unsigned short http_major
unsigned short http_minor
unsigned int status_code
unsigned int method
unsigned int http_errno
unsigned int upgrade
void *data
struct http_parser_settings:
http_cb on_message_begin
http_data_cb on_url
http_data_cb on_status
http_data_cb on_header_field
http_data_cb on_header_value
http_cb on_headers_complete
http_data_cb on_body
http_cb on_message_complete
http_cb on_chunk_header
http_cb on_chunk_complete
enum http_parser_type:
HTTP_REQUEST,
HTTP_RESPONSE,
HTTP_BOTH
enum http_errno:
HPE_OK,
HPE_CB_message_begin,
HPE_CB_url,
HPE_CB_header_field,
HPE_CB_header_value,
HPE_CB_headers_complete,
HPE_CB_body,
HPE_CB_message_complete,
HPE_CB_status,
HPE_CB_chunk_header,
HPE_CB_chunk_complete,
HPE_INVALID_EOF_STATE,
HPE_HEADER_OVERFLOW,
HPE_CLOSED_CONNECTION,
HPE_INVALID_VERSION,
HPE_INVALID_STATUS,
HPE_INVALID_METHOD,
HPE_INVALID_URL,
HPE_INVALID_HOST,
HPE_INVALID_PORT,
HPE_INVALID_PATH,
HPE_INVALID_QUERY_STRING,
HPE_INVALID_FRAGMENT,
HPE_LF_EXPECTED,
HPE_INVALID_HEADER_TOKEN,
HPE_INVALID_CONTENT_LENGTH,
HPE_INVALID_CHUNK_SIZE,
HPE_INVALID_CONSTANT,
HPE_INVALID_INTERNAL_STATE,
HPE_STRICT,
HPE_PAUSED,
HPE_UNKNOWN
enum flags:
F_CHUNKED,
F_CONNECTION_KEEP_ALIVE,
F_CONNECTION_CLOSE,
F_CONNECTION_UPGRADE,
F_TRAILING,
F_UPGRADE,
F_SKIPBODY,
F_CONTENTLENGTH
enum http_method:
DELETE, GET, HEAD, POST, PUT, CONNECT, OPTIONS, TRACE, COPY,
LOCK, MKCOL, MOVE, PROPFIND, PROPPATCH, SEARCH, UNLOCK, BIND,
REBIND, UNBIND, ACL, REPORT, MKACTIVITY, CHECKOUT, MERGE,
MSEARCH, NOTIFY, SUBSCRIBE, UNSUBSCRIBE, PATCH, PURGE, MKCALENDAR,
LINK, UNLINK
void http_parser_init(http_parser *parser, http_parser_type type)
size_t http_parser_execute(http_parser *parser,
const http_parser_settings *settings,
const char *data,
size_t len)
int http_should_keep_alive(const http_parser *parser)
void http_parser_settings_init(http_parser_settings *settings)
const char *http_errno_name(http_errno err)
const char *http_errno_description(http_errno err)
const char *http_method_str(http_method m)
# URL Parser
enum http_parser_url_fields:
UF_SCHEMA = 0,
UF_HOST = 1,
UF_PORT = 2,
UF_PATH = 3,
UF_QUERY = 4,
UF_FRAGMENT = 5,
UF_USERINFO = 6,
UF_MAX = 7
struct http_parser_url_field_data:
uint16_t off
uint16_t len
struct http_parser_url:
uint16_t field_set
uint16_t port
http_parser_url_field_data[<int>UF_MAX] field_data
void http_parser_url_init(http_parser_url *u)
int http_parser_parse_url(const char *buf,
size_t buflen,
int is_connect,
http_parser_url *u)

File diff suppressed because it is too large Load diff

View file

@ -1,14 +0,0 @@
#ifndef _FIND_HEADERS_H
#define _FIND_HEADERS_H
#ifdef __cplusplus
extern "C" {
#endif
int find_header(const char *str, int size);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,2 +0,0 @@
cdef extern from "_find_header.h":
int find_header(char *, int)

File diff suppressed because it is too large Load diff

View file

@ -1,108 +0,0 @@
from collections.abc import MutableSequence
cdef class FrozenList:
cdef readonly bint frozen
cdef list _items
def __init__(self, items=None):
self.frozen = False
if items is not None:
items = list(items)
else:
items = []
self._items = items
cdef object _check_frozen(self):
if self.frozen:
raise RuntimeError("Cannot modify frozen list.")
cdef inline object _fast_len(self):
return len(self._items)
def freeze(self):
self.frozen = True
def __getitem__(self, index):
return self._items[index]
def __setitem__(self, index, value):
self._check_frozen()
self._items[index] = value
def __delitem__(self, index):
self._check_frozen()
del self._items[index]
def __len__(self):
return self._fast_len()
def __iter__(self):
return self._items.__iter__()
def __reversed__(self):
return self._items.__reversed__()
def __richcmp__(self, other, op):
if op == 0: # <
return list(self) < other
if op == 1: # <=
return list(self) <= other
if op == 2: # ==
return list(self) == other
if op == 3: # !=
return list(self) != other
if op == 4: # >
return list(self) > other
if op == 5: # =>
return list(self) >= other
def insert(self, pos, item):
self._check_frozen()
self._items.insert(pos, item)
def __contains__(self, item):
return item in self._items
def __iadd__(self, items):
self._check_frozen()
self._items += list(items)
return self
def index(self, item):
return self._items.index(item)
def remove(self, item):
self._check_frozen()
self._items.remove(item)
def clear(self):
self._check_frozen()
self._items.clear()
def extend(self, items):
self._check_frozen()
self._items += list(items)
def reverse(self):
self._check_frozen()
self._items.reverse()
def pop(self, index=-1):
self._check_frozen()
return self._items.pop(index)
def append(self, item):
self._check_frozen()
return self._items.append(item)
def count(self, item):
return self._items.count(item)
def __repr__(self):
return '<FrozenList(frozen={}, {!r})>'.format(self.frozen,
self._items)
MutableSequence.register(FrozenList)

View file

@ -1,83 +0,0 @@
# The file is autogenerated from aiohttp/hdrs.py
# Run ./tools/gen.py to update it after the origin changing.
from . import hdrs
cdef tuple headers = (
hdrs.ACCEPT,
hdrs.ACCEPT_CHARSET,
hdrs.ACCEPT_ENCODING,
hdrs.ACCEPT_LANGUAGE,
hdrs.ACCEPT_RANGES,
hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS,
hdrs.ACCESS_CONTROL_ALLOW_HEADERS,
hdrs.ACCESS_CONTROL_ALLOW_METHODS,
hdrs.ACCESS_CONTROL_ALLOW_ORIGIN,
hdrs.ACCESS_CONTROL_EXPOSE_HEADERS,
hdrs.ACCESS_CONTROL_MAX_AGE,
hdrs.ACCESS_CONTROL_REQUEST_HEADERS,
hdrs.ACCESS_CONTROL_REQUEST_METHOD,
hdrs.AGE,
hdrs.ALLOW,
hdrs.AUTHORIZATION,
hdrs.CACHE_CONTROL,
hdrs.CONNECTION,
hdrs.CONTENT_DISPOSITION,
hdrs.CONTENT_ENCODING,
hdrs.CONTENT_LANGUAGE,
hdrs.CONTENT_LENGTH,
hdrs.CONTENT_LOCATION,
hdrs.CONTENT_MD5,
hdrs.CONTENT_RANGE,
hdrs.CONTENT_TRANSFER_ENCODING,
hdrs.CONTENT_TYPE,
hdrs.COOKIE,
hdrs.DATE,
hdrs.DESTINATION,
hdrs.DIGEST,
hdrs.ETAG,
hdrs.EXPECT,
hdrs.EXPIRES,
hdrs.FORWARDED,
hdrs.FROM,
hdrs.HOST,
hdrs.IF_MATCH,
hdrs.IF_MODIFIED_SINCE,
hdrs.IF_NONE_MATCH,
hdrs.IF_RANGE,
hdrs.IF_UNMODIFIED_SINCE,
hdrs.KEEP_ALIVE,
hdrs.LAST_EVENT_ID,
hdrs.LAST_MODIFIED,
hdrs.LINK,
hdrs.LOCATION,
hdrs.MAX_FORWARDS,
hdrs.ORIGIN,
hdrs.PRAGMA,
hdrs.PROXY_AUTHENTICATE,
hdrs.PROXY_AUTHORIZATION,
hdrs.RANGE,
hdrs.REFERER,
hdrs.RETRY_AFTER,
hdrs.SEC_WEBSOCKET_ACCEPT,
hdrs.SEC_WEBSOCKET_EXTENSIONS,
hdrs.SEC_WEBSOCKET_KEY,
hdrs.SEC_WEBSOCKET_KEY1,
hdrs.SEC_WEBSOCKET_PROTOCOL,
hdrs.SEC_WEBSOCKET_VERSION,
hdrs.SERVER,
hdrs.SET_COOKIE,
hdrs.TE,
hdrs.TRAILER,
hdrs.TRANSFER_ENCODING,
hdrs.URI,
hdrs.UPGRADE,
hdrs.USER_AGENT,
hdrs.VARY,
hdrs.VIA,
hdrs.WWW_AUTHENTICATE,
hdrs.WANT_DIGEST,
hdrs.WARNING,
hdrs.X_FORWARDED_FOR,
hdrs.X_FORWARDED_HOST,
hdrs.X_FORWARDED_PROTO,
)

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
from typing import Any
class reify:
def __init__(self, wrapped: Any) -> None: ...
def __get__(self, inst: Any, owner: Any) -> Any: ...
def __set__(self, inst: Any, value: Any) -> None: ...

View file

@ -1,35 +0,0 @@
cdef class reify:
"""Use as a class method decorator. It operates almost exactly like
the Python `@property` decorator, but it puts the result of the
method it decorates into the instance dict after the first call,
effectively replacing the function it decorates with an instance
variable. It is, in Python parlance, a data descriptor.
"""
cdef object wrapped
cdef object name
def __init__(self, wrapped):
self.wrapped = wrapped
self.name = wrapped.__name__
@property
def __doc__(self):
return self.wrapped.__doc__
def __get__(self, inst, owner):
try:
try:
return inst._cache[self.name]
except KeyError:
val = self.wrapped(inst)
inst._cache[self.name] = val
return val
except AttributeError:
if inst is None:
return self
raise
def __set__(self, inst, value):
raise AttributeError("reified property is read-only")

File diff suppressed because it is too large Load diff

View file

@ -1,875 +0,0 @@
#cython: language_level=3
#
# Based on https://github.com/MagicStack/httptools
#
from __future__ import absolute_import, print_function
from cpython cimport (
Py_buffer,
PyBUF_SIMPLE,
PyBuffer_Release,
PyBytes_AsString,
PyBytes_AsStringAndSize,
PyObject_GetBuffer,
)
from cpython.mem cimport PyMem_Free, PyMem_Malloc
from libc.limits cimport ULLONG_MAX
from libc.string cimport memcpy
from multidict import CIMultiDict as _CIMultiDict, CIMultiDictProxy as _CIMultiDictProxy
from yarl import URL as _URL
from aiohttp import hdrs
from .http_exceptions import (
BadHttpMessage,
BadStatusLine,
ContentLengthError,
InvalidHeader,
InvalidURLError,
LineTooLong,
PayloadEncodingError,
TransferEncodingError,
)
from .http_parser import DeflateBuffer as _DeflateBuffer
from .http_writer import (
HttpVersion as _HttpVersion,
HttpVersion10 as _HttpVersion10,
HttpVersion11 as _HttpVersion11,
)
from .streams import EMPTY_PAYLOAD as _EMPTY_PAYLOAD, StreamReader as _StreamReader
cimport cython
from aiohttp cimport _cparser as cparser
include "_headers.pxi"
from aiohttp cimport _find_header
DEF DEFAULT_FREELIST_SIZE = 250
cdef extern from "Python.h":
int PyByteArray_Resize(object, Py_ssize_t) except -1
Py_ssize_t PyByteArray_Size(object) except -1
char* PyByteArray_AsString(object)
__all__ = ('HttpRequestParser', 'HttpResponseParser',
'RawRequestMessage', 'RawResponseMessage')
cdef object URL = _URL
cdef object URL_build = URL.build
cdef object CIMultiDict = _CIMultiDict
cdef object CIMultiDictProxy = _CIMultiDictProxy
cdef object HttpVersion = _HttpVersion
cdef object HttpVersion10 = _HttpVersion10
cdef object HttpVersion11 = _HttpVersion11
cdef object SEC_WEBSOCKET_KEY1 = hdrs.SEC_WEBSOCKET_KEY1
cdef object CONTENT_ENCODING = hdrs.CONTENT_ENCODING
cdef object EMPTY_PAYLOAD = _EMPTY_PAYLOAD
cdef object StreamReader = _StreamReader
cdef object DeflateBuffer = _DeflateBuffer
cdef inline object extend(object buf, const char* at, size_t length):
cdef Py_ssize_t s
cdef char* ptr
s = PyByteArray_Size(buf)
PyByteArray_Resize(buf, s + length)
ptr = PyByteArray_AsString(buf)
memcpy(ptr + s, at, length)
DEF METHODS_COUNT = 34;
cdef list _http_method = []
for i in range(METHODS_COUNT):
_http_method.append(
cparser.http_method_str(<cparser.http_method> i).decode('ascii'))
cdef inline str http_method_str(int i):
if i < METHODS_COUNT:
return <str>_http_method[i]
else:
return "<unknown>"
cdef inline object find_header(bytes raw_header):
cdef Py_ssize_t size
cdef char *buf
cdef int idx
PyBytes_AsStringAndSize(raw_header, &buf, &size)
idx = _find_header.find_header(buf, size)
if idx == -1:
return raw_header.decode('utf-8', 'surrogateescape')
return headers[idx]
@cython.freelist(DEFAULT_FREELIST_SIZE)
cdef class RawRequestMessage:
cdef readonly str method
cdef readonly str path
cdef readonly object version # HttpVersion
cdef readonly object headers # CIMultiDict
cdef readonly object raw_headers # tuple
cdef readonly object should_close
cdef readonly object compression
cdef readonly object upgrade
cdef readonly object chunked
cdef readonly object url # yarl.URL
def __init__(self, method, path, version, headers, raw_headers,
should_close, compression, upgrade, chunked, url):
self.method = method
self.path = path
self.version = version
self.headers = headers
self.raw_headers = raw_headers
self.should_close = should_close
self.compression = compression
self.upgrade = upgrade
self.chunked = chunked
self.url = url
def __repr__(self):
info = []
info.append(("method", self.method))
info.append(("path", self.path))
info.append(("version", self.version))
info.append(("headers", self.headers))
info.append(("raw_headers", self.raw_headers))
info.append(("should_close", self.should_close))
info.append(("compression", self.compression))
info.append(("upgrade", self.upgrade))
info.append(("chunked", self.chunked))
info.append(("url", self.url))
sinfo = ', '.join(name + '=' + repr(val) for name, val in info)
return '<RawRequestMessage(' + sinfo + ')>'
def _replace(self, **dct):
cdef RawRequestMessage ret
ret = _new_request_message(self.method,
self.path,
self.version,
self.headers,
self.raw_headers,
self.should_close,
self.compression,
self.upgrade,
self.chunked,
self.url)
if "method" in dct:
ret.method = dct["method"]
if "path" in dct:
ret.path = dct["path"]
if "version" in dct:
ret.version = dct["version"]
if "headers" in dct:
ret.headers = dct["headers"]
if "raw_headers" in dct:
ret.raw_headers = dct["raw_headers"]
if "should_close" in dct:
ret.should_close = dct["should_close"]
if "compression" in dct:
ret.compression = dct["compression"]
if "upgrade" in dct:
ret.upgrade = dct["upgrade"]
if "chunked" in dct:
ret.chunked = dct["chunked"]
if "url" in dct:
ret.url = dct["url"]
return ret
cdef _new_request_message(str method,
str path,
object version,
object headers,
object raw_headers,
bint should_close,
object compression,
bint upgrade,
bint chunked,
object url):
cdef RawRequestMessage ret
ret = RawRequestMessage.__new__(RawRequestMessage)
ret.method = method
ret.path = path
ret.version = version
ret.headers = headers
ret.raw_headers = raw_headers
ret.should_close = should_close
ret.compression = compression
ret.upgrade = upgrade
ret.chunked = chunked
ret.url = url
return ret
@cython.freelist(DEFAULT_FREELIST_SIZE)
cdef class RawResponseMessage:
cdef readonly object version # HttpVersion
cdef readonly int code
cdef readonly str reason
cdef readonly object headers # CIMultiDict
cdef readonly object raw_headers # tuple
cdef readonly object should_close
cdef readonly object compression
cdef readonly object upgrade
cdef readonly object chunked
def __init__(self, version, code, reason, headers, raw_headers,
should_close, compression, upgrade, chunked):
self.version = version
self.code = code
self.reason = reason
self.headers = headers
self.raw_headers = raw_headers
self.should_close = should_close
self.compression = compression
self.upgrade = upgrade
self.chunked = chunked
def __repr__(self):
info = []
info.append(("version", self.version))
info.append(("code", self.code))
info.append(("reason", self.reason))
info.append(("headers", self.headers))
info.append(("raw_headers", self.raw_headers))
info.append(("should_close", self.should_close))
info.append(("compression", self.compression))
info.append(("upgrade", self.upgrade))
info.append(("chunked", self.chunked))
sinfo = ', '.join(name + '=' + repr(val) for name, val in info)
return '<RawResponseMessage(' + sinfo + ')>'
cdef _new_response_message(object version,
int code,
str reason,
object headers,
object raw_headers,
bint should_close,
object compression,
bint upgrade,
bint chunked):
cdef RawResponseMessage ret
ret = RawResponseMessage.__new__(RawResponseMessage)
ret.version = version
ret.code = code
ret.reason = reason
ret.headers = headers
ret.raw_headers = raw_headers
ret.should_close = should_close
ret.compression = compression
ret.upgrade = upgrade
ret.chunked = chunked
return ret
@cython.internal
cdef class HttpParser:
cdef:
cparser.http_parser* _cparser
cparser.http_parser_settings* _csettings
bytearray _raw_name
bytearray _raw_value
bint _has_value
object _protocol
object _loop
object _timer
size_t _max_line_size
size_t _max_field_size
size_t _max_headers
bint _response_with_body
bint _read_until_eof
bint _started
object _url
bytearray _buf
str _path
str _reason
object _headers
list _raw_headers
bint _upgraded
list _messages
object _payload
bint _payload_error
object _payload_exception
object _last_error
bint _auto_decompress
int _limit
str _content_encoding
Py_buffer py_buf
def __cinit__(self):
self._cparser = <cparser.http_parser*> \
PyMem_Malloc(sizeof(cparser.http_parser))
if self._cparser is NULL:
raise MemoryError()
self._csettings = <cparser.http_parser_settings*> \
PyMem_Malloc(sizeof(cparser.http_parser_settings))
if self._csettings is NULL:
raise MemoryError()
def __dealloc__(self):
PyMem_Free(self._cparser)
PyMem_Free(self._csettings)
cdef _init(self, cparser.http_parser_type mode,
object protocol, object loop, int limit,
object timer=None,
size_t max_line_size=8190, size_t max_headers=32768,
size_t max_field_size=8190, payload_exception=None,
bint response_with_body=True, bint read_until_eof=False,
bint auto_decompress=True):
cparser.http_parser_init(self._cparser, mode)
self._cparser.data = <void*>self
self._cparser.content_length = 0
cparser.http_parser_settings_init(self._csettings)
self._protocol = protocol
self._loop = loop
self._timer = timer
self._buf = bytearray()
self._payload = None
self._payload_error = 0
self._payload_exception = payload_exception
self._messages = []
self._raw_name = bytearray()
self._raw_value = bytearray()
self._has_value = False
self._max_line_size = max_line_size
self._max_headers = max_headers
self._max_field_size = max_field_size
self._response_with_body = response_with_body
self._read_until_eof = read_until_eof
self._upgraded = False
self._auto_decompress = auto_decompress
self._content_encoding = None
self._csettings.on_url = cb_on_url
self._csettings.on_status = cb_on_status
self._csettings.on_header_field = cb_on_header_field
self._csettings.on_header_value = cb_on_header_value
self._csettings.on_headers_complete = cb_on_headers_complete
self._csettings.on_body = cb_on_body
self._csettings.on_message_begin = cb_on_message_begin
self._csettings.on_message_complete = cb_on_message_complete
self._csettings.on_chunk_header = cb_on_chunk_header
self._csettings.on_chunk_complete = cb_on_chunk_complete
self._last_error = None
self._limit = limit
cdef _process_header(self):
if self._raw_name:
raw_name = bytes(self._raw_name)
raw_value = bytes(self._raw_value)
name = find_header(raw_name)
value = raw_value.decode('utf-8', 'surrogateescape')
self._headers.add(name, value)
if name is CONTENT_ENCODING:
self._content_encoding = value
PyByteArray_Resize(self._raw_name, 0)
PyByteArray_Resize(self._raw_value, 0)
self._has_value = False
self._raw_headers.append((raw_name, raw_value))
cdef _on_header_field(self, char* at, size_t length):
cdef Py_ssize_t size
cdef char *buf
if self._has_value:
self._process_header()
size = PyByteArray_Size(self._raw_name)
PyByteArray_Resize(self._raw_name, size + length)
buf = PyByteArray_AsString(self._raw_name)
memcpy(buf + size, at, length)
cdef _on_header_value(self, char* at, size_t length):
cdef Py_ssize_t size
cdef char *buf
size = PyByteArray_Size(self._raw_value)
PyByteArray_Resize(self._raw_value, size + length)
buf = PyByteArray_AsString(self._raw_value)
memcpy(buf + size, at, length)
self._has_value = True
cdef _on_headers_complete(self):
self._process_header()
method = http_method_str(self._cparser.method)
should_close = not cparser.http_should_keep_alive(self._cparser)
upgrade = self._cparser.upgrade
chunked = self._cparser.flags & cparser.F_CHUNKED
raw_headers = tuple(self._raw_headers)
headers = CIMultiDictProxy(self._headers)
if upgrade or self._cparser.method == 5: # cparser.CONNECT:
self._upgraded = True
# do not support old websocket spec
if SEC_WEBSOCKET_KEY1 in headers:
raise InvalidHeader(SEC_WEBSOCKET_KEY1)
encoding = None
enc = self._content_encoding
if enc is not None:
self._content_encoding = None
enc = enc.lower()
if enc in ('gzip', 'deflate', 'br'):
encoding = enc
if self._cparser.type == cparser.HTTP_REQUEST:
msg = _new_request_message(
method, self._path,
self.http_version(), headers, raw_headers,
should_close, encoding, upgrade, chunked, self._url)
else:
msg = _new_response_message(
self.http_version(), self._cparser.status_code, self._reason,
headers, raw_headers, should_close, encoding,
upgrade, chunked)
if (ULLONG_MAX > self._cparser.content_length > 0 or chunked or
self._cparser.method == 5 or # CONNECT: 5
(self._cparser.status_code >= 199 and
self._cparser.content_length == ULLONG_MAX and
self._read_until_eof)
):
payload = StreamReader(
self._protocol, timer=self._timer, loop=self._loop,
limit=self._limit)
else:
payload = EMPTY_PAYLOAD
self._payload = payload
if encoding is not None and self._auto_decompress:
self._payload = DeflateBuffer(payload, encoding)
if not self._response_with_body:
payload = EMPTY_PAYLOAD
self._messages.append((msg, payload))
cdef _on_message_complete(self):
self._payload.feed_eof()
self._payload = None
cdef _on_chunk_header(self):
self._payload.begin_http_chunk_receiving()
cdef _on_chunk_complete(self):
self._payload.end_http_chunk_receiving()
cdef object _on_status_complete(self):
pass
cdef inline http_version(self):
cdef cparser.http_parser* parser = self._cparser
if parser.http_major == 1:
if parser.http_minor == 0:
return HttpVersion10
elif parser.http_minor == 1:
return HttpVersion11
return HttpVersion(parser.http_major, parser.http_minor)
### Public API ###
def feed_eof(self):
cdef bytes desc
if self._payload is not None:
if self._cparser.flags & cparser.F_CHUNKED:
raise TransferEncodingError(
"Not enough data for satisfy transfer length header.")
elif self._cparser.flags & cparser.F_CONTENTLENGTH:
raise ContentLengthError(
"Not enough data for satisfy content length header.")
elif self._cparser.http_errno != cparser.HPE_OK:
desc = cparser.http_errno_description(
<cparser.http_errno> self._cparser.http_errno)
raise PayloadEncodingError(desc.decode('latin-1'))
else:
self._payload.feed_eof()
elif self._started:
self._on_headers_complete()
if self._messages:
return self._messages[-1][0]
def feed_data(self, data):
cdef:
size_t data_len
size_t nb
PyObject_GetBuffer(data, &self.py_buf, PyBUF_SIMPLE)
data_len = <size_t>self.py_buf.len
nb = cparser.http_parser_execute(
self._cparser,
self._csettings,
<char*>self.py_buf.buf,
data_len)
PyBuffer_Release(&self.py_buf)
if (self._cparser.http_errno != cparser.HPE_OK):
if self._payload_error == 0:
if self._last_error is not None:
ex = self._last_error
self._last_error = None
else:
ex = parser_error_from_errno(
<cparser.http_errno> self._cparser.http_errno)
self._payload = None
raise ex
if self._messages:
messages = self._messages
self._messages = []
else:
messages = ()
if self._upgraded:
return messages, True, data[nb:]
else:
return messages, False, b''
def set_upgraded(self, val):
self._upgraded = val
cdef class HttpRequestParser(HttpParser):
def __init__(self, protocol, loop, int limit, timer=None,
size_t max_line_size=8190, size_t max_headers=32768,
size_t max_field_size=8190, payload_exception=None,
bint response_with_body=True, bint read_until_eof=False,
):
self._init(cparser.HTTP_REQUEST, protocol, loop, limit, timer,
max_line_size, max_headers, max_field_size,
payload_exception, response_with_body, read_until_eof)
cdef object _on_status_complete(self):
cdef Py_buffer py_buf
if not self._buf:
return
self._path = self._buf.decode('utf-8', 'surrogateescape')
if self._cparser.method == 5: # CONNECT
self._url = URL(self._path)
else:
PyObject_GetBuffer(self._buf, &py_buf, PyBUF_SIMPLE)
try:
self._url = _parse_url(<char*>py_buf.buf,
py_buf.len)
finally:
PyBuffer_Release(&py_buf)
PyByteArray_Resize(self._buf, 0)
cdef class HttpResponseParser(HttpParser):
def __init__(self, protocol, loop, int limit, timer=None,
size_t max_line_size=8190, size_t max_headers=32768,
size_t max_field_size=8190, payload_exception=None,
bint response_with_body=True, bint read_until_eof=False,
bint auto_decompress=True
):
self._init(cparser.HTTP_RESPONSE, protocol, loop, limit, timer,
max_line_size, max_headers, max_field_size,
payload_exception, response_with_body, read_until_eof,
auto_decompress)
cdef object _on_status_complete(self):
if self._buf:
self._reason = self._buf.decode('utf-8', 'surrogateescape')
PyByteArray_Resize(self._buf, 0)
else:
self._reason = self._reason or ''
cdef int cb_on_message_begin(cparser.http_parser* parser) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
pyparser._started = True
pyparser._headers = CIMultiDict()
pyparser._raw_headers = []
PyByteArray_Resize(pyparser._buf, 0)
pyparser._path = None
pyparser._reason = None
return 0
cdef int cb_on_url(cparser.http_parser* parser,
const char *at, size_t length) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
try:
if length > pyparser._max_line_size:
raise LineTooLong(
'Status line is too long', pyparser._max_line_size, length)
extend(pyparser._buf, at, length)
except BaseException as ex:
pyparser._last_error = ex
return -1
else:
return 0
cdef int cb_on_status(cparser.http_parser* parser,
const char *at, size_t length) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
cdef str reason
try:
if length > pyparser._max_line_size:
raise LineTooLong(
'Status line is too long', pyparser._max_line_size, length)
extend(pyparser._buf, at, length)
except BaseException as ex:
pyparser._last_error = ex
return -1
else:
return 0
cdef int cb_on_header_field(cparser.http_parser* parser,
const char *at, size_t length) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
cdef Py_ssize_t size
try:
pyparser._on_status_complete()
size = len(pyparser._raw_name) + length
if size > pyparser._max_field_size:
raise LineTooLong(
'Header name is too long', pyparser._max_field_size, size)
pyparser._on_header_field(at, length)
except BaseException as ex:
pyparser._last_error = ex
return -1
else:
return 0
cdef int cb_on_header_value(cparser.http_parser* parser,
const char *at, size_t length) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
cdef Py_ssize_t size
try:
size = len(pyparser._raw_value) + length
if size > pyparser._max_field_size:
raise LineTooLong(
'Header value is too long', pyparser._max_field_size, size)
pyparser._on_header_value(at, length)
except BaseException as ex:
pyparser._last_error = ex
return -1
else:
return 0
cdef int cb_on_headers_complete(cparser.http_parser* parser) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
try:
pyparser._on_status_complete()
pyparser._on_headers_complete()
except BaseException as exc:
pyparser._last_error = exc
return -1
else:
if pyparser._cparser.upgrade or pyparser._cparser.method == 5: # CONNECT
return 2
else:
return 0
cdef int cb_on_body(cparser.http_parser* parser,
const char *at, size_t length) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
cdef bytes body = at[:length]
try:
pyparser._payload.feed_data(body, length)
except BaseException as exc:
if pyparser._payload_exception is not None:
pyparser._payload.set_exception(pyparser._payload_exception(str(exc)))
else:
pyparser._payload.set_exception(exc)
pyparser._payload_error = 1
return -1
else:
return 0
cdef int cb_on_message_complete(cparser.http_parser* parser) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
try:
pyparser._started = False
pyparser._on_message_complete()
except BaseException as exc:
pyparser._last_error = exc
return -1
else:
return 0
cdef int cb_on_chunk_header(cparser.http_parser* parser) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
try:
pyparser._on_chunk_header()
except BaseException as exc:
pyparser._last_error = exc
return -1
else:
return 0
cdef int cb_on_chunk_complete(cparser.http_parser* parser) except -1:
cdef HttpParser pyparser = <HttpParser>parser.data
try:
pyparser._on_chunk_complete()
except BaseException as exc:
pyparser._last_error = exc
return -1
else:
return 0
cdef parser_error_from_errno(cparser.http_errno errno):
cdef bytes desc = cparser.http_errno_description(errno)
if errno in (cparser.HPE_CB_message_begin,
cparser.HPE_CB_url,
cparser.HPE_CB_header_field,
cparser.HPE_CB_header_value,
cparser.HPE_CB_headers_complete,
cparser.HPE_CB_body,
cparser.HPE_CB_message_complete,
cparser.HPE_CB_status,
cparser.HPE_CB_chunk_header,
cparser.HPE_CB_chunk_complete):
cls = BadHttpMessage
elif errno == cparser.HPE_INVALID_STATUS:
cls = BadStatusLine
elif errno == cparser.HPE_INVALID_METHOD:
cls = BadStatusLine
elif errno == cparser.HPE_INVALID_URL:
cls = InvalidURLError
else:
cls = BadHttpMessage
return cls(desc.decode('latin-1'))
def parse_url(url):
cdef:
Py_buffer py_buf
char* buf_data
PyObject_GetBuffer(url, &py_buf, PyBUF_SIMPLE)
try:
buf_data = <char*>py_buf.buf
return _parse_url(buf_data, py_buf.len)
finally:
PyBuffer_Release(&py_buf)
cdef _parse_url(char* buf_data, size_t length):
cdef:
cparser.http_parser_url* parsed
int res
str schema = None
str host = None
object port = None
str path = None
str query = None
str fragment = None
str user = None
str password = None
str userinfo = None
object result = None
int off
int ln
parsed = <cparser.http_parser_url*> \
PyMem_Malloc(sizeof(cparser.http_parser_url))
if parsed is NULL:
raise MemoryError()
cparser.http_parser_url_init(parsed)
try:
res = cparser.http_parser_parse_url(buf_data, length, 0, parsed)
if res == 0:
if parsed.field_set & (1 << cparser.UF_SCHEMA):
off = parsed.field_data[<int>cparser.UF_SCHEMA].off
ln = parsed.field_data[<int>cparser.UF_SCHEMA].len
schema = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
else:
schema = ''
if parsed.field_set & (1 << cparser.UF_HOST):
off = parsed.field_data[<int>cparser.UF_HOST].off
ln = parsed.field_data[<int>cparser.UF_HOST].len
host = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
else:
host = ''
if parsed.field_set & (1 << cparser.UF_PORT):
port = parsed.port
if parsed.field_set & (1 << cparser.UF_PATH):
off = parsed.field_data[<int>cparser.UF_PATH].off
ln = parsed.field_data[<int>cparser.UF_PATH].len
path = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
else:
path = ''
if parsed.field_set & (1 << cparser.UF_QUERY):
off = parsed.field_data[<int>cparser.UF_QUERY].off
ln = parsed.field_data[<int>cparser.UF_QUERY].len
query = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
else:
query = ''
if parsed.field_set & (1 << cparser.UF_FRAGMENT):
off = parsed.field_data[<int>cparser.UF_FRAGMENT].off
ln = parsed.field_data[<int>cparser.UF_FRAGMENT].len
fragment = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
else:
fragment = ''
if parsed.field_set & (1 << cparser.UF_USERINFO):
off = parsed.field_data[<int>cparser.UF_USERINFO].off
ln = parsed.field_data[<int>cparser.UF_USERINFO].len
userinfo = buf_data[off:off+ln].decode('utf-8', 'surrogateescape')
user, sep, password = userinfo.partition(':')
return URL_build(scheme=schema,
user=user, password=password, host=host, port=port,
path=path, query_string=query, fragment=fragment, encoded=True)
else:
raise InvalidURLError("invalid url {!r}".format(buf_data))
finally:
PyMem_Free(parsed)

File diff suppressed because it is too large Load diff

View file

@ -1,151 +0,0 @@
from cpython.bytes cimport PyBytes_FromStringAndSize
from cpython.exc cimport PyErr_NoMemory
from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc
from cpython.object cimport PyObject_Str
from libc.stdint cimport uint8_t, uint64_t
from libc.string cimport memcpy
from multidict import istr
DEF BUF_SIZE = 16 * 1024 # 16KiB
cdef char BUFFER[BUF_SIZE]
cdef object _istr = istr
# ----------------- writer ---------------------------
cdef struct Writer:
char *buf
Py_ssize_t size
Py_ssize_t pos
cdef inline void _init_writer(Writer* writer):
writer.buf = &BUFFER[0]
writer.size = BUF_SIZE
writer.pos = 0
cdef inline void _release_writer(Writer* writer):
if writer.buf != BUFFER:
PyMem_Free(writer.buf)
cdef inline int _write_byte(Writer* writer, uint8_t ch):
cdef char * buf
cdef Py_ssize_t size
if writer.pos == writer.size:
# reallocate
size = writer.size + BUF_SIZE
if writer.buf == BUFFER:
buf = <char*>PyMem_Malloc(size)
if buf == NULL:
PyErr_NoMemory()
return -1
memcpy(buf, writer.buf, writer.size)
else:
buf = <char*>PyMem_Realloc(writer.buf, size)
if buf == NULL:
PyErr_NoMemory()
return -1
writer.buf = buf
writer.size = size
writer.buf[writer.pos] = <char>ch
writer.pos += 1
return 0
cdef inline int _write_utf8(Writer* writer, Py_UCS4 symbol):
cdef uint64_t utf = <uint64_t> symbol
if utf < 0x80:
return _write_byte(writer, <uint8_t>utf)
elif utf < 0x800:
if _write_byte(writer, <uint8_t>(0xc0 | (utf >> 6))) < 0:
return -1
return _write_byte(writer, <uint8_t>(0x80 | (utf & 0x3f)))
elif 0xD800 <= utf <= 0xDFFF:
# surogate pair, ignored
return 0
elif utf < 0x10000:
if _write_byte(writer, <uint8_t>(0xe0 | (utf >> 12))) < 0:
return -1
if _write_byte(writer, <uint8_t>(0x80 | ((utf >> 6) & 0x3f))) < 0:
return -1
return _write_byte(writer, <uint8_t>(0x80 | (utf & 0x3f)))
elif utf > 0x10FFFF:
# symbol is too large
return 0
else:
if _write_byte(writer, <uint8_t>(0xf0 | (utf >> 18))) < 0:
return -1
if _write_byte(writer,
<uint8_t>(0x80 | ((utf >> 12) & 0x3f))) < 0:
return -1
if _write_byte(writer,
<uint8_t>(0x80 | ((utf >> 6) & 0x3f))) < 0:
return -1
return _write_byte(writer, <uint8_t>(0x80 | (utf & 0x3f)))
cdef inline int _write_str(Writer* writer, str s):
cdef Py_UCS4 ch
for ch in s:
if _write_utf8(writer, ch) < 0:
return -1
# --------------- _serialize_headers ----------------------
cdef str to_str(object s):
typ = type(s)
if typ is str:
return <str>s
elif typ is _istr:
return PyObject_Str(s)
elif not isinstance(s, str):
raise TypeError("Cannot serialize non-str key {!r}".format(s))
else:
return str(s)
def _serialize_headers(str status_line, headers):
cdef Writer writer
cdef object key
cdef object val
cdef bytes ret
_init_writer(&writer)
try:
if _write_str(&writer, status_line) < 0:
raise
if _write_byte(&writer, b'\r') < 0:
raise
if _write_byte(&writer, b'\n') < 0:
raise
for key, val in headers.items():
if _write_str(&writer, to_str(key)) < 0:
raise
if _write_byte(&writer, b':') < 0:
raise
if _write_byte(&writer, b' ') < 0:
raise
if _write_str(&writer, to_str(val)) < 0:
raise
if _write_byte(&writer, b'\r') < 0:
raise
if _write_byte(&writer, b'\n') < 0:
raise
if _write_byte(&writer, b'\r') < 0:
raise
if _write_byte(&writer, b'\n') < 0:
raise
return PyBytes_FromStringAndSize(writer.buf, writer.pos)
finally:
_release_writer(&writer)

File diff suppressed because it is too large Load diff

View file

@ -1,56 +0,0 @@
from cpython cimport PyBytes_AsString
#from cpython cimport PyByteArray_AsString # cython still not exports that
cdef extern from "Python.h":
char* PyByteArray_AsString(bytearray ba) except NULL
from libc.stdint cimport uint32_t, uint64_t, uintmax_t
def _websocket_mask_cython(object mask, object data):
"""Note, this function mutates its `data` argument
"""
cdef:
Py_ssize_t data_len, i
# bit operations on signed integers are implementation-specific
unsigned char * in_buf
const unsigned char * mask_buf
uint32_t uint32_msk
uint64_t uint64_msk
assert len(mask) == 4
if not isinstance(mask, bytes):
mask = bytes(mask)
if isinstance(data, bytearray):
data = <bytearray>data
else:
data = bytearray(data)
data_len = len(data)
in_buf = <unsigned char*>PyByteArray_AsString(data)
mask_buf = <const unsigned char*>PyBytes_AsString(mask)
uint32_msk = (<uint32_t*>mask_buf)[0]
# TODO: align in_data ptr to achieve even faster speeds
# does it need in python ?! malloc() always aligns to sizeof(long) bytes
if sizeof(size_t) >= 8:
uint64_msk = uint32_msk
uint64_msk = (uint64_msk << 32) | uint32_msk
while data_len >= 8:
(<uint64_t*>in_buf)[0] ^= uint64_msk
in_buf += 8
data_len -= 8
while data_len >= 4:
(<uint32_t*>in_buf)[0] ^= uint32_msk
in_buf += 4
data_len -= 4
for i in range(0, data_len):
in_buf[i] ^= mask_buf[i]

View file

@ -1,200 +0,0 @@
import asyncio
import logging
from abc import ABC, abstractmethod
from collections.abc import Sized
from http.cookies import BaseCookie, Morsel
from typing import (
TYPE_CHECKING,
Any,
Awaitable,
Callable,
Dict,
Generator,
Iterable,
List,
Optional,
Tuple,
)
from multidict import CIMultiDict
from yarl import URL
from .helpers import get_running_loop
from .typedefs import LooseCookies
if TYPE_CHECKING: # pragma: no cover
from .web_app import Application
from .web_exceptions import HTTPException
from .web_request import BaseRequest, Request
from .web_response import StreamResponse
else:
BaseRequest = Request = Application = StreamResponse = None
HTTPException = None
class AbstractRouter(ABC):
def __init__(self) -> None:
self._frozen = False
def post_init(self, app: Application) -> None:
"""Post init stage.
Not an abstract method for sake of backward compatibility,
but if the router wants to be aware of the application
it can override this.
"""
@property
def frozen(self) -> bool:
return self._frozen
def freeze(self) -> None:
"""Freeze router."""
self._frozen = True
@abstractmethod
async def resolve(self, request: Request) -> "AbstractMatchInfo":
"""Return MATCH_INFO for given request"""
class AbstractMatchInfo(ABC):
@property # pragma: no branch
@abstractmethod
def handler(self) -> Callable[[Request], Awaitable[StreamResponse]]:
"""Execute matched request handler"""
@property
@abstractmethod
def expect_handler(self) -> Callable[[Request], Awaitable[None]]:
"""Expect handler for 100-continue processing"""
@property # pragma: no branch
@abstractmethod
def http_exception(self) -> Optional[HTTPException]:
"""HTTPException instance raised on router's resolving, or None"""
@abstractmethod # pragma: no branch
def get_info(self) -> Dict[str, Any]:
"""Return a dict with additional info useful for introspection"""
@property # pragma: no branch
@abstractmethod
def apps(self) -> Tuple[Application, ...]:
"""Stack of nested applications.
Top level application is left-most element.
"""
@abstractmethod
def add_app(self, app: Application) -> None:
"""Add application to the nested apps stack."""
@abstractmethod
def freeze(self) -> None:
"""Freeze the match info.
The method is called after route resolution.
After the call .add_app() is forbidden.
"""
class AbstractView(ABC):
"""Abstract class based view."""
def __init__(self, request: Request) -> None:
self._request = request
@property
def request(self) -> Request:
"""Request instance."""
return self._request
@abstractmethod
def __await__(self) -> Generator[Any, None, StreamResponse]:
"""Execute the view handler."""
class AbstractResolver(ABC):
"""Abstract DNS resolver."""
@abstractmethod
async def resolve(self, host: str, port: int, family: int) -> List[Dict[str, Any]]:
"""Return IP address for given hostname"""
@abstractmethod
async def close(self) -> None:
"""Release resolver"""
if TYPE_CHECKING: # pragma: no cover
IterableBase = Iterable[Morsel[str]]
else:
IterableBase = Iterable
class AbstractCookieJar(Sized, IterableBase):
"""Abstract Cookie Jar."""
def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None:
self._loop = get_running_loop(loop)
@abstractmethod
def clear(self) -> None:
"""Clear all cookies."""
@abstractmethod
def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:
"""Update cookies."""
@abstractmethod
def filter_cookies(self, request_url: URL) -> "BaseCookie[str]":
"""Return the jar's cookies filtered by their attributes."""
class AbstractStreamWriter(ABC):
"""Abstract stream writer."""
buffer_size = 0
output_size = 0
length = 0 # type: Optional[int]
@abstractmethod
async def write(self, chunk: bytes) -> None:
"""Write chunk into stream."""
@abstractmethod
async def write_eof(self, chunk: bytes = b"") -> None:
"""Write last chunk."""
@abstractmethod
async def drain(self) -> None:
"""Flush the write buffer."""
@abstractmethod
def enable_compression(self, encoding: str = "deflate") -> None:
"""Enable HTTP body compression"""
@abstractmethod
def enable_chunking(self) -> None:
"""Enable HTTP chunked mode"""
@abstractmethod
async def write_headers(
self, status_line: str, headers: "CIMultiDict[str]"
) -> None:
"""Write HTTP headers"""
class AbstractAccessLogger(ABC):
"""Abstract writer to access log."""
def __init__(self, logger: logging.Logger, log_format: str) -> None:
self.logger = logger
self.log_format = log_format
@abstractmethod
def log(self, request: BaseRequest, response: StreamResponse, time: float) -> None:
"""Emit log to logger."""

View file

@ -1,87 +0,0 @@
import asyncio
from typing import Optional, cast
from .tcp_helpers import tcp_nodelay
class BaseProtocol(asyncio.Protocol):
__slots__ = (
"_loop",
"_paused",
"_drain_waiter",
"_connection_lost",
"_reading_paused",
"transport",
)
def __init__(self, loop: asyncio.AbstractEventLoop) -> None:
self._loop = loop # type: asyncio.AbstractEventLoop
self._paused = False
self._drain_waiter = None # type: Optional[asyncio.Future[None]]
self._connection_lost = False
self._reading_paused = False
self.transport = None # type: Optional[asyncio.Transport]
def pause_writing(self) -> None:
assert not self._paused
self._paused = True
def resume_writing(self) -> None:
assert self._paused
self._paused = False
waiter = self._drain_waiter
if waiter is not None:
self._drain_waiter = None
if not waiter.done():
waiter.set_result(None)
def pause_reading(self) -> None:
if not self._reading_paused and self.transport is not None:
try:
self.transport.pause_reading()
except (AttributeError, NotImplementedError, RuntimeError):
pass
self._reading_paused = True
def resume_reading(self) -> None:
if self._reading_paused and self.transport is not None:
try:
self.transport.resume_reading()
except (AttributeError, NotImplementedError, RuntimeError):
pass
self._reading_paused = False
def connection_made(self, transport: asyncio.BaseTransport) -> None:
tr = cast(asyncio.Transport, transport)
tcp_nodelay(tr, True)
self.transport = tr
def connection_lost(self, exc: Optional[BaseException]) -> None:
self._connection_lost = True
# Wake up the writer if currently paused.
self.transport = None
if not self._paused:
return
waiter = self._drain_waiter
if waiter is None:
return
self._drain_waiter = None
if waiter.done():
return
if exc is None:
waiter.set_result(None)
else:
waiter.set_exception(exc)
async def _drain_helper(self) -> None:
if self._connection_lost:
raise ConnectionResetError("Connection lost")
if not self._paused:
return
waiter = self._drain_waiter
assert waiter is None or waiter.cancelled()
waiter = self._loop.create_future()
self._drain_waiter = waiter
await waiter

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