Compare commits

...

36 Commits

Author SHA1 Message Date
Cameron Gutman 79bf17fe24 Add fastlane metadata for v9.10.1 2021-08-21 15:25:45 -05:00
Cameron Gutman 31f66031bc Version 9.10.1 2021-08-21 15:22:05 -05:00
Cameron Gutman d3f2284791 Update NDK to r23 2021-08-18 00:33:57 -05:00
Cameron Gutman ec647608c4 Allow state loss when committing SettingsFragment 2021-08-18 00:24:30 -05:00
Cameron Gutman 597582ddd8 Add workaround for NPE in getNetworkInterfaces() 2021-08-18 00:04:34 -05:00
Cameron Gutman c6d9889182 Fix lint results path for Gradle 7.0 2021-08-10 02:12:03 -05:00
Cameron Gutman 7c58234174 Use JDK 11 for Gradle 7.0 2021-08-10 02:02:24 -05:00
Cameron Gutman ae9282b0af Plumb UTF-8 text support through to NvConnection 2021-08-10 00:14:13 -05:00
Cameron Gutman 310ba646fc Update Gradle 2021-08-09 23:24:44 -05:00
Cameron Gutman 3e0bf25acb Update moonlight-common-c 2021-07-17 14:16:40 -05:00
Cameron Gutman f3d277c94a Update Maven dependencies 2021-07-17 14:01:59 -05:00
Cameron Gutman 04545ecbb0 Avoid tons of redundant calls to InputEvent.getSource() 2021-07-17 14:01:12 -05:00
Cameron Gutman 5350651d6f Fix crash when using USB driver on Android 12 2021-07-17 13:59:11 -05:00
Cameron Gutman f2e2e28419 Fix NPE if we receive a SOURCE_CLASS_POSITION event with no associated device 2021-07-17 13:15:57 -05:00
Cameron Gutman b9031785ac Fix crash if maxShortcutCountPerActivity is zero 2021-07-17 13:08:25 -05:00
Cameron Gutman 91a72474a1 Version 9.10 r2 2021-07-16 21:01:16 -05:00
Cameron Gutman b6e7c425c6 Fix input from SOURCE_TRACKPAD devices 2021-07-16 20:44:01 -05:00
Cameron Gutman 834ace4566 Add SoC details and performance class to exception data 2021-07-16 20:00:03 -05:00
Cameron Gutman 54af70005d Fix spurious gamepad removal when entering PiP with PS4 controller on Android 12
The relative mouse axes AXIS_RELATIVE_X/Y are added/removed when gaining/losing input focus
2021-07-16 19:51:14 -05:00
Cameron Gutman f2bf168925 Fix possible rumble crash if only the lower motor byte is non-zero 2021-07-16 19:25:10 -05:00
Cameron Gutman 27ffbd8dec Version 9.10 2021-07-16 19:23:37 -05:00
Cameron Gutman eaa82592fe Merge remote-tracking branch 'origin/weblate' 2021-07-15 19:59:07 -05:00
Cameron Gutman 73784585a8 Fix new Android 12 rumble code based on real hardware testing
Independent rumble motor controller tested working on:
- DualShock 4 (USB and BT)
- DualShock 3 (USB)
- Xbox Series X (USB)
2021-07-15 19:51:08 -05:00
Cameron Gutman 262d562dd9 Implement enhanced rumble support for Android 12 devices
This allows independent control of large and small motors which
was not possible with the old single Vibrator API.

Currently untested on real hardware.
2021-07-14 20:18:35 -05:00
Cameron Gutman ab4f904dc9 Target Android 12 2021-07-14 20:04:46 -05:00
Cameron Gutman fc4fdd5ee2 Implement seamless PiP entry on Android 12 2021-07-14 20:00:53 -05:00
Cameron Gutman 41c5b62b1a Update AGP to 4.2.2 2021-07-14 19:58:12 -05:00
Cameron Gutman 239cb0435c Add new backup rules for Android 12 2021-07-14 19:58:01 -05:00
bruh c6ccc7a6e2 Translated using Weblate (Vietnamese)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/vi/
2021-07-05 18:33:43 +02:00
Cameron Gutman 6cedb9019c Pass RTSP session URL to moonlight-common-c for dynamic ports 2021-07-02 17:41:07 -05:00
Furkan 8bc64f0438 Translated using Weblate (Turkish)
Currently translated at 19.0% (36 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/tr/
2021-07-02 18:33:32 +02:00
WALKTHROUGH RAYMAND LEGENDS 89e6e39e58 Translated using Weblate (Hungarian)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/hu/
2021-07-02 18:33:31 +02:00
Furkan 645761f677 Added translation using Weblate (Turkish) 2021-07-01 17:53:08 +02:00
DankXylese 0fc60f7855 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/uk/
2021-06-30 13:33:24 +02:00
LUTEN VR ce38460d87 Translated using Weblate (Korean)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/ko/
2021-06-28 03:36:01 +02:00
Jorys Paulin de8e759d3a Translated using Weblate (French)
Currently translated at 100.0% (189 of 189 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/fr/
2021-06-28 03:36:00 +02:00
29 changed files with 472 additions and 183 deletions
+9 -9
View File
@@ -1,16 +1,16 @@
apply plugin: 'com.android.application'
android {
ndkVersion "22.1.7171670"
ndkVersion "23.0.7599858"
compileSdkVersion 30
compileSdkVersion 31
defaultConfig {
minSdkVersion 16
targetSdkVersion 30
targetSdkVersion 31
versionName "9.9.6"
versionCode = 268
versionName "9.10.1"
versionCode = 271
}
flavorDimensions "root"
@@ -118,10 +118,10 @@ android {
}
dependencies {
implementation 'org.bouncycastle:bcprov-jdk15on:1.66'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.66'
implementation 'org.bouncycastle:bcprov-jdk15on:1.69'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.69'
implementation 'org.jcodec:jcodec:0.2.3'
implementation 'com.squareup.okhttp3:okhttp:3.12.12'
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
implementation 'com.squareup.okio:okio:1.17.5'
implementation 'org.jmdns:jmdns:3.5.5'
implementation 'org.jmdns:jmdns:3.5.7'
}
+1
View File
@@ -35,6 +35,7 @@
<application
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:dataExtractionRules="@xml/backup_rules_s"
android:networkSecurityConfig="@xml/network_security_config"
android:isGame="true"
android:banner="@drawable/atv_banner"
+82 -21
View File
@@ -78,7 +78,6 @@ import android.widget.TextView;
import android.widget.Toast;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Field;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -118,6 +117,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private boolean displayedFailureDialog = false;
private boolean connecting = false;
private boolean connected = false;
private boolean autoEnterPip = false;
private boolean surfaceCreated = false;
private boolean attemptedConnection = false;
@@ -571,23 +571,49 @@ public class Game extends Activity implements SurfaceHolder.Callback,
}
}
@TargetApi(Build.VERSION_CODES.O)
private PictureInPictureParams getPictureInPictureParams(boolean autoEnter) {
PictureInPictureParams.Builder builder =
new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(prefConfig.width, prefConfig.height))
.setSourceRectHint(new Rect(
streamView.getLeft(), streamView.getTop(),
streamView.getRight(), streamView.getBottom()));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
builder.setAutoEnterEnabled(autoEnter);
builder.setSeamlessResizeEnabled(true);
}
return builder.build();
}
private void setPipAutoEnter(boolean autoEnter) {
if (!prefConfig.enablePip) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
setPictureInPictureParams(getPictureInPictureParams(autoEnter));
}
else {
autoEnterPip = autoEnter;
}
}
@Override
public void onUserLeaveHint() {
super.onUserLeaveHint();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (prefConfig.enablePip && connected) {
// PiP is only supported on Oreo and later, and we don't need to manually enter PiP on
// Android S and later.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
if (autoEnterPip) {
try {
// This has thrown all sorts of weird exceptions on Samsung devices
// running Oreo. Just eat them and close gracefully on leave, rather
// than crashing.
enterPictureInPictureMode(
new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(prefConfig.width, prefConfig.height))
.setSourceRectHint(new Rect(
streamView.getLeft(), streamView.getTop(),
streamView.getRight(), streamView.getBottom()))
.build());
enterPictureInPictureMode(getPictureInPictureParams(false));
} catch (Exception e) {
e.printStackTrace();
}
@@ -800,6 +826,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private final Runnable hideSystemUi = new Runnable() {
@Override
public void run() {
// TODO: Do we want to use WindowInsetsController here on R+ instead of
// SYSTEM_UI_FLAG_IMMERSIVE_STICKY? They seem to do the same thing as of S...
// In multi-window mode on N+, we need to drop our layout flags or we'll
// be drawing underneath the system UI.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode()) {
@@ -1060,8 +1089,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Handle a synthetic back button event that some Android OS versions
// create as a result of a right-click. This event WILL repeat if
// the right mouse button is held down, so we ignore those.
if ((event.getSource() == InputDevice.SOURCE_MOUSE ||
event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE) &&
int eventSource = event.getSource();
if ((eventSource == InputDevice.SOURCE_MOUSE ||
eventSource == InputDevice.SOURCE_MOUSE_RELATIVE) &&
event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
// Send the right mouse button event if mouse back and forward
@@ -1130,8 +1160,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Handle a synthetic back button event that some Android OS versions
// create as a result of a right-click.
if ((event.getSource() == InputDevice.SOURCE_MOUSE ||
event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE) &&
int eventSource = event.getSource();
if ((eventSource == InputDevice.SOURCE_MOUSE ||
eventSource == InputDevice.SOURCE_MOUSE_RELATIVE) &&
event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
// Send the right mouse button event if mouse back and forward
@@ -1204,18 +1235,20 @@ public class Game extends Activity implements SurfaceHolder.Callback,
return false;
}
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
int eventSource = event.getSource();
if ((eventSource & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
if (controllerHandler.handleMotionEvent(event)) {
return true;
}
}
else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0 ||
event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE)
else if ((eventSource & InputDevice.SOURCE_CLASS_POINTER) != 0 ||
(eventSource & InputDevice.SOURCE_CLASS_POSITION) != 0 ||
eventSource == InputDevice.SOURCE_MOUSE_RELATIVE)
{
// This case is for mice and non-finger touch devices
if (event.getSource() == InputDevice.SOURCE_MOUSE ||
event.getSource() == InputDevice.SOURCE_TOUCHPAD ||
event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE ||
if (eventSource == InputDevice.SOURCE_MOUSE ||
(eventSource & InputDevice.SOURCE_CLASS_POSITION) != 0 || // SOURCE_TOUCHPAD
eventSource == InputDevice.SOURCE_MOUSE_RELATIVE ||
(event.getPointerCount() >= 1 &&
(event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE ||
event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS ||
@@ -1242,8 +1275,34 @@ public class Game extends Activity implements SurfaceHolder.Callback,
conn.sendMouseMove(deltaX, deltaY);
}
}
else if ((eventSource & InputDevice.SOURCE_CLASS_POSITION) != 0) {
// If this input device is not associated with the view itself (like a trackpad),
// we'll convert the device-specific coordinates to use to send the cursor position.
// This really isn't ideal but it's probably better than nothing.
//
// Trackpad on newer versions of Android (Oreo and later) should be caught by the
// relative axes case above. If we get here, we're on an older version that doesn't
// support pointer capture.
InputDevice device = event.getDevice();
if (device != null) {
InputDevice.MotionRange xRange = device.getMotionRange(MotionEvent.AXIS_X, eventSource);
InputDevice.MotionRange yRange = device.getMotionRange(MotionEvent.AXIS_Y, eventSource);
// All touchpads coordinate planes should start at (0, 0)
if (xRange != null && yRange != null && xRange.getMin() == 0 && yRange.getMin() == 0) {
int xMax = (int)xRange.getMax();
int yMax = (int)yRange.getMax();
// Touchpads must be smaller than (65535, 65535)
if (xMax <= Short.MAX_VALUE && yMax <= Short.MAX_VALUE) {
conn.sendMousePosition((short)event.getX(), (short)event.getY(),
(short)xMax, (short)yMax);
}
}
}
}
else if (view != null) {
// Otherwise send absolute position
// Otherwise send absolute position based on the view for SOURCE_CLASS_POINTER
updateMousePosition(view, event);
}
@@ -1538,6 +1597,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private void stopConnection() {
if (connecting || connected) {
setPipAutoEnter(false);
connecting = connected = false;
controllerHandler.stop();
@@ -1702,6 +1762,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
spinner = null;
}
setPipAutoEnter(true);
connected = true;
connecting = false;
@@ -1,5 +1,6 @@
package com.limelight.binding.input;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.hardware.input.InputManager;
@@ -7,9 +8,11 @@ import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.media.AudioAttributes;
import android.os.Build;
import android.os.CombinedVibration;
import android.os.SystemClock;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.os.VibratorManager;
import android.util.SparseArray;
import android.view.InputDevice;
import android.view.InputEvent;
@@ -155,11 +158,36 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
}
}
// This can happen when gaining/losing input focus with some devices.
// Input devices that have a trackpad may gain/lose AXIS_RELATIVE_X/Y.
@Override
public void onInputDeviceChanged(int deviceId) {
// Remove and re-add
onInputDeviceRemoved(deviceId);
onInputDeviceAdded(deviceId);
InputDevice device = InputDevice.getDevice(deviceId);
if (device == null) {
return;
}
// If we don't have a context for this device, we don't need to update anything
InputDeviceContext existingContext = inputDeviceContexts.get(deviceId);
if (existingContext == null) {
return;
}
LimeLog.info("Device changed: "+existingContext.name+" ("+deviceId+")");
// Don't release the controller number, because we will carry it over if it is present.
// We also want to make sure the change is invisible to the host PC to avoid an add/remove
// cycle for the gamepad which may break some games.
existingContext.destroy();
InputDeviceContext newContext = createInputDeviceContextForDevice(device);
// Copy over existing controller number state
newContext.assignedControllerNumber = existingContext.assignedControllerNumber;
newContext.reservedControllerNumber = existingContext.reservedControllerNumber;
newContext.controllerNumber = existingContext.controllerNumber;
inputDeviceContexts.put(deviceId, newContext);
}
public void stop() {
@@ -487,7 +515,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
context.productId = dev.getProductId();
}
if (dev.getVibrator().hasVibrator()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && hasDualAmplitudeControlledRumbleVibrators(dev.getVibratorManager())) {
context.vibratorManager = dev.getVibratorManager();
}
else if (dev.getVibrator().hasVibrator()) {
context.vibrator = dev.getVibrator();
}
@@ -1283,7 +1314,58 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
}
}
private void rumbleVibrator(Vibrator vibrator, short lowFreqMotor, short highFreqMotor) {
@TargetApi(31)
private boolean hasDualAmplitudeControlledRumbleVibrators(VibratorManager vm) {
int[] vibratorIds = vm.getVibratorIds();
// There must be exactly 2 vibrators on this device
if (vibratorIds.length != 2) {
return false;
}
// Both vibrators must have amplitude control
for (int vid : vibratorIds) {
if (!vm.getVibrator(vid).hasAmplitudeControl()) {
return false;
}
}
return true;
}
// This must only be called if hasDualAmplitudeControlledRumbleVibrators() is true!
@TargetApi(31)
private void rumbleDualVibrators(VibratorManager vm, short lowFreqMotor, short highFreqMotor) {
// Normalize motor values to 0-255 amplitudes for VibrationManager
highFreqMotor = (short)((highFreqMotor >> 8) & 0xFF);
lowFreqMotor = (short)((lowFreqMotor >> 8) & 0xFF);
// If they're both zero, we can just call cancel().
if (lowFreqMotor == 0 && highFreqMotor == 0) {
vm.cancel();
return;
}
// There's no documentation that states that vibrators for FF_RUMBLE input devices will
// always be enumerated in this order, but it seems consistent between Xbox Series X (USB),
// PS3 (USB), and PS4 (USB+BT) controllers on Android 12 Beta 3.
int[] vibratorIds = vm.getVibratorIds();
int[] vibratorAmplitudes = new int[] { highFreqMotor, lowFreqMotor };
CombinedVibration.ParallelCombination combo = CombinedVibration.startParallel();
for (int i = 0; i < vibratorIds.length; i++) {
// It's illegal to create a VibrationEffect with an amplitude of 0.
// Simply excluding that vibrator from our ParallelCombination will turn it off.
if (vibratorAmplitudes[i] != 0) {
combo.addVibrator(vibratorIds[i], VibrationEffect.createOneShot(60000, vibratorAmplitudes[i]));
}
}
vm.vibrate(combo.combine());
}
private void rumbleSingleVibrator(Vibrator vibrator, short lowFreqMotor, short highFreqMotor) {
// Since we can only use a single amplitude value, compute the desired amplitude
// by taking 80% of the big motor and 33% of the small motor, then capping to 255.
// NB: This value is now 0-255 as required by VibrationEffect.
@@ -1339,9 +1421,13 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
if (deviceContext.controllerNumber == controllerNumber) {
foundMatchingDevice = true;
if (deviceContext.vibrator != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && deviceContext.vibratorManager != null) {
vibrated = true;
rumbleVibrator(deviceContext.vibrator, lowFreqMotor, highFreqMotor);
rumbleDualVibrators(deviceContext.vibratorManager, lowFreqMotor, highFreqMotor);
}
else if (deviceContext.vibrator != null) {
vibrated = true;
rumbleSingleVibrator(deviceContext.vibrator, lowFreqMotor, highFreqMotor);
}
}
}
@@ -1361,12 +1447,12 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
// controls that triggered the rumble. Vibrate the device if
// the user has requested that behavior.
if (!foundMatchingDevice && prefConfig.onscreenController && !prefConfig.onlyL3R3 && prefConfig.vibrateOsc) {
rumbleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
rumbleSingleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
}
else if (foundMatchingDevice && !vibrated && prefConfig.vibrateFallbackToDevice) {
// We found a device to vibrate but it didn't have rumble support. The user
// has requested us to vibrate the device in this case.
rumbleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
rumbleSingleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
}
}
}
@@ -1803,6 +1889,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
class InputDeviceContext extends GenericControllerContext {
public String name;
public VibratorManager vibratorManager;
public Vibrator vibrator;
public int leftStickXAxis = -1;
@@ -1849,7 +1936,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
public void destroy() {
super.destroy();
if (vibrator != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && vibratorManager != null) {
vibratorManager.cancel();
}
else if (vibrator != null) {
vibrator.cancel();
}
}
@@ -41,8 +41,9 @@ public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptu
// SOURCE_MOUSE_RELATIVE is how SOURCE_MOUSE appears when our view has pointer capture.
// SOURCE_TOUCHPAD will have relative axes populated iff our view has pointer capture.
// See https://developer.android.com/reference/android/view/View#requestPointerCapture()
return event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE ||
(event.getSource() == InputDevice.SOURCE_TOUCHPAD && targetView.hasPointerCapture());
int eventSource = event.getSource();
return eventSource == InputDevice.SOURCE_MOUSE_RELATIVE ||
(eventSource == InputDevice.SOURCE_TOUCHPAD && targetView.hasPointerCapture());
}
@Override
@@ -127,7 +127,12 @@ public class UsbDriverService extends Service implements UsbDriverListener {
// just returning a false result or returning 0 enumerated devices,
// they throw an undocumented SecurityException from this call, crashing
// the whole app. :(
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), 0));
int intentFlags = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// This PendingIntent must be mutable to allow the framework to populate EXTRA_DEVICE and EXTRA_PERMISSION_GRANTED.
intentFlags |= PendingIntent.FLAG_MUTABLE;
}
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), intentFlags));
} catch (SecurityException e) {
Toast.makeText(this, this.getText(R.string.error_usb_prohibited), Toast.LENGTH_LONG).show();
}
@@ -1107,6 +1107,10 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
str += "Adaptive playback: "+renderer.adaptivePlayback+"\n";
str += "GL Renderer: "+renderer.glRenderer+"\n";
str += "Build fingerprint: "+Build.FINGERPRINT+"\n";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
str += "SOC: "+Build.SOC_MANUFACTURER+" - "+Build.SOC_MODEL+"\n";
str += "Performance class: "+Build.VERSION.MEDIA_PERFORMANCE_CLASS+"\n";
}
str += "Foreground: "+renderer.foreground+"\n";
str += "Consecutive crashes: "+renderer.consecutiveCrashCount+"\n";
str += "RFI active: "+renderer.refFrameInvalidationActive+"\n";
@@ -15,6 +15,9 @@ public class ConnectionContext {
// This is the version quad from the appversion tag of /serverinfo
public String serverAppVersion;
public String serverGfeVersion;
// This is the sessionUrl0 tag from /resume and /launch
public String rtspSessionUrl;
public int negotiatedWidth, negotiatedHeight;
public boolean negotiatedHdr;
@@ -275,7 +275,7 @@ public class NvConnection {
synchronized (MoonBridge.class) {
MoonBridge.setupBridge(videoDecoderRenderer, audioRenderer, connectionListener);
int ret = MoonBridge.startConnection(context.serverAddress,
context.serverAppVersion, context.serverGfeVersion,
context.serverAppVersion, context.serverGfeVersion, context.rtspSessionUrl,
context.negotiatedWidth, context.negotiatedHeight,
context.streamConfig.getRefreshRate(), context.streamConfig.getBitrate(),
context.streamConfig.getMaxPacketSize(),
@@ -367,6 +367,12 @@ public class NvConnection {
}
}
public void sendUtf8Text(final String text) {
if (!isMonkey) {
MoonBridge.sendUtf8Text(text);
}
}
public static String findExternalAddressForMdns(String stunHostname, int stunPort) {
return MoonBridge.findExternalAddressIP4(stunHostname, stunPort);
}
@@ -680,7 +680,13 @@ public class NvHTTP {
(context.streamConfig.getAttachedGamepadMask() != 0 ? "&gcmap=" + context.streamConfig.getAttachedGamepadMask() : ""),
false);
String gameSession = getXmlString(xmlStr, "gamesession");
return gameSession != null && !gameSession.equals("0");
if (gameSession != null && !gameSession.equals("0")) {
context.rtspSessionUrl = getXmlString(xmlStr, "sessionUrl0");
return true;
}
else {
return false;
}
}
public boolean resumeApp(ConnectionContext context) throws IOException, XmlPullParserException {
@@ -690,7 +696,13 @@ public class NvHTTP {
"&surroundAudioInfo=" + context.streamConfig.getAudioConfiguration().getSurroundAudioInfo(),
false);
String resume = getXmlString(xmlStr, "resume");
return Integer.parseInt(resume) != 0;
if (Integer.parseInt(resume) != 0) {
context.rtspSessionUrl = getXmlString(xmlStr, "sessionUrl0");
return true;
}
else {
return false;
}
}
public boolean quitApp() throws IOException, XmlPullParserException {
@@ -253,6 +253,7 @@ public class MoonBridge {
}
public static native int startConnection(String address, String appVersion, String gfeVersion,
String rtspSessionUrl,
int width, int height, int fps,
int bitrate, int packetSize, int streamingRemotely,
int audioConfiguration, boolean supportsHevc,
@@ -290,6 +291,8 @@ public class MoonBridge {
public static native void sendMouseHighResScroll(short scrollAmount);
public static native void sendUtf8Text(String text);
public static native String getStageName(int stage);
public static native String findExternalAddressIP4(String stunHostName, int stunPort);
@@ -88,11 +88,11 @@ public class AddComputerManually extends Activity {
// Couldn't find a matching interface
return true;
} catch (SocketException e) {
} catch (Exception e) {
// Catch all exceptions because some broken Android devices
// will throw an NPE from inside getNetworkInterfaces().
e.printStackTrace();
return false;
} catch (UnknownHostException e) {
return false;
}
}
@@ -44,7 +44,7 @@ public class StreamSettings extends Activity {
void reloadSettings() {
getFragmentManager().beginTransaction().replace(
R.id.stream_settings, new SettingsFragment()
).commit();
).commitAllowingStateLoss();
}
@Override
@@ -39,7 +39,7 @@ public class ShortcutHelper {
@TargetApi(Build.VERSION_CODES.N_MR1)
private void reapShortcutsForDynamicAdd() {
List<ShortcutInfo> dynamicShortcuts = sm.getDynamicShortcuts();
while (dynamicShortcuts.size() >= sm.getMaxShortcutCountPerActivity()) {
while (!dynamicShortcuts.isEmpty() && dynamicShortcuts.size() >= sm.getMaxShortcutCountPerActivity()) {
ShortcutInfo maxRankShortcut = dynamicShortcuts.get(0);
for (ShortcutInfo scut : dynamicShortcuts) {
if (maxRankShortcut.getRank() < scut.getRank()) {
@@ -118,8 +118,16 @@ public class ShortcutHelper {
// To avoid a random carousel of shortcuts popping in and out based on polling status,
// we only add shortcuts if it's not at the limit or the user made a conscious action
// to interact with this PC.
if (forceAdd || sm.getDynamicShortcuts().size() < sm.getMaxShortcutCountPerActivity()) {
if (forceAdd) {
// This should free an entry for us to add one below
reapShortcutsForDynamicAdd();
}
// We still need to check the maximum shortcut count even after reaping,
// because there's a possibility that it could be zero.
if (sm.getDynamicShortcuts().size() < sm.getMaxShortcutCountPerActivity()) {
// Add a shortcut if there is room
sm.addDynamicShortcuts(Collections.singletonList(sinfo));
}
}
@@ -364,6 +364,7 @@ static CONNECTION_LISTENER_CALLBACKS BridgeConnListenerCallbacks = {
JNIEXPORT jint JNICALL
Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass clazz,
jstring address, jstring appVersion, jstring gfeVersion,
jstring rtspSessionUrl,
jint width, jint height, jint fps,
jint bitrate, jint packetSize, jint streamingRemotely,
jint audioConfiguration, jboolean supportsHevc,
@@ -377,6 +378,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass c
.address = (*env)->GetStringUTFChars(env, address, 0),
.serverInfoAppVersion = (*env)->GetStringUTFChars(env, appVersion, 0),
.serverInfoGfeVersion = gfeVersion ? (*env)->GetStringUTFChars(env, gfeVersion, 0) : NULL,
.rtspSessionUrl = rtspSessionUrl ? (*env)->GetStringUTFChars(env, rtspSessionUrl, 0) : NULL,
};
STREAM_CONFIGURATION streamConfig = {
.width = width,
@@ -416,6 +418,9 @@ Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass c
if (gfeVersion != NULL) {
(*env)->ReleaseStringUTFChars(env, gfeVersion, serverInfo.serverInfoGfeVersion);
}
if (rtspSessionUrl != NULL) {
(*env)->ReleaseStringUTFChars(env, rtspSessionUrl, serverInfo.rtspSessionUrl);
}
return ret;
}
@@ -4,6 +4,7 @@
#include <android/log.h>
#include <arpa/inet.h>
#include <string.h>
JNIEXPORT void JNICALL
Java_com_limelight_nvstream_jni_MoonBridge_sendMouseMove(JNIEnv *env, jclass clazz, jshort deltaX, jshort deltaY) {
@@ -54,6 +55,13 @@ Java_com_limelight_nvstream_jni_MoonBridge_sendMouseHighResScroll(JNIEnv *env, j
LiSendHighResScrollEvent(scrollAmount);
}
JNIEXPORT void JNICALL
Java_com_limelight_nvstream_jni_MoonBridge_sendUtf8Text(JNIEnv *env, jclass clazz, jstring text) {
const char* utf8Text = (*env)->GetStringUTFChars(env, text, NULL);
LiSendUtf8TextEvent(utf8Text, strlen(utf8Text));
(*env)->ReleaseStringUTFChars(env, text, utf8Text);
}
JNIEXPORT void JNICALL
Java_com_limelight_nvstream_jni_MoonBridge_stopConnection(JNIEnv *env, jclass clazz) {
LiStopConnection();
+3
View File
@@ -217,4 +217,7 @@
\n
\nSi le problème persiste, essayez de réinstaller les pilotes de votre GPU ainsi que GeForce Experience.</string>
<string name="no_frame_received_error">Votre connexion ne fonctionne pas bien. Baissez votre paramètres de débit ou utilisez une connexion plus rapide.</string>
<string name="resolution_prefix_native_fullscreen">Plein-écran natif</string>
<string name="perf_overlay_netlatency">Latence réseau moyenne : %1$d ms (variance : %2$d ms)</string>
<string name="perf_overlay_streamdetails">Stream vidéo : %1$s %2$.2f FPS</string>
</resources>
+1
View File
@@ -206,4 +206,5 @@
<string name="scut_pc_not_found">Pc nem található</string>
<string name="scut_not_paired">PC nincs csatlakoztatva</string>
<string name="scut_deleted_pc">PC eltávolítva</string>
<string name="resolution_prefix_native_fullscreen">Natív teljes képernyős</string>
</resources>
+1
View File
@@ -219,4 +219,5 @@
<string name="title_checkbox_mouse_emulation">게임패드를 마우스처럼 사용하기</string>
<string name="perf_overlay_streamdetails">비디오 스트림 : %1$s %2$.2f FPS</string>
<string name="unable_to_pin_shortcut">현재 런처에서는 바로가기 생성이 불가능합니다.</string>
<string name="resolution_prefix_native_fullscreen">네이티브 (전체화면)</string>
</resources>
+37
View File
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="summary_reset_osc">Bütün ekran kontrollerini varsayılan boyutu ve pozisyonuna sıfırlar</string>
<string name="title_checkbox_touchscreen_trackpad">Dokunmatik ekranı trackpad olarak kullan</string>
<string name="category_input_settings">Girdi Ayarları</string>
<string name="summary_language_list">Moonlight için kullanılacak olan dil</string>
<string name="ip_hint">GeForce PC\'nin IP adresi</string>
<string name="title_details">Detaylar</string>
<string name="dialog_title_osc_opacity">Opaklığı değiştir</string>
<string name="conn_error_title">Bağlantı Hatası</string>
<string name="conn_starting">Başlatılıyor</string>
<string name="conn_error_msg">Başlatma başarısız</string>
<string name="summary_audio_config_list">Ev-sinema sistemleri için 5.1 yada 7.1 surround sesi etkinleştir</string>
<string name="title_checkbox_host_audio">Sesleri bilgisayarda çal</string>
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
<string name="error_pc_offline">Bilgisayar çevrimdışı</string>
<string name="unpair_success">Eşleştirme başarıyla kaldırıldı</string>
<string name="unpairing">Eşleştirme kaldırılıyor…</string>
<string name="pair_fail">Eşleştirme başarısız</string>
<string name="pair_incorrect_pin">Yanlış PIN</string>
<string name="pair_pairing_title">Eşleştiriliyor</string>
<string name="pair_pc_offline">Bilgisayar çevrimdışı</string>
<string name="pairing">Eşleştiriliyor…</string>
<string name="nettest_title_waiting">Ağ Bağlantısı Test Ediliyor</string>
<string name="pcview_menu_details">Detayları Görüntüle</string>
<string name="pcview_menu_test_network">Ağ Bağlantısını Test Et</string>
<string name="pcview_menu_delete_pc">PC\'yi sil</string>
<string name="pcview_menu_unpair_pc">Eşleştirmeyi kaldır</string>
<string name="pcview_menu_pair_pc">PC ile eşle</string>
<string name="pcview_menu_app_list">Bütün Uygulamaları Göster</string>
<string name="pcview_menu_header_unknown">Yenileniyor</string>
<string name="pcview_menu_header_offline">Çevrimdışı</string>
<string name="pcview_menu_header_online">Çevrimiçi</string>
<string name="scut_pc_not_found">PC bulunamadı</string>
<string name="scut_not_paired">PC eşleştirilmedi</string>
<string name="scut_deleted_pc">PC silindi</string>
</resources>
+149 -127
View File
@@ -1,198 +1,220 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- PC view menu entries -->
<string name="pcview_menu_app_list">Подивитися список ігор</string>
<string name="pcview_menu_pair_pc">Створити пару з ПК</string>
<string name="pcview_menu_app_list">Подивитися перелік додатків</string>
<string name="pcview_menu_pair_pc">Створити пару з пристроєм</string>
<string name="pcview_menu_unpair_pc">Розірвати пару</string>
<string name="pcview_menu_send_wol">Надіслати Wake-On-LAN запит</string>
<string name="pcview_menu_delete_pc">Видалити ПК</string>
<string name="pcview_menu_send_wol">Надіслати запит Wake-On-LAN</string>
<string name="pcview_menu_delete_pc">Видалити пристрій</string>
<!-- Pair messages -->
<string name="pairing">Створення пари…</string>
<string name="pair_pc_offline">Комп\'ютер вимкнений або знаходиться не в мережі</string>
<string name="pair_pc_ingame">Комп\'ютер в даний момент знаходиться в грі. Ви повинні закрити гру перед створенням пари.</string>
<string name="pair_pc_offline">Пристрій вимкнений або знаходиться поза мережею</string>
<string name="pair_pc_ingame">Пристрій на даний момент знаходиться у грі. Ви повинні закрити гру перед створенням пари.</string>
<string name="pair_pairing_title">Створення пари</string>
<string name="pair_pairing_msg">Будь ласка, введіть цей PIN на ПК:</string>
<string name="pair_incorrect_pin">Неправильний PIN</string>
<string name="pair_pairing_msg">Будь ласка, введіть цей код на пристрої:</string>
<string name="pair_incorrect_pin">Неправильний код</string>
<string name="pair_fail">Створення пари не вдалося</string>
<!-- WOL messages -->
<string name="wol_pc_online">Комп\'ютер в мережі</string>
<string name="wol_no_mac">Неможливо розбудити ПК бо GFE не відправили MAC адреса</string>
<string name="wol_waking_pc">Пробудження ПК</string>
<string name="wol_waking_msg">Пробудження ПК може зайняти кілька секунд.
Якщо цього не відбувається, упевніться що Wake-On-LAN налаштований правильно.
</string>
<string name="wol_pc_online">Пристрій у мережі</string>
<string name="wol_no_mac">Неможливо розбудити пристрій бо GFE не відправило MAC адреса</string>
<string name="wol_waking_pc">Пробудження пристрою</string>
<string name="wol_waking_msg">Пробудження пристрою може зайняти кілька секунд. Якщо цього не відбувається, упевніться що Wake-On-LAN налаштований правильно.</string>
<string name="wol_fail">Помилка при відправці Wake-On-LAN пакетів</string>
<!-- Unpair messages -->
<string name="unpairing">Розрив пари…</string>
<string name="unpair_success">Розрив пари закінчився успішно</string>
<string name="unpair_fail">Розрив пари не вдався</string>
<string name="unpair_error">Пристрій не було спарено</string>
<!-- Errors -->
<string name="error_pc_offline">Комп\'ютер вимкнений або знаходиться не в мережі</string>
<string name="error_manager_not_running">Сервіс ComputerManager не запущено. Будь ласка, зачекайте кілька секунд або запустіть програму.</string>
<string name="error_unknown_host">Неможливо знайти хост</string>
<string name="error_404">GFE повернув помилку HTTP 404. Переконайтеся що Ваш ПК використовує підтримуваний GPU.
Використання програм для віддаленого доступу також може викликати цю помилку. Спробуйте перезавантажити комп\'ютер або перевстановити GFE.
</string>
<string name="error_pc_offline">Пристрій вимкнено чи знаходиться поза мережею</string>
<string name="error_manager_not_running">Сервіс ComputerManager не запущено. Будь ласка, зачекайте кілька секунд або перезапустіть додаток.</string>
<string name="error_unknown_host">Неможливо знайти хоста</string>
<string name="error_404">GFE повернув помилку HTTP 404. Переконайтеся що ваш пристрій використовує підтримуваний GPU. Використання програм для віддаленого доступу також може викликати цю помилку. Спробуйте перезавантажити пристрій або перевстановити GFE.</string>
<!-- Start application messages -->
<string name="conn_establishing_title">Створення з\'єднання</string>
<string name="conn_establishing_msg">Підключення</string>
<string name="conn_metered">Увага: Відбувається вимір Вашого мережевого з\'єднання!</string>
<string name="conn_client_latency">Середня затримка декодування кадру:</string>
<string name="conn_client_latency_hw">затримка апаратного декодування:</string>
<string name="conn_hardware_latency">Середня затримка апаратного декодування:</string>
<string name="conn_metered">Увага: Ваше мережеве з\'єднання вимірюється оператором!</string>
<string name="conn_client_latency">Середня затримка розцифрування кадру:</string>
<string name="conn_client_latency_hw">затримка апаратного розцифрування:</string>
<string name="conn_hardware_latency">Середня затримка апаратного розцифрування:</string>
<string name="conn_starting">Запуск</string>
<string name="conn_error_title">Помилка з\'єднання</string>
<string name="conn_error_msg">Запуск не вдався</string>
<string name="conn_terminated_title">З\'єднання припинено</string>
<string name="conn_terminated_msg">Підключення було перервано</string>
<string name="conn_terminated_msg">З\'єднання перервано</string>
<!-- General strings -->
<string name="ip_hint">IP-адреса комп\'ютера з GeForce</string>
<string name="searching_pc">Пошук комп\'ютерів із запущеним GameStream…\n\n
Переконайтеся що GameStream увімкнений в налаштуваннях GeForce Experience в розділі SHIELD.</string>
<string name="ip_hint">IP-адреса пристрою з GeForce</string>
<string name="searching_pc">Пошук пристроїв із запущеним GameStream…
\n
\n Переконайтеся що GameStream увімкнений в налаштуваннях GeForce Experience в розділі SHIELD.</string>
<string name="yes">Так</string>
<string name="no">Ні</string>
<string name="lost_connection">З\'єднання втрачено з ПК</string>
<string name="lost_connection">З\'єднання з пристроєм втрачено</string>
<!-- AppList activity -->
<string name="applist_menu_resume">Відновити сесію</string>
<string name="applist_menu_quit">Вийти з сесії</string>
<string name="applist_menu_quit_and_start">Вийти з поточної гри і запустити</string>
<string name="applist_menu_cancel">Скасування</string>
<string name="applist_menu_cancel">Скасувати</string>
<string name="applist_menu_tv_channel">Додати на канал</string>
<string name="applist_refresh_title">Список додатків</string>
<string name="applist_refresh_title">Перелік додатків</string>
<string name="applist_refresh_msg">Оновлення додатків…</string>
<string name="applist_refresh_error_title">Помилка</string>
<string name="applist_refresh_error_msg">Помилка при отриманні списку додатків</string>
<string name="applist_quit_app">Вихід з</string>
<string name="applist_quit_success">Вихід відбувся успішно з</string>
<string name="applist_refresh_error_msg">Помилка отримання переліку додатків</string>
<string name="applist_quit_app">Виходимо з</string>
<string name="applist_quit_success">Успішний вихід з</string>
<string name="applist_quit_fail">Помилка при виході</string>
<string name="applist_quit_confirmation">Ви впевнені, що хочете вийти з запущеного додатку? Усі незбережені дані будуть втрачені.</string>
<!-- Add computer manually activity -->
<string name="title_add_pc">Додавання ПК вручну</string>
<string name="msg_add_pc">З\'єднання з ПК</string>
<string name="addpc_fail">Неможливо підключитися до вибраного комп\'ютера. Переконайтеся, що необхідні порти дозволені в налаштуваннях брандмауера.</string>
<string name="addpc_success">Комп\'ютер доданий успішно</string>
<string name="addpc_unknown_host">Неможливо знайти ПК за вказаною адресою. Переконайтеся, що Ви не зробили помилок під час його написання.</string>
<string name="title_add_pc">Додати пристрій вручну</string>
<string name="msg_add_pc">З\'єднання з пристроєм</string>
<string name="addpc_fail">Неможливо під\'єднатися до вибраного пристрою. Переконайтеся, що необхідні порти дозволені в налаштуваннях брандмауера.</string>
<string name="addpc_success">Пристрій додано успішно</string>
<string name="addpc_unknown_host">Неможливо знайти пристрій за вказаною адресою. Переконайтеся, що ви не зробили помилок під час його написання.</string>
<string name="addpc_enter_ip">Ви повинні ввести IP адресу</string>
<!-- Preferences -->
<string name="category_basic_settings">Загальні Налаштування</string>
<string name="title_resolution_list">Виберіть розширення і частоту кадрів</string>
<string name="summary_resolution_list">Вибір занадто високого значеня для свого пристрою може викликати гальма або вильоти</string>
<string name="title_seekbar_bitrate">Виберіть бітрейт відео</string>
<string name="summary_seekbar_bitrate">Низький бітрейт зменшить зависання. Збільшення бітрейта поліпшить якість зображення.</string>
<string name="title_checkbox_stretch_video">Розтягувати відео на весь екран</string>
<string name="title_checkbox_disable_warnings">Відключити повідомлення з попередженнями</string>
<string name="summary_checkbox_disable_warnings">Вимкнути екранні попередження про з\'єднання під час трансляції</string>
<string name="category_audio_settings">Аудіо Налаштування</string>
<string name="title_audio_config_list">Конфігурація об\'ємного звуку</string>
<string name="category_basic_settings">Загальні налаштування</string>
<string name="title_resolution_list">Роздільна здатність</string>
<string name="summary_resolution_list">Вибір надто високого значення для свого пристрою може викликати сповільнення на нешвидких мережах, або вильоти на менш потужних пристроях.</string>
<string name="title_seekbar_bitrate">Швидкість потоку відео</string>
<string name="summary_seekbar_bitrate">Збільшіть для якіснішої картинки. Зменшіть задля кращої продуктивності на повільних мережах.</string>
<string name="title_checkbox_stretch_video">Розтягнути відео на весь екран</string>
<string name="title_checkbox_disable_warnings">Вимкнути попередження</string>
<string name="summary_checkbox_disable_warnings">Вимкнути мережні попередження під час трансляції</string>
<string name="category_audio_settings">Налаштування авдіо</string>
<string name="title_audio_config_list">Конфігурація об\'ємного звуку</string>
<string name="summary_audio_config_list">Увімкнути 5.1 або 7.1 об\'ємний звук для систем домашнього кінотеатру</string>
<string name="title_checkbox_multi_controller">Підтримка декількох контролерів</string>
<string name="summary_checkbox_multi_controller">Коли вимкнено, всі контролери визначаються як один</string>
<string name="title_seekbar_deadzone">Регулювати мертву зону аналогового стіку</string>
<string name="summary_checkbox_multi_controller">Коли вимкнено, усі контролери працюють як один</string>
<string name="title_seekbar_deadzone">Змінити мертву зону аналогового соску</string>
<string name="suffix_seekbar_deadzone">%</string>
<string name="title_checkbox_xb1_driver">Драйвер контролерів Xbox 360/One</string>
<string name="summary_checkbox_xb1_driver">Увімкнути вбудований USB драйвер для пристроїв без власної підтримки контролерів Xbox</string>
<string name="title_checkbox_xb1_driver">Драйвер для контролерів Xbox 360/One</string>
<string name="summary_checkbox_xb1_driver">Вмикає вбудований USB драйвер для пристроїв без власної підтримки контролерів Xbox</string>
<string name="category_ui_settings">Налаштування інтерфейсу</string>
<string name="title_language_list">Мова</string>
<string name="summary_language_list">Мова, яка буде використовуватися в Moonlight</string>
<string name="title_checkbox_small_icon_mode">Використовувати маленькі іконки</string>
<string name="summary_checkbox_small_icon_mode">Використовувати маленькі іконки в сітці для відображення більшої кількості елементів на екрані</string>
<string name="category_host_settings">Налаштування Хоста</string>
<string name="summary_checkbox_small_icon_mode">Використовувати маленькі іконки в сітці додатків, для відображення більшої кількості елементів на екрані</string>
<string name="category_host_settings">Налаштування хоста</string>
<string name="title_checkbox_enable_sops">Оптимізувати ігрові налаштування</string>
<string name="summary_checkbox_enable_sops">Дозволити GFE змінювати налаштування ігор для оптимальної трансляції</string>
<string name="title_checkbox_host_audio">Програвати звук на ПК</string>
<string name="summary_checkbox_host_audio">Програвати звук на комп\'ютері і поточному пристрої</string>
<string name="category_advanced_settings">Розширені Налаштування</string>
<string name="title_checkbox_host_audio">Програвати звук на пристрої хоста</string>
<string name="summary_checkbox_host_audio">Програвати звук на пристроях хоста та клієнта</string>
<string name="category_advanced_settings">Розширені налаштування</string>
<string name="title_video_format">Змінити налаштування HEVC</string>
<string name="summary_video_format">HEVC знижує вимоги до пропускної здатності, але вимагає дуже нового пристрою</string>
<string name="category_on_screen_controls_settings">Налаштування дисплею з кнопками</string>
<string name="title_checkbox_show_onscreen_controls">Показувати екранні кнопки</string>
<string name="summary_checkbox_show_onscreen_controls">Відображати оверлей віртуального контролера на сенсорному екрані</string>
<string name="title_only_l3r3">Показувати тільки L3 і R3</string>
<string name="summary_only_l3r3">Приховувати всі екранні кнопки крім L3 і R3</string>
<string name="scut_deleted_pc">ПК видалений</string>
<string name="scut_not_paired">ПК не сполучений</string>
<string name="help_loading_title">Перегляд Допомоги</string>
<string name="summary_video_format">HEVC знижує вимоги мережі, даючи можливість транслювати на повільних мережах але, вимагає нового пристрою з підтримкою цієї системи</string>
<string name="category_on_screen_controls_settings">Налаштування екранних ґудзиків</string>
<string name="title_checkbox_show_onscreen_controls">Показувати екранні ґудзики</string>
<string name="summary_checkbox_show_onscreen_controls">Відображати віртуальні ґудзики контролера на екрані</string>
<string name="title_only_l3r3">Показувати тільки L3 та R3</string>
<string name="summary_only_l3r3">Приховувати всі віртуальні ґудзики окрім L3 та R3</string>
<string name="scut_deleted_pc">Пристрій видалено</string>
<string name="scut_not_paired">Пристрій не сполучений</string>
<string name="help_loading_title">Перегляд допомоги</string>
<string name="help_loading_msg">Завантаження сторінки допомоги…</string>
<string name="pair_already_in_progress">Сполучення вже в процесі</string>
<string name="help">Допомога</string>
<string name="applist_connect_msg">Підключення до ПК</string>
<string name="title_decoding_error">Збій відео декодера</string>
<string name="message_decoding_error">Стався збій Moonlight через проблеми з відео декодером даного пристрою. Спробуйте змінити налаштування трансляції якщо збої будуть продовжуватися.</string>
<string name="title_decoding_reset">Відео Налаштування Скинуті</string>
<string name="message_decoding_reset">Відео декодер Вашого пристрою давав збої з вибраними налаштуваннями. Налаштування трансляції були скинуті до значень за замовчуванням.</string>
<string name="applist_connect_msg">Підключення до пристрою</string>
<string name="title_decoding_error">Збій відео розцифрувача</string>
<string name="message_decoding_error">Стався збій Moonlight через несумітність з відео розцифрувачем даного пристрою. Спробуйте змінити налаштування трансляції якщо збої продовжуватимуться.</string>
<string name="title_decoding_reset">Налаштування відео скинуті</string>
<string name="message_decoding_reset">Відео розцифрувач вашого пристрою продовжує давати збої з поточними налаштуваннями трансляції. Налаштування трансляції були скинуті до значень за замовчуванням.</string>
<string name="error_usb_prohibited">USB доступ заборонений адміністратором пристрою. Перевірте налаштування Knox або MDM.</string>
<string name="addpc_wrong_sitelocal">Адреса вказана невірно. Ви повинні ввести публічну IP-адресу Вашого роутера для передачі через інтернет.</string>
<string name="title_checkbox_enable_pip">Увімкнути перегляд у режимі \"Картинка в картинці\"</string>
<string name="addpc_wrong_sitelocal">Вказана адреса неправильна. Ви повинні ввести публічну IP-адресу вашого мережника (роутера) для передачі через інтернет.</string>
<string name="title_checkbox_enable_pip">Увімкнути режим перегляду \"Картинка в картинці\"</string>
<string name="summary_checkbox_enable_pip">Дозволяє переглядати трансляцію (але не керувати нею) під час роботи в інших додатках</string>
<string name="title_checkbox_usb_bind_all">Відхилити підтримку контролерів Android</string>
<string name="summary_checkbox_usb_bind_all">Змушує USB драйвер Moonlight взяти на себе роботу з усіма підтримуваними Xbox геймпадами</string>
<string name="title_checkbox_mouse_emulation">Емуляція миші на геймпаді</string>
<string name="summary_checkbox_mouse_emulation">Довге натиснення кнопки Start перемкне геймпад в режим миші</string>
<string name="title_reset_osc">Скинути схему розташування екранних кнопок</string>
<string name="title_checkbox_usb_bind_all">Вимкнути рідну підтримку Xbox контролерів від Андроїда</string>
<string name="summary_checkbox_usb_bind_all">Використовувати USB драйвер Moonlight для усіх підтриманих контролерів, навіть якщо існує рідна підтримка</string>
<string name="title_checkbox_mouse_emulation">Емуляція миші через контролер</string>
<string name="summary_checkbox_mouse_emulation">Довге натиснення ґудзика Start, перемкне контролер в режим миші</string>
<string name="title_reset_osc">Скинути власне розташування ґудзиків на екрані</string>
<string name="summary_reset_osc">Повертає всі екранні елементи керування до їх розташуванням за замовчуванням</string>
<string name="dialog_title_reset_osc">Скинути Схему</string>
<string name="dialog_text_reset_osc">Ви впевнені що хочете видалити збережену схему розташування кнопок?</string>
<string name="dialog_title_reset_osc">Скинути розташування</string>
<string name="dialog_text_reset_osc">Ви впевнені що хочете видалити збережене розташування ґудзиків\?</string>
<string name="toast_reset_osc_success">Екранні елементи керування повернуті до положень за замовчуванням</string>
<string name="title_disable_frame_drop">Ніколи не пропускати кадри</string>
<string name="summary_disable_frame_drop">Може зменшити мікрозависання на деяких пристроях, але також збільшити затримку</string>
<string name="summary_disable_frame_drop">Може зменшити мікрозависання на деяких пристроях але, також збільшити затримку</string>
<string name="title_enable_hdr">Увімкнути HDR (Експериментально)</string>
<string name="summary_enable_hdr">Транслювати в HDR якщо гра і GPU комп\'ютера підтримують це. HDR вимагає відеокарти GTX 1000 серії або більш нової.</string>
<string name="summary_enable_hdr">Транслювати в HDR якщо гра та відео карта на пристрої хоста підтримують це. HDR вимагає відеокарти серії GTX 1000 або новіше.</string>
<string name="title_checkbox_vibrate_osc">Увімкнути вібрацію</string>
<string name="title_fps_list">Частота кадрів</string>
<string name="applist_menu_details">Деталі</string>
<string name="applist_menu_scut">Створити ярлик</string>
<string name="category_input_settings">Налаштування введення</string>
<string name="title_checkbox_touchscreen_trackpad">Використовувати сенсорний екран як трекпад</string>
<string name="summary_checkbox_touchscreen_trackpad">Якщо увімкнено, сенсорний екран працює як трекпад. Якщо його вимкнено, сенсорний екран безпосередньо керує курсором миші.</string>
<string name="delete_pc_msg">Ви впевнені що хочете видалити цей ПК?</string>
<string name="title_checkbox_touchscreen_trackpad">Використовувати сенсорний екран як пальцевід</string>
<string name="summary_checkbox_touchscreen_trackpad">Якщо увімкнено, сенсорний екран працює як ноутбуковий пальцевід. Якщо вимкнено, безпосередньо керує вказівником миші.</string>
<string name="delete_pc_msg">Ви впевнені що хочете видалити цей пристрій\?</string>
<string name="pcview_menu_details">Деталі</string>
<string name="poor_connection_msg">Слабке з\'єднання з ПК</string>
<string name="poor_connection_msg">Слабке з\'єднання з пристроєм</string>
<string name="title_details">Деталі</string>
<string name="title_enable_perf_overlay">Увімкнути відображення статистики</string>
<string name="title_unlock_fps">Розблокувати всі можливі частоти оновлення</string>
<string name="title_unlock_fps">Розблокувати всі можливі частоти кадрів</string>
<string name="applist_details_id">ID додатку:</string>
<string name="title_checkbox_vibrate_fallback">Емуляція вібровіддачі</string>
<string name="summary_checkbox_vibrate_osc">Вібрація пристрою для емуляції вібровіддачі при екранному управлінні</string>
<string name="summary_checkbox_vibrate_fallback">Вібрувати пристрій для емуляції вібровіддачі для геймпадов без підтримки вібрації</string>
<string name="summary_checkbox_mouse_nav_buttons">Включення цієї опції може привести до неправильної роботи правої кнопки миші на деяких пристроях</string>
<string name="title_checkbox_flip_face_buttons">Відкідні кнопки</string>
<string name="summary_checkbox_flip_face_buttons">Перемикає лицьові кнопки A/B і X/Y для геймпадів та екранних елементів керування</string>
<string name="scut_pc_not_found">ПК не знайдено</string>
<string name="unable_to_pin_shortcut">Поточний лаунчер не дозволяє створювати закріплені ярлики</string>
<string name="title_checkbox_mouse_nav_buttons">Увімкнути кнопки вперед і назад для миші</string>
<string name="slow_connection_msg">Повільне підключення до ПК\nЗменшити бітрейт</string>
<string name="summary_unlock_fps">Трансляція зі швидкістю 90 або 120 кадрів в секунду може зменшити затримку на пристроях високого класу, але може викликати затримки або збій на пристроях без підтримки цього функціоналу</string>
<string name="summary_enable_perf_overlay">Відображення накладення на екрані з інформацією про продуктивність під час трансляції в режимі реального часу</string>
<string name="perf_overlay_decoder">Декодер: %1$s</string>
<string name="summary_checkbox_vibrate_fallback">Вібрує пристрій для емуляції вібровіддачі, якщо під\'єднаний контролер не підтримує її</string>
<string name="summary_checkbox_mouse_nav_buttons">Включення цієї опції може привести до неправильної роботи правої клавіші миші на деяких пристроях</string>
<string name="title_checkbox_flip_face_buttons">Перевернути ґудзики</string>
<string name="summary_checkbox_flip_face_buttons">Перемикає ґудзики A/B та X/Y для контролерів та екранних елементів керування</string>
<string name="scut_pc_not_found">Пристрій не знайдено</string>
<string name="unable_to_pin_shortcut">Поточний запускач не дозволяє створювати закріплені ярлики.</string>
<string name="title_checkbox_mouse_nav_buttons">Увімкнути ґудзики «вперед» та «назад» для миші</string>
<string name="slow_connection_msg">Повільне підключення
\nЗменшіть швидкість потоку</string>
<string name="summary_unlock_fps">Трансляція зі швидкістю 90 або 120 кадрів на секунду може зменшити затримку на швидких пристроях але, може викликати затримки або збої на слабших</string>
<string name="summary_enable_perf_overlay">Відображає статистику продуктивності під час трансляції, в режимі реального часу</string>
<string name="perf_overlay_decoder">Розцифрувач: %1$s</string>
<string name="perf_overlay_incomingfps">Вхідна частота кадрів з мережі: %1$.2f FPS</string>
<string name="perf_overlay_renderingfps">Частота кадрів під час рендерінгу: %1$.2f FPS</string>
<string name="perf_overlay_netdrops">Відкинутих кадрів вашою мережею: %1$.2f%%</string>
<string name="perf_overlay_dectime">Середній час декодування: %1$.2f ms</string>
<string name="summary_fps_list">Збільшення для більш плавного відео потоку. Зменшіть для кращої продуктивності на більш слабких пристроях.</string>
<string name="scut_invalid_uuid">Зазначений ПК недійсний</string>
<string name="scut_invalid_app_id">Зазначений додаток недійсне</string>
<string name="title_osc_opacity">Змінити непрозорість екранних елементів керування</string>
<string name="perf_overlay_renderingfps">Частота кадрів при відтворенні: %1$.2f FPS</string>
<string name="perf_overlay_netdrops">Кадри втрачені вашою мережею: %1$.2f%%</string>
<string name="perf_overlay_dectime">Середній час розцифрування: %1$.2f мс</string>
<string name="summary_fps_list">Збільшіть для плавнішого відео потоку. Зменшіть для кращої продуктивності на повільних пристроях.</string>
<string name="scut_invalid_uuid">Зазначений пристрій недійсний</string>
<string name="scut_invalid_app_id">Зазначений додаток недійсний</string>
<string name="title_osc_opacity">Змінити прозорість екранних елементів керування</string>
<string name="summary_osc_opacity">Зробити екранні елементи керування більш/менш прозорими</string>
<string name="dialog_title_osc_opacity">Зміна непрозорості</string>
<string name="dialog_title_osc_opacity">Зміна прозорості</string>
<string name="suffix_osc_opacity">%</string>
<string name="title_enable_post_stream_toast">Показувати затримку після трансляції</string>
<string name="summary_enable_post_stream_toast">Вивести інформаційне повідомлення про затримку після закінчення потоку</string>
</resources>
<string name="title_enable_post_stream_toast">Статистика затримки після трансляції</string>
<string name="summary_enable_post_stream_toast">Показувати статистику затримки після закінчення трансляції</string>
<string name="early_termination_error">Щось пішло не так на пристрої хоста при початку трансляції.
\n
\nВпевніться що у вас не відкриті додатки з DRM змістом на пристрої хоста. Ви також можете спробувати перезапустити його.
\n
\nЯкщо проблема не виправиться, спробуйте перевстановити драйвера для вашої відео карти та, GeForce Experience якщо встановлено.</string>
<string name="nettest_text_success">Схоже що ваша мережа не блокує Moonlight. Якщо у вас й надалі проблеми з підключенням, перевірте налаштування брандмауера.
\n
\nЯкщо ви намагаєтеся транслювати через Інтернет, встановіть на своєму пристрої Moonlight Internet Hosting Tool, та запустіть випробування мережі щоб перевірити ваше з\'єднання до Інтернету.</string>
<string name="resolution_prefix_native_fullscreen">Рідний повноекранний</string>
<string name="resolution_prefix_native">Рідна</string>
<string name="suffix_seekbar_bitrate_mbps">Мб/с</string>
<string name="text_native_res_dialog">Режими рідної роздільної здатності не підтримуються офіційно через GeForce Experience, і тому не змінять роздільну здатність хоста на ту що в клієнта автоматично. Вам потрібно буде виставити її самостійно у грі.
\n
\nЯкщо ви вирішили створити власну роздільну здатність у панелі керування NVIDIA переконайтеся, що ви прочитали та зрозуміли попередження NVIDIA щодо можливих пошкоджень монітора, нестабільності пристрою та інших потенційних проблем.
\n
\nМи не несемо відповідальності за будь-які проблеми, спричинені створенням власних роздільних здатностей на ваших пристроях.
\n
\nЗрештою, пристрої клієнта чи хоста можуть не підтримувати трансляції рідною роздільною здатністю. Якщо це не працює на вашому пристрої, вам на жаль просто не пощастило.</string>
<string name="title_native_res_dialog">Застереження про рідну роздільну здатність</string>
<string name="applist_menu_hide_app">Сховати додаток</string>
<string name="perf_overlay_netlatency">Середня затримка мережі: %1$d мс (розбіжність %2$d мс)</string>
<string name="perf_overlay_streamdetails">Відео трансл: %1$s %2$.2f FPS</string>
<string name="check_ports_msg">Перевірте правила брандмауера та переадресації для наступних портів:</string>
<string name="no_frame_received_error">Здається, ваше мережеве з\'єднання човпає. Спробуйте зменшити швидкість потоку (бітрейт) чи переключіть пристрій на швидшу мережу.</string>
<string name="no_video_received_error">Не отримано відео від хоста.</string>
<string name="video_decoder_init_failed">Не вдалося запустити відео розцифрувач. Ваш пристрій може не підтримувати розмір екрану чи частоту кадрів.</string>
<string name="nettest_text_blocked">Поточне мережеве з’єднання вашого пристрою блокує Moonlight. Трансляції через Інтернет можуть не працювати на цієї мережі.</string>
<string name="nettest_text_failure">Поточне мережеве з’єднання вашого пристрою блокує Moonlight. Трансляції через Інтернет можуть не працювати на цієї мережі.
\n
\nНаступні мережеві порти були заблоковані:
\n</string>
<string name="nettest_text_inconclusive">Не вдалося перевірити мережу, тому що усі мережо-перевірочні сервери Moonlight недосяжні. Перевірте ваше з\'єднання з інтернетом та спробуйте знову.</string>
<string name="nettest_title_done">Перевірка мережі завершена</string>
<string name="nettest_text_waiting">Moonlight перевіряє мережеве з\'єднання щоб визначити чи заблокований NVIDIA GameStream.
\n
\nЦе займе кілька секунд…</string>
<string name="nettest_title_waiting">Перевіряємо з\'єднання</string>
<string name="pcview_menu_test_network">Перевірити мережеве з\'єднання</string>
<string name="pcview_menu_header_unknown">Оновлення</string>
<string name="pcview_menu_header_offline">Поза мережею</string>
<string name="pcview_menu_header_online">В мережі</string>
</resources>
+1
View File
@@ -206,4 +206,5 @@
<string name="scut_deleted_pc">PC đã bị xoá</string>
<string name="perf_overlay_netlatency">Độ trễ mạng trung bình: %1$d ms (sai số: %2$d ms)</string>
<string name="perf_overlay_streamdetails">Tốc độ khung hình: %1$s %2$.2f FPS</string>
<string name="resolution_prefix_native_fullscreen">Toàn màn hình theo hệ thống</string>
</resources>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<!-- Don't sync preferences because it often contains device-specific data -->
<cloud-backup disableIfNoEncryptionCapabilities="true">
<exclude domain="sharedpref" path="."/>
</cloud-backup>
<device-transfer>
<exclude domain="sharedpref" path="."/>
</device-transfer>
</data-extraction-rules>
+2 -1
View File
@@ -8,11 +8,12 @@ before_build:
- 'git submodule update --init --recursive'
- 'mklink /D C:\android-sdk "C:\Program Files (x86)\Android\android-sdk"'
- 'set ANDROID_HOME=C:\android-sdk'
- 'set JAVA_HOME=C:\Program Files\Java\jdk11'
build_script:
- gradlew.bat build connectedCheck
after_build:
- 'appveyor PushArtifact app\build\reports\lint-results.html'
- 'appveyor PushArtifact app\build\reports\lint-results-nonRootDebug.html'
deploy: off
+1 -1
View File
@@ -5,7 +5,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.1'
classpath 'com.android.tools.build:gradle:7.0.0'
}
}
@@ -0,0 +1,4 @@
- Improved controller rumble support with independent rumble motor control using the new Android 12 APIs
- Fixed touchpad input on DualShock controllers (if supported by the Android device itself)
- Fixed certain controllers disconnecting from the host when Moonlight enters the background
- Updated community-contributed translations from Weblate
@@ -0,0 +1,2 @@
- Fixed crash on Android 12 when using USB driver
- Fixed several other rare user-reported crashes
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip