maint: hotreload updated to 1.13.7
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
@@ -52,4 +51,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -86,6 +85,11 @@ namespace SingularityGroup.HotReload {
|
||||
/// </summary>
|
||||
public string buildMachineRequestOrigin;
|
||||
|
||||
/// <summary>
|
||||
/// Used to define which language the package is translated to
|
||||
/// </summary>
|
||||
public string locale;
|
||||
|
||||
[JsonIgnore]
|
||||
public HashSet<string> DefineSymbolsAsHashSet {
|
||||
get {
|
||||
@@ -168,4 +172,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
@@ -38,4 +37,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -10,6 +8,7 @@ using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SingularityGroup.HotReload.DTO;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
using JetBrains.Annotations;
|
||||
using SingularityGroup.HotReload.Burst;
|
||||
using SingularityGroup.HotReload.HarmonyLib;
|
||||
@@ -33,16 +32,17 @@ namespace SingularityGroup.HotReload {
|
||||
public List<SField> addedFields = new List<SField>();
|
||||
public readonly List<SMethod> patchedSMethods = new List<SMethod>();
|
||||
public bool inspectorModified;
|
||||
public bool inspectorFieldAdded;
|
||||
public readonly List<Tuple<SMethod, string>> patchFailures = new List<Tuple<SMethod, string>>();
|
||||
public readonly List<string> patchExceptions = new List<string>();
|
||||
}
|
||||
|
||||
class FieldHandler {
|
||||
public readonly Action<Type, FieldInfo> storeField;
|
||||
public readonly Func<Type, FieldInfo, bool> storeField;
|
||||
public readonly Action<Type, FieldInfo, FieldInfo> registerInspectorFieldAttributes;
|
||||
public readonly Func<Type, string, bool> hideField;
|
||||
|
||||
public FieldHandler(Action<Type, FieldInfo> storeField, Func<Type, string, bool> hideField, Action<Type, FieldInfo, FieldInfo> registerInspectorFieldAttributes) {
|
||||
public FieldHandler(Func<Type, FieldInfo, bool> storeField, Func<Type, string, bool> hideField, Action<Type, FieldInfo, FieldInfo> registerInspectorFieldAttributes) {
|
||||
this.storeField = storeField;
|
||||
this.hideField = hideField;
|
||||
this.registerInspectorFieldAttributes = registerInspectorFieldAttributes;
|
||||
@@ -79,7 +79,7 @@ namespace SingularityGroup.HotReload {
|
||||
try {
|
||||
LoadPatches(PersistencePath);
|
||||
} catch(Exception ex) {
|
||||
Log.Error("Encountered exception when loading patches from disk:\n{0}", ex);
|
||||
Log.Error($"{Localization.Translations.Logging.LoadingPatchesFromDiskError}\n{ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,12 +91,12 @@ namespace SingularityGroup.HotReload {
|
||||
|
||||
|
||||
void LoadPatches(string filePath) {
|
||||
PlayerLog("Loading patches from file {0}", filePath);
|
||||
PlayerLog(Localization.Translations.Logging.LoadingPatchesFromFile, filePath);
|
||||
var file = new FileInfo(filePath);
|
||||
if(file.Exists) {
|
||||
var bytes = File.ReadAllText(filePath);
|
||||
var patches = JsonConvert.DeserializeObject<List<MethodPatchResponse>>(bytes);
|
||||
PlayerLog("Loaded {0} patches from disk", patches.Count.ToString());
|
||||
PlayerLog(Localization.Translations.Logging.LoadedPatchesFromDisk, patches.Count.ToString());
|
||||
foreach (var patch in patches) {
|
||||
RegisterPatches(patch, persist: false);
|
||||
}
|
||||
@@ -114,13 +114,13 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
|
||||
internal RegisterPatchesResult RegisterPatches(MethodPatchResponse patches, bool persist) {
|
||||
PlayerLog("Register patches.\nWarnings: {0} \nMethods:\n{1}", string.Join("\n", patches.failures), string.Join("\n", patches.patches.SelectMany(p => p.modifiedMethods).Select(m => m.displayName)));
|
||||
PlayerLog(Localization.Translations.Logging.RegisterPatches, string.Join("\n", patches.failures), string.Join("\n", patches.patches.SelectMany(p => p.modifiedMethods).Select(m => m.displayName)));
|
||||
pendingPatches.Add(patches);
|
||||
return ApplyPatches(persist);
|
||||
}
|
||||
|
||||
RegisterPatchesResult ApplyPatches(bool persist) {
|
||||
PlayerLog("ApplyPatches. {0} patches pending.", pendingPatches.Count);
|
||||
PlayerLog(Localization.Translations.Logging.ApplyPatchesPending, pendingPatches.Count);
|
||||
EnsureSymbolResolver();
|
||||
|
||||
var result = new RegisterPatchesResult();
|
||||
@@ -161,7 +161,7 @@ namespace SingularityGroup.HotReload {
|
||||
Dispatch.OnHotReload(result.patchedMethods).Forget();
|
||||
}
|
||||
} catch(Exception ex) {
|
||||
Log.Warning("Exception occured when handling method patch. Exception:\n{0}", ex);
|
||||
Log.Warning($"{Localization.Translations.Logging.ExceptionHandlingMethodPatch}\n{ex}");
|
||||
} finally {
|
||||
pendingPatches.Clear();
|
||||
}
|
||||
@@ -185,7 +185,7 @@ namespace SingularityGroup.HotReload {
|
||||
if (didLog || !UnityEventHelper.UnityMethodsAdded()) {
|
||||
return;
|
||||
}
|
||||
Log.Warning("A new Scene was loaded while new unity event methods were added at runtime. MonoBehaviours in the Scene will not trigger these new events.");
|
||||
Log.Warning(Localization.Translations.Logging.SceneLoadedWithNewUnityEventMethods);
|
||||
didLog = true;
|
||||
};
|
||||
}
|
||||
@@ -200,7 +200,7 @@ namespace SingularityGroup.HotReload {
|
||||
try {
|
||||
UnityEventHelper.EnsureUnityEventMethod(newMethod);
|
||||
} catch(Exception ex) {
|
||||
Log.Warning("Encountered exception in EnsureUnityEventMethod: {0} {1}", ex.GetType().Name, ex.Message);
|
||||
Log.Warning(Localization.Translations.Logging.ExceptionEnsureUnityEventMethod, ex.GetType().Name, ex.Message);
|
||||
}
|
||||
MethodUtils.DisableVisibilityChecks(newMethod);
|
||||
if (!patch.patchMethods.Any(m => m.metadataToken == sMethod.metadataToken)) {
|
||||
@@ -231,7 +231,7 @@ namespace SingularityGroup.HotReload {
|
||||
{ StatKey.PatchId, patch.patchId },
|
||||
{ StatKey.Detailed_Exception, ex.ToString() },
|
||||
}).Forget();
|
||||
result.patchExceptions.Add($"Edit requires full recompile to apply: Encountered exception when applying a patch.\nCommon causes: editing code that failed to patch previously, an unsupported change, or a real bug in Hot Reload.\nIf you think this is a bug, please report the issue on Discord and include a code-snippet before/after.\nException: {ex}");
|
||||
result.patchExceptions.Add($"{Localization.Translations.Logging.ExceptionApplyingPatch}\nException: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,7 +247,7 @@ namespace SingularityGroup.HotReload {
|
||||
} catch (SymbolResolvingFailedException) {
|
||||
// ignore, not a unity event method if can't resolve
|
||||
} catch(Exception ex) {
|
||||
Log.Warning("Encountered exception in RemoveUnityEventMethod: {0} {1}", ex.GetType().Name, ex.Message);
|
||||
Log.Warning(Localization.Translations.Logging.ExceptionRemoveUnityEventMethod, ex.GetType().Name, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -261,7 +261,7 @@ namespace SingularityGroup.HotReload {
|
||||
var declaringType = SymbolResolver.Resolve(sField.declaringType);
|
||||
var method = SymbolResolver.Resolve(sMethod);
|
||||
if (!(method is MethodInfo initializer)) {
|
||||
Log.Warning($"Failed registering initializer for field {sField.fieldName} in {sField.declaringType.typeName}. Field value might not be initialized correctly. Invalid method.");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.FailedRegisteringInitializerInvalidMethod, sField.fieldName, sField.declaringType.typeName));
|
||||
continue;
|
||||
}
|
||||
// We infer if the field is static by the number of parameters the method has
|
||||
@@ -276,7 +276,7 @@ namespace SingularityGroup.HotReload {
|
||||
{ StatKey.PatchId, resp.id },
|
||||
{ StatKey.Detailed_Exception, e.ToString() },
|
||||
}).Forget();
|
||||
Log.Warning($"Failed registering initializer for field {sField.fieldName} in {sField.declaringType.typeName}. Field value might not be initialized correctly. Exception: {e.Message}");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.FailedRegisteringInitializerException, sField.fieldName, sField.declaringType.typeName, e.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -292,7 +292,7 @@ namespace SingularityGroup.HotReload {
|
||||
{ StatKey.PatchId, resp.id },
|
||||
{ StatKey.Detailed_Exception, e.ToString() },
|
||||
}).Forget();
|
||||
Log.Warning($"Failed registering new field definitions for field {sField.fieldName} in {sField.declaringType.typeName}. Exception: {e.Message}");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.FailedRegisteringNewFieldDefinitions, sField.fieldName, sField.declaringType.typeName, e.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,7 +310,7 @@ namespace SingularityGroup.HotReload {
|
||||
{ StatKey.PatchId, resp.id },
|
||||
{ StatKey.Detailed_Exception, e.ToString() },
|
||||
}).Forget();
|
||||
Log.Warning($"Failed removing initializer for field {sField.fieldName} in {sField.declaringType.typeName}. Field value might not be initialized correctly. Exception: {e.Message}");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.FailedRemovingInitializer, sField.fieldName, sField.declaringType.typeName, e.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -333,7 +333,7 @@ namespace SingularityGroup.HotReload {
|
||||
{ StatKey.PatchId, resp.id },
|
||||
{ StatKey.Detailed_Exception, e.ToString() },
|
||||
}).Forget();
|
||||
Log.Warning($"Failed removing field value from {f.fieldName} in {f.declaringType.typeName}. Field value in code might not be up to date. Exception: {e.Message}");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.FailedRemovingFieldValue, f.fieldName, f.declaringType.typeName, e.Message));
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < renamedReshapedFieldsFrom.Length; i++) {
|
||||
@@ -356,7 +356,7 @@ namespace SingularityGroup.HotReload {
|
||||
{ StatKey.PatchId, resp.id },
|
||||
{ StatKey.Detailed_Exception, e.ToString() },
|
||||
}).Forget();
|
||||
Log.Warning($"Failed moving field value from {fromField} to {toField} in {toField.declaringType.typeName}. Field value in code might not be up to date. Exception: {e.Message}");
|
||||
Log.Warning(Localization.Translations.Logging.FailedMovingFieldValue, fromField, toField, toField.declaringType.typeName, e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,7 +400,7 @@ namespace SingularityGroup.HotReload {
|
||||
{ StatKey.PatchId, resp.id },
|
||||
{ StatKey.Detailed_Exception, e.ToString() },
|
||||
}).Forget();
|
||||
Log.Warning($"Failed updating field attributes of {original.fieldName} in {original.declaringType.typeName}. Updates might not reflect in the inspector. Exception: {e.Message}");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.FailedUpdatingFieldAttributes, original.fieldName, original.declaringType.typeName, e.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -414,14 +414,14 @@ namespace SingularityGroup.HotReload {
|
||||
try {
|
||||
var declaringType = SymbolResolver.Resolve(sField.declaringType);
|
||||
var field = SymbolResolver.Resolve(sField);
|
||||
fieldHandler?.storeField?.Invoke(declaringType, field);
|
||||
result.inspectorFieldAdded = fieldHandler?.storeField?.Invoke(declaringType, field) ?? false;
|
||||
result.inspectorModified = true;
|
||||
} catch (Exception e) {
|
||||
RequestHelper.RequestEditorEventWithRetry(new Stat(StatSource.Client, StatLevel.Error, StatFeature.Patching, StatEventType.AddInspectorField), new EditorExtraData {
|
||||
{ StatKey.PatchId, patchId },
|
||||
{ StatKey.Detailed_Exception, e.ToString() },
|
||||
}).Forget();
|
||||
Log.Warning($"Failed adding field {sField.fieldName}:{sField.declaringType.typeName} to the inspector. Field will not be displayed. Exception: {e.Message}");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.FailedAddingFieldToInspector, sField.fieldName, sField.declaringType.typeName, e.Message));
|
||||
}
|
||||
}
|
||||
result.addedFields.AddRange(sFields);
|
||||
@@ -444,7 +444,7 @@ namespace SingularityGroup.HotReload {
|
||||
{ StatKey.PatchId, patchId },
|
||||
{ StatKey.Detailed_Exception, e.ToString() },
|
||||
}).Forget();
|
||||
Log.Warning($"Failed hiding field {sField.fieldName}:{sField.declaringType.typeName} from the inspector. Exception: {e.Message}");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.FailedHidingFieldFromInspector, sField.fieldName, sField.declaringType.typeName, e.Message));
|
||||
}
|
||||
}
|
||||
if (alteredFieldHidden) {
|
||||
@@ -466,22 +466,21 @@ namespace SingularityGroup.HotReload {
|
||||
RequestHelper.RequestEditorEventWithRetry(new Stat(StatSource.Client, StatLevel.Error, StatFeature.Patching, StatEventType.DebuggerAttached), new EditorExtraData {
|
||||
{ StatKey.PatchId, patchId },
|
||||
}).Forget();
|
||||
return "Patching methods is not allowed while the Debugger is attached. You can change this behavior in settings if Hot Reload is compatible with the debugger you're running.";
|
||||
return Localization.Translations.Logging.DebuggerAttachedNotAllowed;
|
||||
}
|
||||
|
||||
if (DateTime.UtcNow - start > TimeSpan.FromMilliseconds(500)) {
|
||||
Log.Info("Hot Reload apply took {0}", (DateTime.UtcNow - start).TotalMilliseconds);
|
||||
Log.Info(Localization.Translations.Logging.HotReloadApplyTook, (DateTime.UtcNow - start).TotalMilliseconds);
|
||||
}
|
||||
|
||||
if(state.match == null) {
|
||||
var error = "Edit requires full recompile to apply: Method mismatch: {0}, patch: {1}. \nCommon causes: editing code that failed to patch previously, an unsupported change, or a real bug in Hot Reload.\nIf you think this is a bug, please report the issue on Discord and include a code-snippet before/after.";
|
||||
RequestHelper.RequestEditorEventWithRetry(new Stat(StatSource.Client, StatLevel.Error, StatFeature.Patching, StatEventType.MethodMismatch), new EditorExtraData {
|
||||
{ StatKey.PatchId, patchId },
|
||||
}).Forget();
|
||||
return string.Format(error, sOriginalMethod.simpleName, patchMethod.Name);
|
||||
return string.Format(Localization.Translations.Logging.MethodMismatch, sOriginalMethod.simpleName, patchMethod.Name);
|
||||
}
|
||||
|
||||
PlayerLog("Detour method {0:X8} {1}, offset: {2}", sOriginalMethod.metadataToken, patchMethod.Name, state.offset);
|
||||
PlayerLog(Localization.Translations.Logging.DetourMethod, sOriginalMethod.metadataToken, patchMethod.Name, state.offset);
|
||||
DetourResult result;
|
||||
DetourApi.DetourMethod(state.match, patchMethod, out result);
|
||||
if (result.success) {
|
||||
@@ -617,7 +616,7 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
|
||||
string HandleMethodPatchFailure(SMethod method, Exception exception) {
|
||||
return $"Edit requires full recompile to apply: Failed to apply patch for method {method.displayName} in assembly {method.assemblyName}.\nCommon causes: editing code that failed to patch previously, an unsupported change, or a real bug in Hot Reload.\nIf you think this is a bug, please report the issue on Discord and include a code-snippet before/after.\nException: {exception}";
|
||||
return string.Format(Localization.Translations.Logging.FailedToApplyPatchForMethod, method.displayName, method.assemblyName, exception);
|
||||
}
|
||||
|
||||
void EnsureSymbolResolver() {
|
||||
@@ -664,12 +663,12 @@ namespace SingularityGroup.HotReload {
|
||||
filePath = Path.GetFullPath(filePath);
|
||||
var dir = Path.GetDirectoryName(filePath);
|
||||
if(string.IsNullOrEmpty(dir)) {
|
||||
throw new ArgumentException("Invalid path: " + filePath, nameof(filePath));
|
||||
throw new ArgumentException(string.Format(Localization.Translations.Logging.InvalidPath, filePath), nameof(filePath));
|
||||
}
|
||||
Directory.CreateDirectory(dir);
|
||||
var history = patchHistory.ToList();
|
||||
|
||||
PlayerLog("Saving {0} applied patches to {1}", history.Count, filePath);
|
||||
PlayerLog(Localization.Translations.Logging.SavingAppliedPatches, history.Count, filePath);
|
||||
|
||||
await Task.Run(() => {
|
||||
using (FileStream fs = File.Create(filePath))
|
||||
@@ -717,4 +716,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -32,9 +32,9 @@ namespace SingularityGroup.HotReload.Demo {
|
||||
// Update is called once per frame
|
||||
void Update() {
|
||||
if (Demo.I.IsServerRunning()) {
|
||||
informationText.text = "Hot Reload is running";
|
||||
informationText.text = Localization.Translations.Common.HotReloadIsRunning;
|
||||
} else {
|
||||
informationText.text = "Hot Reload is not running";
|
||||
informationText.text = Localization.Translations.Common.HotReloadIsNotRunning;
|
||||
}
|
||||
|
||||
// // 2. Editing functions in monobehaviours, normal classes or static classes
|
||||
|
||||
@@ -34,9 +34,9 @@ namespace SingularityGroup.HotReload.Demo {
|
||||
handle.Complete();
|
||||
|
||||
if (Demo.I.IsServerRunning()) {
|
||||
informationText.text = "Hot Reload is running";
|
||||
informationText.text = Localization.Translations.Common.HotReloadIsRunning;
|
||||
} else {
|
||||
informationText.text = "Hot Reload is not running";
|
||||
informationText.text = Localization.Translations.Common.HotReloadIsNotRunning;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
|
||||
internal static class HotReloadSettingsHelper {
|
||||
public static UnityEngine.GameObject GetOrCreateSettingsPrefab(string prefabAssetPath) {
|
||||
#if UNITY_EDITOR
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<UnityEngine.GameObject>(prefabAssetPath);
|
||||
if (prefab == null) {
|
||||
// when you use HotReload as a unitypackage, prefab is somewhere inside your assets folder
|
||||
var guids = AssetDatabase.FindAssets("HotReloadPrompts t:prefab", new string[]{"Assets"});
|
||||
var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid));
|
||||
var promptsPrefabPath = paths.FirstOrDefault(assetpath => Path.GetFileName(assetpath) == "HotReloadPrompts.prefab");
|
||||
if (promptsPrefabPath != null) {
|
||||
prefab = AssetDatabase.LoadAssetAtPath<UnityEngine.GameObject>(promptsPrefabPath);
|
||||
}
|
||||
}
|
||||
if (prefab == null) {
|
||||
throw new Exception(Localization.Translations.Errors.FailedPromptsPrefab);
|
||||
}
|
||||
return prefab;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static HotReloadSettingsObject GetSettingsObject(string editorAssetPath) {
|
||||
#if UNITY_EDITOR
|
||||
return AssetDatabase.LoadAssetAtPath<HotReloadSettingsObject>(editorAssetPath);
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bff36678f3d4a2bb24c477d28f96888
|
||||
timeCreated: 1765129558
|
||||
@@ -1,14 +1,8 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
/// <summary>
|
||||
/// HotReload runtime settings. These can be changed while the app is running.
|
||||
@@ -62,11 +56,7 @@ namespace SingularityGroup.HotReload {
|
||||
private static HotReloadSettingsObject LoadSettings() {
|
||||
HotReloadSettingsObject settings;
|
||||
if (Application.isEditor) {
|
||||
#if UNITY_EDITOR
|
||||
settings = AssetDatabase.LoadAssetAtPath<HotReloadSettingsObject>(editorAssetPath);
|
||||
#else
|
||||
settings = null;
|
||||
#endif
|
||||
settings = HotReloadSettingsHelper.GetSettingsObject(editorAssetPath);
|
||||
} else {
|
||||
// load from Resources (assumes that build includes the resource)
|
||||
settings = Resources.Load<HotReloadSettingsObject>(resourceName);
|
||||
@@ -93,38 +83,21 @@ namespace SingularityGroup.HotReload {
|
||||
|
||||
// Call this during build, just to be sure the field is correct. (I had some issues with it while editing the prefab)
|
||||
public void EnsurePrefabSetCorrectly() {
|
||||
#if UNITY_EDITOR
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabAssetPath);
|
||||
if (prefab == null) {
|
||||
// when you use HotReload as a unitypackage, prefab is somewhere inside your assets folder
|
||||
var guids = AssetDatabase.FindAssets("HotReloadPrompts t:prefab", new string[]{"Assets"});
|
||||
var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid));
|
||||
var promptsPrefabPath = paths.FirstOrDefault(assetpath => Path.GetFileName(assetpath) == "HotReloadPrompts.prefab");
|
||||
if (promptsPrefabPath != null) {
|
||||
prefab = AssetDatabase.LoadAssetAtPath<GameObject>(promptsPrefabPath);
|
||||
}
|
||||
}
|
||||
if (prefab == null) {
|
||||
throw new Exception("Failed to find PromptsPrefab (are you using Hot Reload as a package?");
|
||||
}
|
||||
PromptsPrefab = prefab;
|
||||
#endif
|
||||
PromptsPrefab = HotReloadSettingsHelper.GetOrCreateSettingsPrefab(prefabAssetPath);
|
||||
}
|
||||
|
||||
public void EnsurePrefabNotInBuild() {
|
||||
#if UNITY_EDITOR
|
||||
PromptsPrefab = null;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// put the stored settings here
|
||||
|
||||
[Header("Build Settings")]
|
||||
[Tooltip("Should the Hot Reload runtime be included in development builds? HotReload is never included in release builds.")]
|
||||
[Header(Localization.Translations.MenuItems.BuildSettings)]
|
||||
[Tooltip(Localization.Translations.MenuItems.IncludeInBuildTooltip)]
|
||||
public bool IncludeInBuild = true;
|
||||
|
||||
[Header("Player Settings")]
|
||||
[Header(Localization.Translations.MenuItems.PlayerSettings)]
|
||||
public bool AllowAndroidAppToMakeHttpRequests = false;
|
||||
|
||||
#region hidden
|
||||
@@ -137,4 +110,3 @@ namespace SingularityGroup.HotReload {
|
||||
#endregion settings
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System.Net.Http;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
|
||||
@@ -15,5 +14,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
namespace SingularityGroup.HotReload {
|
||||
public interface IServerHealthCheck {
|
||||
bool IsServerHealthy { get; }
|
||||
@@ -8,4 +7,3 @@ namespace SingularityGroup.HotReload {
|
||||
void CheckHealth();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@@ -24,4 +23,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
#define MOBILE_ANDROID
|
||||
#endif
|
||||
@@ -61,4 +60,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -7,7 +7,7 @@ PluginImporter:
|
||||
executionOrder: {}
|
||||
defineConstraints:
|
||||
- ENABLE_MONO
|
||||
- DEVELOPMENT_BUILD
|
||||
- DEVELOPMENT_BUILD || UNITY_EDITOR
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 1
|
||||
|
||||
@@ -8,7 +8,7 @@ PluginImporter:
|
||||
defineConstraints:
|
||||
- ENABLE_MONO
|
||||
- UNITY_2019_4_OR_NEWER
|
||||
- DEVELOPMENT_BUILD
|
||||
- DEVELOPMENT_BUILD || UNITY_EDITOR
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 1
|
||||
|
||||
@@ -8,7 +8,7 @@ PluginImporter:
|
||||
defineConstraints:
|
||||
- ENABLE_MONO
|
||||
- UNITY_2020_3_OR_NEWER
|
||||
- DEVELOPMENT_BUILD
|
||||
- DEVELOPMENT_BUILD || UNITY_EDITOR
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 1
|
||||
|
||||
@@ -8,7 +8,7 @@ PluginImporter:
|
||||
defineConstraints:
|
||||
- ENABLE_MONO
|
||||
- UNITY_2022_2_OR_NEWER
|
||||
- DEVELOPMENT_BUILD
|
||||
- DEVELOPMENT_BUILD || UNITY_EDITOR
|
||||
isPreloaded: 0
|
||||
isOverridable: 1
|
||||
isExplicitlyReferenced: 1
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 392d4a942d5d4d26872be33e375c8d32
|
||||
timeCreated: 1759652490
|
||||
@@ -0,0 +1,46 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
namespace SingularityGroup.HotReload.Localization {
|
||||
|
||||
internal static partial class Translations {
|
||||
public static class Common {
|
||||
public static string UnknownException;
|
||||
public static string HotReloadIsRunning;
|
||||
public static string HotReloadIsNotRunning;
|
||||
public static string UnableToResolveMethod;
|
||||
public static string UnableToResolveType;
|
||||
public static string UnableToResolveField;
|
||||
public static string HotReloadUnreachable;
|
||||
public static string TryingToReconnect;
|
||||
public static string Disconnected;
|
||||
public static string Unknown;
|
||||
|
||||
public static void LoadEnglish() {
|
||||
UnknownException = "unknown exception";
|
||||
HotReloadIsRunning = "Hot Reload is running";
|
||||
HotReloadIsNotRunning = "Hot Reload is not running";
|
||||
UnableToResolveMethod = "Unable to resolve method";
|
||||
UnableToResolveType = "Unable to resolve type";
|
||||
UnableToResolveField = "Unable to resolve field";
|
||||
HotReloadUnreachable = "Hot Reload was unreachable for 5 seconds, trying to reconnect...";
|
||||
TryingToReconnect = "Trying to reconnect...";
|
||||
Disconnected = "Disconnected";
|
||||
Unknown = "unknown";
|
||||
}
|
||||
|
||||
public static void LoadSimplifiedChinese() {
|
||||
UnknownException = "未知异常";
|
||||
HotReloadIsRunning = "Hot Reload 正在运行";
|
||||
HotReloadIsNotRunning = "Hot Reload 未运行";
|
||||
UnableToResolveMethod = "无法解析方法";
|
||||
UnableToResolveType = "无法解析类型";
|
||||
UnableToResolveField = "无法解析字段";
|
||||
HotReloadUnreachable = "Hot Reload 5 秒内无法访问,正在尝试重新连接...";
|
||||
TryingToReconnect = "正在尝试重新连接...";
|
||||
Disconnected = "已断开连接";
|
||||
Unknown = "未知";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71c2ede153664ef48b2919d3c42da1a3
|
||||
timeCreated: 1762538401
|
||||
@@ -0,0 +1,82 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
namespace SingularityGroup.HotReload.Localization {
|
||||
|
||||
internal static partial class Translations {
|
||||
public static class Dialogs {
|
||||
public static string Information;
|
||||
public static string ContinueButtonText;
|
||||
public static string CancelButtonText;
|
||||
public static string DifferentProjectSummary;
|
||||
public static string DifferentProjectSuggestion;
|
||||
public static string DifferentCommitSummary;
|
||||
public static string DifferentCommitSuggestion;
|
||||
public static string ConnectionStateConnecting;
|
||||
public static string ConnectionStateHandshaking;
|
||||
public static string ConnectionStateDifferencesFound;
|
||||
public static string ConnectionStateConnected;
|
||||
public static string ConnectionStateCancelled;
|
||||
public static string Patches;
|
||||
public static string IsConnected;
|
||||
public static string NoWiFiNetwork;
|
||||
public static string WaitForCompiling;
|
||||
public static string TargetNetworkIsReachable;
|
||||
public static string AutoPairEncounteredIssue;
|
||||
public static string ConnectionFailed;
|
||||
public static string TryingToReconnect;
|
||||
public static string Disconnected;
|
||||
public static string PatchesStatus;
|
||||
|
||||
public static void LoadEnglish() {
|
||||
Information = "Information";
|
||||
ContinueButtonText = "Continue";
|
||||
CancelButtonText = "Cancel";
|
||||
DifferentProjectSummary = "Hot Reload was started from a different project";
|
||||
DifferentProjectSuggestion = "Please run Hot Reload from the matching Unity project";
|
||||
DifferentCommitSummary = "Editor and current build are on different commits";
|
||||
DifferentCommitSuggestion = "This can cause errors when the build was made on an old commit.";
|
||||
ConnectionStateConnecting = "Connecting ...";
|
||||
ConnectionStateHandshaking = "Handshaking ...";
|
||||
ConnectionStateDifferencesFound = "Differences found";
|
||||
ConnectionStateConnected = "Connected!";
|
||||
ConnectionStateCancelled = "Cancelled";
|
||||
Patches = "Patches";
|
||||
IsConnected = "Is this device connected to {0}?";
|
||||
NoWiFiNetwork = "WiFi";
|
||||
WaitForCompiling = "Wait for compiling to finish before trying again";
|
||||
TargetNetworkIsReachable = "Make sure you're on the same {0} network. Also ensure Hot Reload is running";
|
||||
AutoPairEncounteredIssue = "Auto-pair encountered an issue";
|
||||
ConnectionFailed = "Connection failed";
|
||||
TryingToReconnect = "Trying to reconnect ...";
|
||||
Disconnected = "Disconnected";
|
||||
PatchesStatus = "Patches: {0} pending, {1} applied";
|
||||
}
|
||||
|
||||
public static void LoadSimplifiedChinese() {
|
||||
Information = "信息";
|
||||
ContinueButtonText = "继续";
|
||||
CancelButtonText = "取消";
|
||||
DifferentProjectSummary = "Hot Reload 从不同的项目启动";
|
||||
DifferentProjectSuggestion = "请从匹配的 Unity 项目运行 Hot Reload";
|
||||
DifferentCommitSummary = "编辑器和当前构建在不同的提交上";
|
||||
DifferentCommitSuggestion = "当构建是在旧的提交上进行时,这可能会导致错误。";
|
||||
ConnectionStateConnecting = "正在连接 ...";
|
||||
ConnectionStateHandshaking = "正在握手 ...";
|
||||
ConnectionStateDifferencesFound = "发现差异";
|
||||
ConnectionStateConnected = "已连接!";
|
||||
ConnectionStateCancelled = "已取消";
|
||||
Patches = "补丁";
|
||||
IsConnected = "此设备是否已连接到 {0}?";
|
||||
NoWiFiNetwork = "WiFi";
|
||||
WaitForCompiling = "请等待编译完成后再试";
|
||||
TargetNetworkIsReachable = "请确保您在同一个 {0} 网络中。还要确保 Hot Reload 正在运行";
|
||||
AutoPairEncounteredIssue = "自动配对遇到问题";
|
||||
ConnectionFailed = "连接失败";
|
||||
TryingToReconnect = "正在尝试重新连接 ...";
|
||||
Disconnected = "已断开连接";
|
||||
PatchesStatus = "补丁:{0} 待处理,{1} 已应用";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3970cf8b2b8a47dd9d16ce5051375690
|
||||
timeCreated: 1762538420
|
||||
@@ -0,0 +1,73 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
namespace SingularityGroup.HotReload.Localization {
|
||||
|
||||
internal static partial class Translations {
|
||||
public static class Errors {
|
||||
public static string MethodNameMismatch;
|
||||
public static string DeclaringTypeNameMismatch;
|
||||
public static string IsGenericMethodDefinitionMismatch;
|
||||
public static string MissingThisParameter;
|
||||
public static string ThisParameterTypeMismatch;
|
||||
public static string ParameterCountMismatch;
|
||||
public static string ParameterTypeMismatch;
|
||||
public static string ReturnTypeMismatch;
|
||||
public static string GenericParameterNotGenericType;
|
||||
public static string GenericParameterDidNotExist;
|
||||
public static string IsPlayerWithHotReloadFalse;
|
||||
public static string UnknownExceptionReadingBuildInfo;
|
||||
public static string BuildInfoNotFound;
|
||||
public static string FailedPromptsPrefab;
|
||||
public static string HandshakeFailedInvalidBuildTarget;
|
||||
public static string BuildTargetMismatch;
|
||||
public static string UnableToResolveMethodInAssembly;
|
||||
public static string UnableToResolveTypeInAssembly;
|
||||
public static string UnableToResolveFieldInAssembly;
|
||||
|
||||
public static void LoadEnglish() {
|
||||
MethodNameMismatch = "Method name mismatch";
|
||||
DeclaringTypeNameMismatch = "Declaring type name mismatch";
|
||||
IsGenericMethodDefinitionMismatch = "IsGenericMethodDefinition mismatch";
|
||||
MissingThisParameter = "missing this parameter";
|
||||
ThisParameterTypeMismatch = "this parameter type mismatch";
|
||||
ParameterCountMismatch = "parameter count mismatch";
|
||||
ParameterTypeMismatch = "parameter type mismatch";
|
||||
ReturnTypeMismatch = "Return type mismatch";
|
||||
GenericParameterNotGenericType = "Generic parameter did not resolve to generic type definition";
|
||||
GenericParameterDidNotExist = "Generic parameter did not exist on the generic type definition";
|
||||
IsPlayerWithHotReloadFalse = "IsPlayerWithHotReload() is false";
|
||||
UnknownExceptionReadingBuildInfo = "Uknown exception happened when reading build info";
|
||||
BuildInfoNotFound = "Uknown issue happened when reading build info.";
|
||||
FailedPromptsPrefab = "Failed to find PromptsPrefab (are you using Hot Reload as a package?";
|
||||
HandshakeFailedInvalidBuildTarget = "Server did not declare its current Unity activeBuildTarget in the handshake response. Will assume it is {0}.";
|
||||
BuildTargetMismatch = "Your Unity project is running on {0}. You may need to switch it to {1} for Hot Reload to work.";
|
||||
UnableToResolveMethodInAssembly = "Unable to resolve method {0} in assembly {1}";
|
||||
UnableToResolveTypeInAssembly = "Unable to resolve type with name: {0} in assembly {1}";
|
||||
UnableToResolveFieldInAssembly = "Unable to resolve field with name: {0} in assembly {1}";
|
||||
}
|
||||
|
||||
public static void LoadSimplifiedChinese() {
|
||||
MethodNameMismatch = "方法名称不匹配";
|
||||
DeclaringTypeNameMismatch = "声明类型名称不匹配";
|
||||
IsGenericMethodDefinitionMismatch = "IsGenericMethodDefinition 不匹配";
|
||||
MissingThisParameter = "缺少 this 参数";
|
||||
ThisParameterTypeMismatch = "this 参数类型不匹配";
|
||||
ParameterCountMismatch = "参数数量不匹配";
|
||||
ParameterTypeMismatch = "参数类型不匹配";
|
||||
ReturnTypeMismatch = "返回类型不匹配";
|
||||
GenericParameterNotGenericType = "泛型参数未解析为泛型类型定义";
|
||||
GenericParameterDidNotExist = "泛型参数在泛型类型定义上不存在";
|
||||
IsPlayerWithHotReloadFalse = "IsPlayerWithHotReload() 为 false";
|
||||
UnknownExceptionReadingBuildInfo = "读取构建信息时发生未知异常";
|
||||
BuildInfoNotFound = "读取构建信息时发生未知问题。";
|
||||
FailedPromptsPrefab = "未能找到 PromptsPrefab(您是否将 Hot Reload 作为软件包使用?";
|
||||
HandshakeFailedInvalidBuildTarget = "服务器在握手响应中未声明其当前的 Unity activeBuildTarget。将假定为 {0}。";
|
||||
BuildTargetMismatch = "您的 Unity 项目正在 {0} 上运行。您可能需要将其切换到 {1} 才能使 Hot Reload 工作。";
|
||||
UnableToResolveMethodInAssembly = "无法在程序集 {1} 中解析方法 {0}";
|
||||
UnableToResolveTypeInAssembly = "无法在程序集 {1} 中解析名称为 {0} 的类型";
|
||||
UnableToResolveFieldInAssembly = "无法在程序集 {1} 中解析名称为 {0} 的字段";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c96d2f0898524320839b84cf22fcd820
|
||||
timeCreated: 1762538447
|
||||
@@ -0,0 +1,178 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
namespace SingularityGroup.HotReload.Localization {
|
||||
|
||||
internal static partial class Translations {
|
||||
public static class Logging {
|
||||
// Server and Connection
|
||||
public static string HotReloadUnreachableDisconnecting;
|
||||
public static string RequestHandshakeToServer;
|
||||
public static string ServerHealthyAfterHandshake;
|
||||
|
||||
// Polling Errors
|
||||
public static string PollMethodPatchesFailed;
|
||||
public static string PollPatchStatusFailed;
|
||||
public static string PollAssetChangesFailed;
|
||||
|
||||
// Request Errors
|
||||
public static string DeserializingResponseFailed;
|
||||
public static string RequestTimeout;
|
||||
|
||||
// Method Invocation
|
||||
public static string InvokeOnHotReloadFailed;
|
||||
public static string InvokeOnHotReloadLocalFailed;
|
||||
|
||||
// Build and Player
|
||||
public static string HotReloadNotAvailableBuildSettings;
|
||||
public static string BuildInfoNotFound;
|
||||
|
||||
// Method Compatibility
|
||||
public static string UnknownIssue;
|
||||
|
||||
// Patch Loading/Saving
|
||||
public static string LoadingPatchesFromDiskError;
|
||||
public static string LoadingPatchesFromFile;
|
||||
public static string LoadedPatchesFromDisk;
|
||||
public static string SavingAppliedPatches;
|
||||
|
||||
// Patch Registration/Application
|
||||
public static string RegisterPatches;
|
||||
public static string ApplyPatchesPending;
|
||||
public static string DetourMethod;
|
||||
|
||||
// Exceptions
|
||||
public static string ExceptionHandlingMethodPatch;
|
||||
public static string ExceptionApplyingPatch;
|
||||
public static string ExceptionEnsureUnityEventMethod;
|
||||
public static string ExceptionRemoveUnityEventMethod;
|
||||
public static string InvalidPath;
|
||||
|
||||
// Field Operations
|
||||
public static string FailedRegisteringInitializerInvalidMethod;
|
||||
public static string FailedRegisteringInitializerException;
|
||||
public static string FailedRegisteringNewFieldDefinitions;
|
||||
public static string FailedRemovingInitializer;
|
||||
public static string FailedRemovingFieldValue;
|
||||
public static string FailedMovingFieldValue;
|
||||
public static string FailedUpdatingFieldAttributes;
|
||||
public static string FailedAddingFieldToInspector;
|
||||
public static string FailedHidingFieldFromInspector;
|
||||
|
||||
// Method Patching
|
||||
public static string DebuggerAttachedNotAllowed;
|
||||
public static string MethodMismatch;
|
||||
public static string FailedToApplyPatchForMethod;
|
||||
public static string HotReloadApplyTook;
|
||||
|
||||
// Unity Events
|
||||
public static string SceneLoadedWithNewUnityEventMethods;
|
||||
|
||||
public static void LoadEnglish() {
|
||||
HotReloadUnreachableDisconnecting = "Hot Reload was unreachable for {0} seconds, disconnecting";
|
||||
RequestHandshakeToServer = "Request handshake to Hot Reload server with hostname: {0}";
|
||||
ServerHealthyAfterHandshake = "Server is healthy after first handshake? {0}";
|
||||
|
||||
PollMethodPatchesFailed = "PollMethodPatches failed with code {0} {1} {2}";
|
||||
PollPatchStatusFailed = "PollPatchStatus failed with code {0} {1} {2}";
|
||||
PollAssetChangesFailed = "PollAssetChanges failed with code {0} {1} {2}";
|
||||
|
||||
DeserializingResponseFailed = "Deserializing response failed with {0}: {1}";
|
||||
RequestTimeout = "Request timeout";
|
||||
|
||||
InvokeOnHotReloadFailed = "[InvokeOnHotReload] {0} {1} failed. Exception:\n{2}";
|
||||
InvokeOnHotReloadLocalFailed = "[InvokeOnHotReloadLocal] {0} {1} failed. Exception:\n{2}";
|
||||
|
||||
HotReloadNotAvailableBuildSettings = "Hot Reload is not available in this build because one or more build settings were not supported.";
|
||||
BuildInfoNotFound = "Build info not found";
|
||||
|
||||
UnknownIssue = "unknown issue";
|
||||
|
||||
LoadingPatchesFromDiskError = "Encountered exception when loading patches from disk:";
|
||||
LoadingPatchesFromFile = "Loading patches from file {0}";
|
||||
LoadedPatchesFromDisk = "Loaded {0} patches from disk";
|
||||
SavingAppliedPatches = "Saving {0} applied patches to {1}";
|
||||
|
||||
RegisterPatches = "Register patches.\nWarnings: {0} \nMethods:\n{1}";
|
||||
ApplyPatchesPending = "ApplyPatches. {0} patches pending.";
|
||||
DetourMethod = "Detour method {0:X8} {1}, offset: {2}";
|
||||
|
||||
ExceptionHandlingMethodPatch = "Exception occured when handling method patch. Exception:";
|
||||
ExceptionApplyingPatch = "Edit requires full recompile to apply: Encountered exception when applying a patch.\nCommon causes: editing code that failed to patch previously, an unsupported change, or a real bug in Hot Reload.\nIf you think this is a bug, please report the issue on Discord and include a code-snippet before/after.";
|
||||
ExceptionEnsureUnityEventMethod = "Encountered exception in EnsureUnityEventMethod: {0} {1}";
|
||||
ExceptionRemoveUnityEventMethod = "Encountered exception in RemoveUnityEventMethod: {0} {1}";
|
||||
InvalidPath = "Invalid path: {0}";
|
||||
|
||||
FailedRegisteringInitializerInvalidMethod = "Failed registering initializer for field {0} in {1}. Field value might not be initialized correctly. Invalid method.";
|
||||
FailedRegisteringInitializerException = "Failed registering initializer for field {0} in {1}. Field value might not be initialized correctly. Exception: {2}";
|
||||
FailedRegisteringNewFieldDefinitions = "Failed registering new field definitions for field {0} in {1}. Exception: {2}";
|
||||
FailedRemovingInitializer = "Failed removing initializer for field {0} in {1}. Field value might not be initialized correctly. Exception: {2}";
|
||||
FailedRemovingFieldValue = "Failed removing field value from {0} in {1}. Field value in code might not be up to date. Exception: {2}";
|
||||
FailedMovingFieldValue = "Failed moving field value from {0} to {1} in {2}. Field value in code might not be up to date. Exception: {3}";
|
||||
FailedUpdatingFieldAttributes = "Failed updating field attributes of {0} in {1}. Updates might not reflect in the inspector. Exception: {2}";
|
||||
FailedAddingFieldToInspector = "Failed adding field {0}:{1} to the inspector. Field will not be displayed. Exception: {2}";
|
||||
FailedHidingFieldFromInspector = "Failed hiding field {0}:{1} from the inspector. Exception: {2}";
|
||||
|
||||
DebuggerAttachedNotAllowed = "Patching methods is not allowed while the Debugger is attached. You can change this behavior in settings if Hot Reload is compatible with the debugger you're running.";
|
||||
MethodMismatch = "Edit requires full recompile to apply: Method mismatch: {0}, patch: {1}. \nCommon causes: editing code that failed to patch previously, an unsupported change, or a real bug in Hot Reload.\nIf you think this is a bug, please report the issue on Discord and include a code-snippet before/after.";
|
||||
FailedToApplyPatchForMethod = "Edit requires full recompile to apply: Failed to apply patch for method {0} in assembly {1}.\nCommon causes: editing code that failed to patch previously, an unsupported change, or a real bug in Hot Reload.\nIf you think this is a bug, please report the issue on Discord and include a code-snippet before/after.\nException: {2}";
|
||||
HotReloadApplyTook = "Hot Reload apply took {0}";
|
||||
|
||||
SceneLoadedWithNewUnityEventMethods = "A new Scene was loaded while new unity event methods were added at runtime. MonoBehaviours in the Scene will not trigger these new events.";
|
||||
}
|
||||
|
||||
public static void LoadSimplifiedChinese() {
|
||||
HotReloadUnreachableDisconnecting = "Hot Reload {0} 秒内无法访问,正在断开连接";
|
||||
RequestHandshakeToServer = "向 Hot Reload 服务器请求握手,主机名:{0}";
|
||||
ServerHealthyAfterHandshake = "第一次握手后服务器是否健康?{0}";
|
||||
|
||||
PollMethodPatchesFailed = "PollMethodPatches 失败,代码 {0} {1} {2}";
|
||||
PollPatchStatusFailed = "PollPatchStatus 失败,代码 {0} {1} {2}";
|
||||
PollAssetChangesFailed = "PollAssetChanges 失败,代码 {0} {1} {2}";
|
||||
|
||||
DeserializingResponseFailed = "反序列化响应失败,{0}:{1}";
|
||||
RequestTimeout = "请求超时";
|
||||
|
||||
InvokeOnHotReloadFailed = "[InvokeOnHotReload] {0} {1} 失败。异常:\n{2}";
|
||||
InvokeOnHotReloadLocalFailed = "[InvokeOnHotReloadLocal] {0} {1} 失败。异常:\n{2}";
|
||||
|
||||
HotReloadNotAvailableBuildSettings = "由于一个或多个构建设置不受支持,Hot Reload 在此构建中不可用。";
|
||||
BuildInfoNotFound = "未找到构建信息";
|
||||
|
||||
UnknownIssue = "未知问题";
|
||||
|
||||
LoadingPatchesFromDiskError = "从磁盘加载补丁时遇到异常:";
|
||||
LoadingPatchesFromFile = "从文件 {0} 加载补丁";
|
||||
LoadedPatchesFromDisk = "从磁盘加载了 {0} 个补丁";
|
||||
SavingAppliedPatches = "将 {0} 个已应用的补丁保存到 {1}";
|
||||
|
||||
RegisterPatches = "注册补丁。\n警告:{0} \n方法:\n{1}";
|
||||
ApplyPatchesPending = "ApplyPatches。{0} 个补丁待处理。";
|
||||
DetourMethod = "Detour 方法 {0:X8} {1},偏移量:{2}";
|
||||
|
||||
ExceptionHandlingMethodPatch = "处理方法补丁时发生异常。异常:";
|
||||
ExceptionApplyingPatch = "编辑需要完全重新编译才能应用:应用补丁时遇到异常。\n常见原因:编辑之前修补失败的代码、不支持的更改或 Hot Reload 中的真正错误。\n如果您认为这是一个错误,请在 Discord 上报告问题并附上之前/之后的代码片段。";
|
||||
ExceptionEnsureUnityEventMethod = "在 EnsureUnityEventMethod 中遇到异常:{0} {1}";
|
||||
ExceptionRemoveUnityEventMethod = "在 RemoveUnityEventMethod 中遇到异常:{0} {1}";
|
||||
InvalidPath = "无效路径:{0}";
|
||||
|
||||
FailedRegisteringInitializerInvalidMethod = "在 {1} 中为字段 {0} 注册初始化程序失败。字段值可能未正确初始化。方法无效。";
|
||||
FailedRegisteringInitializerException = "在 {1} 中为字段 {0} 注册初始化程序失败。字段值可能未正确初始化。异常:{2}";
|
||||
FailedRegisteringNewFieldDefinitions = "在 {1} 中为字段 {0} 注册新字段定义失败。异常:{2}";
|
||||
FailedRemovingInitializer = "在 {1} 中为字段 {0} 删除初始化程序失败。字段值可能未正确初始化。异常:{2}";
|
||||
FailedRemovingFieldValue = "从 {1} 中的 {0} 删除字段值失败。代码中的字段值可能不是最新的。异常:{2}";
|
||||
FailedMovingFieldValue = "在 {2} 中将字段值从 {0} 移动到 {1} 失败。代码中的字段值可能不是最新的。异常:{3}";
|
||||
FailedUpdatingFieldAttributes = "在 {1} 中更新 {0} 的字段属性失败。更新可能不会反映在检查器中。异常:{2}";
|
||||
FailedAddingFieldToInspector = "将字段 {0}:{1} 添加到检查器失败。字段将不会显示。异常:{2}";
|
||||
FailedHidingFieldFromInspector = "从检查器中隐藏字段 {0}:{1} 失败。异常:{2}";
|
||||
|
||||
DebuggerAttachedNotAllowed = "附加调试器时不允许修补方法。如果 Hot Reload 与您正在运行的调试器兼容,您可以在设置中更改此行为。";
|
||||
MethodMismatch = "编辑需要完全重新编译才能应用:方法不匹配:{0},补丁:{1}。\n常见原因:编辑之前修补失败的代码、不支持的更改或 Hot Reload 中的真正错误。\n如果您认为这是一个错误,请在 Discord 上报告问题并附上之前/之后的代码片段。";
|
||||
FailedToApplyPatchForMethod = "编辑需要完全重新编译才能应用:为程序集 {1} 中的方法 {0} 应用补丁失败。\n常见原因:编辑之前修补失败的代码、不支持的更改或 Hot Reload 中的真正错误。\n如果您认为这是一个错误,请在 Discord 上报告问题并附上之前/之后的代码片段。\n异常:{2}";
|
||||
HotReloadApplyTook = "Hot Reload 应用耗时 {0}";
|
||||
|
||||
SceneLoadedWithNewUnityEventMethods = "在运行时添加新的 unity 事件方法时加载了新场景。场景中的 MonoBehaviours 不会触发这些新事件。";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bbabe74466b6cb84bb5d2e98d9779397
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
namespace SingularityGroup.HotReload.Localization {
|
||||
|
||||
internal static partial class Translations {
|
||||
public static class MenuItems {
|
||||
public const string UIControls = PackageConst.DefaultLocale == Locale.SimplifiedChinese ? "UI 控件" : "UI controls";
|
||||
public const string Information = PackageConst.DefaultLocale == Locale.SimplifiedChinese ? "信息" : "Information";
|
||||
public const string Other = PackageConst.DefaultLocale == Locale.SimplifiedChinese ? "其他" : "Other";
|
||||
public const string FalllbackEventSystem = PackageConst.DefaultLocale == Locale.SimplifiedChinese ? "当项目未能及早创建 EventSystem 时使用" : "Used when project does not create an EventSystem early enough";
|
||||
public const string BuildSettings = PackageConst.DefaultLocale == Locale.SimplifiedChinese ? "构建设置" : "Build Settings";
|
||||
public const string IncludeInBuildTooltip = PackageConst.DefaultLocale == Locale.SimplifiedChinese ? "Hot Reload 运行时是否应包含在开发版本中?HotReload 永远不会包含在发布版本中。" : "Should the Hot Reload runtime be included in development builds? HotReload is never included in release builds.";
|
||||
public const string PlayerSettings = PackageConst.DefaultLocale == Locale.SimplifiedChinese ? "播放器设置" : "Player Settings";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12be1a0b0b06402da21c46ae29d60746
|
||||
timeCreated: 1762675925
|
||||
@@ -0,0 +1,34 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
namespace SingularityGroup.HotReload.Localization {
|
||||
|
||||
internal static partial class Translations {
|
||||
public static class Settings {
|
||||
public static string BuildSettings;
|
||||
public static string IncludeInBuildTooltip;
|
||||
public static string PlayerSettings;
|
||||
public static string Other;
|
||||
public static string FallbackEventSystemTooltip;
|
||||
public static string NoEventSystemWarning;
|
||||
|
||||
public static void LoadEnglish() {
|
||||
BuildSettings = "Build Settings";
|
||||
IncludeInBuildTooltip = "Should the Hot Reload runtime be included in development builds? HotReload is never included in release builds.";
|
||||
PlayerSettings = "Player Settings";
|
||||
Other = "Other";
|
||||
FallbackEventSystemTooltip = "Used when project does not create an EventSystem early enough";
|
||||
NoEventSystemWarning = "No EventSystem is active, enabling an EventSystem inside Hot Reload {0} prefab. A Unity EventSystem and an Input module is required for tapping buttons on the Unity UI.";
|
||||
}
|
||||
|
||||
public static void LoadSimplifiedChinese() {
|
||||
BuildSettings = "构建设置";
|
||||
IncludeInBuildTooltip = "Hot Reload 运行时是否应包含在开发版本中?HotReload 永远不会包含在发布版本中。";
|
||||
PlayerSettings = "播放器设置";
|
||||
Other = "其他";
|
||||
FallbackEventSystemTooltip = "当项目未能及早创建 EventSystem 时使用";
|
||||
NoEventSystemWarning = "没有活动的 EventSystem,正在 Hot Reload {0} 预制件内启用 EventSystem。点击 Unity UI 上的按钮需要 Unity EventSystem 和输入模块。";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0fe4b08bd0d64689be16dc995c89bf1a
|
||||
timeCreated: 1762538464
|
||||
@@ -0,0 +1,51 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
|
||||
namespace SingularityGroup.HotReload.Localization {
|
||||
public static class Locale {
|
||||
public const string SimplifiedChinese = "zh";
|
||||
public const string English = "en";
|
||||
}
|
||||
|
||||
internal static partial class Translations {
|
||||
static string loadedLocale;
|
||||
static Translations() {
|
||||
LoadDefaultLocalization();
|
||||
}
|
||||
|
||||
public static void LoadDefaultLocalization() {
|
||||
LoadLocalization(PackageConst.DefaultLocale);
|
||||
}
|
||||
|
||||
static void LoadLocalization(string locale) {
|
||||
if (loadedLocale == locale) {
|
||||
return;
|
||||
}
|
||||
if (locale == Locale.SimplifiedChinese) {
|
||||
LoadSimplifiedChinese();
|
||||
} else {
|
||||
LoadEnglish();
|
||||
}
|
||||
loadedLocale = locale;
|
||||
}
|
||||
|
||||
public static void LoadEnglish() {
|
||||
// Load strings from subclasses
|
||||
Common.LoadEnglish();
|
||||
Dialogs.LoadEnglish();
|
||||
Errors.LoadEnglish();
|
||||
Settings.LoadEnglish();
|
||||
Logging.LoadEnglish();
|
||||
Utility.LoadSimplifiedChinese();
|
||||
}
|
||||
|
||||
static void LoadSimplifiedChinese() {
|
||||
Common.LoadSimplifiedChinese();
|
||||
Dialogs.LoadSimplifiedChinese();
|
||||
Errors.LoadSimplifiedChinese();
|
||||
Settings.LoadSimplifiedChinese();
|
||||
Logging.LoadSimplifiedChinese();
|
||||
Utility.LoadSimplifiedChinese();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25df321785e144999ae89a3396247f3d
|
||||
timeCreated: 1759652512
|
||||
@@ -0,0 +1,45 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
namespace SingularityGroup.HotReload.Localization {
|
||||
internal static partial class Translations {
|
||||
public static class Utility {
|
||||
public static string BuildSettings;
|
||||
public static string IncludeInBuildTooltip;
|
||||
public static string PlayerSettings;
|
||||
public static string Other;
|
||||
public static string FallbackEventSystemTooltip;
|
||||
public static string NoEventSystemWarning;
|
||||
public static string OnHotReloadWarning;
|
||||
public static string MethodCallWarning;
|
||||
public static string OnHotReloadLocalCallWarning;
|
||||
public static string OnHotReloadLocalWarning;
|
||||
|
||||
public static void LoadEnglish() {
|
||||
BuildSettings = "Build Settings";
|
||||
IncludeInBuildTooltip = "Should the Hot Reload runtime be included in development builds? HotReload is never included in release builds.";
|
||||
PlayerSettings = "Player Settings";
|
||||
Other = "Other";
|
||||
FallbackEventSystemTooltip = "Used when project does not create an EventSystem early enough";
|
||||
NoEventSystemWarning = "No EventSystem is active, enabling an EventSystem inside Hot Reload {0} prefab. A Unity EventSystem and an Input module is required for tapping buttons on the Unity UI.";
|
||||
OnHotReloadWarning = "failed. Make sure it has 0 parameters, or 1 parameter with type List<MethodPatch>. Exception:";
|
||||
MethodCallWarning = "failed. Make sure it's a method with 0 parameters either static or defined on MonoBehaviour.";
|
||||
OnHotReloadLocalCallWarning = "failed. Make sure it has 0 parameters. Exception:";
|
||||
OnHotReloadLocalWarning = "failed to find method {0}. Make sure it exists within the same class.";
|
||||
}
|
||||
|
||||
public static void LoadSimplifiedChinese() {
|
||||
BuildSettings = "构建设置";
|
||||
IncludeInBuildTooltip = "Hot Reload 运行时是否应包含在开发版本中?HotReload 永远不会包含在发布版本中。";
|
||||
PlayerSettings = "播放器设置";
|
||||
Other = "其他";
|
||||
FallbackEventSystemTooltip = "当项目未能及早创建 EventSystem 时使用";
|
||||
NoEventSystemWarning = "没有活动的 EventSystem,正在 Hot Reload {0} 预制件内启用 EventSystem。点击 Unity UI 上的按钮需要 Unity EventSystem 和输入模块。";
|
||||
OnHotReloadWarning = "失败。请确保它有 0 个参数,或 1 个类型为 List<MethodPatch> 的参数。异常:";
|
||||
MethodCallWarning = "失败。请确保它是一个具有 0 个参数的方法,静态或在 MonoBehaviour 上定义。";
|
||||
OnHotReloadLocalCallWarning = "失败。请确保它有 0 个参数。异常:";
|
||||
OnHotReloadLocalWarning = "未能找到方法 {0}。请确保它存在于同一个类中。";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25823cb7b37e421ca5119f326f3e1b21
|
||||
timeCreated: 1762675217
|
||||
@@ -1,8 +1,7 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using SingularityGroup.HotReload.MonoMod.Utils;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
static class MethodCompatiblity {
|
||||
@@ -17,12 +16,12 @@ namespace SingularityGroup.HotReload {
|
||||
if(!ReferenceEquals(previousMethodInfo, null) && !ReferenceEquals(patchMethodInfo, null)) {
|
||||
return AreMethodInfosCompatible(previousMethodInfo, patchMethodInfo);
|
||||
}
|
||||
return "unknown issue";
|
||||
return Localization.Translations.Logging.UnknownIssue;
|
||||
}
|
||||
|
||||
static string AreMethodBasesCompatible(MethodBase previousMethod, MethodBase patchMethod) {
|
||||
if(previousMethod.Name != patchMethod.Name) {
|
||||
return "Method name mismatch";
|
||||
return Localization.Translations.Errors.MethodNameMismatch;
|
||||
}
|
||||
//Declaring type of patch method is different from the target method but their full name (namespace + name) is equal
|
||||
bool isDeclaringTypeCompatible = false;
|
||||
@@ -35,11 +34,11 @@ namespace SingularityGroup.HotReload {
|
||||
declaringType = declaringType.BaseType;
|
||||
}
|
||||
if (!isDeclaringTypeCompatible) {
|
||||
return "Declaring type name mismatch";
|
||||
return Localization.Translations.Errors.DeclaringTypeNameMismatch;
|
||||
}
|
||||
//Check in case type parameter overloads to distinguish between: void M<T>() { } <-> void M() { }
|
||||
if(previousMethod.IsGenericMethodDefinition != patchMethod.IsGenericMethodDefinition) {
|
||||
return "IsGenericMethodDefinition mismatch";
|
||||
return Localization.Translations.Errors.IsGenericMethodDefinitionMismatch;
|
||||
}
|
||||
|
||||
var prevParams = previousMethod.GetParameters();
|
||||
@@ -62,11 +61,11 @@ namespace SingularityGroup.HotReload {
|
||||
//Special case: patch method for an instance method is static and has an explicit this parameter.
|
||||
//If the patch method doesn't have any parameters it is not compatible.
|
||||
if(patchParams.Length == 0) {
|
||||
return "missing this parameter";
|
||||
return Localization.Translations.Errors.MissingThisParameter;
|
||||
}
|
||||
//this parameter has to be the declaring type
|
||||
if(!ParamTypeMatches(patchParams[0].ParameterType, previousMethod.DeclaringType)) {
|
||||
return "this parameter type mismatch";
|
||||
return Localization.Translations.Errors.ThisParameterTypeMismatch;
|
||||
}
|
||||
//Ignore the this parameter and compare the remaining ones.
|
||||
patchParamsSegment = new ArraySegment<ParameterInfo>(patchParams, 1, patchParams.Length - 1);
|
||||
@@ -93,11 +92,11 @@ namespace SingularityGroup.HotReload {
|
||||
|
||||
static string CompareParameters(ArraySegment<ParameterInfo> x, ArraySegment<ParameterInfo> y) {
|
||||
if(x.Count != y.Count) {
|
||||
return "parameter count mismatch";
|
||||
return Localization.Translations.Errors.ParameterCountMismatch;
|
||||
}
|
||||
for (var i = 0; i < x.Count; i++) {
|
||||
if(x.Array[i + x.Offset].ParameterType != y.Array[i + y.Offset].ParameterType) {
|
||||
return "parameter type mismatch";
|
||||
return Localization.Translations.Errors.ParameterTypeMismatch;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -109,8 +108,7 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
|
||||
static string AreMethodInfosCompatible(MethodInfo x, MethodInfo y) {
|
||||
return AreMethodBasesCompatible(x, y) ?? (x.ReturnType == y.ReturnType ? null : "Return type mismatch");
|
||||
return AreMethodBasesCompatible(x, y) ?? (x.ReturnType == y.ReturnType ? null : Localization.Translations.Errors.ReturnTypeMismatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SingularityGroup.HotReload.DTO;
|
||||
@@ -713,4 +711,3 @@ namespace SingularityGroup.HotReload.JsonConverters {
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
@@ -32,4 +31,3 @@ namespace SingularityGroup.HotReload {
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
internal class ConnectionDialog : MonoBehaviour {
|
||||
[Header("UI controls")]
|
||||
|
||||
[Header(Localization.Translations.MenuItems.UIControls)]
|
||||
public Button buttonHide;
|
||||
|
||||
[Header("Information")]
|
||||
[Header(Localization.Translations.MenuItems.Information)]
|
||||
public Text textSummary;
|
||||
public Text textSuggestion;
|
||||
|
||||
@@ -38,7 +40,7 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
|
||||
/// <param name="summary">One of the <see cref="ConnectionSummary"/> constants</param>
|
||||
public void SetSummary(string summary = ConnectionSummary.Connected) {
|
||||
public void SetSummary(string summary) {
|
||||
if (textSummary != null) textSummary.text = summary;
|
||||
isConnected = summary == ConnectionSummary.Connected;
|
||||
}
|
||||
@@ -49,7 +51,7 @@ namespace SingularityGroup.HotReload {
|
||||
void Update() {
|
||||
textSuggestion.enabled = isConnected;
|
||||
if (SyncPatchCounts()) {
|
||||
textSuggestion.text = $"Patches: {pendingPatches} pending, {patchesApplied} applied";
|
||||
textSuggestion.text = string.Format(Localization.Translations.Dialogs.PatchesStatus, pendingPatches, patchesApplied);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,14 +69,14 @@ namespace SingularityGroup.HotReload {
|
||||
/// Therefore, we use short and simple messages.
|
||||
/// </remarks>
|
||||
internal static class ConnectionSummary {
|
||||
public const string Cancelled = "Cancelled";
|
||||
public const string Connecting = "Connecting ...";
|
||||
public const string Handshaking = "Handshaking ...";
|
||||
public const string DifferencesFound = "Differences found";
|
||||
public const string Connected = "Connected!";
|
||||
public static string Cancelled => Localization.Translations.Dialogs.ConnectionStateCancelled;
|
||||
public static string Connecting => Localization.Translations.Dialogs.ConnectionStateConnecting;
|
||||
public static string Handshaking => Localization.Translations.Dialogs.ConnectionStateHandshaking;
|
||||
public static string DifferencesFound => Localization.Translations.Dialogs.ConnectionStateDifferencesFound;
|
||||
public static string Connected => Localization.Translations.Dialogs.ConnectionStateConnected;
|
||||
// reconnecting can be shown for a long time, so a longer message is okay
|
||||
public const string TryingToReconnect = "Trying to reconnect ...";
|
||||
public const string Disconnected = "Disconnected";
|
||||
public static string TryingToReconnect => Localization.Translations.Dialogs.TryingToReconnect;
|
||||
public static string Disconnected => Localization.Translations.Dialogs.Disconnected;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace SingularityGroup.HotReload {
|
||||
public GameObject connectedPrompt;
|
||||
public GameObject questionPrompt;
|
||||
|
||||
[Header("Other")]
|
||||
[Tooltip("Used when project does not create an EventSystem early enough")]
|
||||
[Header(Localization.Translations.MenuItems.Other)]
|
||||
[Tooltip(Localization.Translations.MenuItems.FalllbackEventSystem)]
|
||||
public GameObject fallbackEventSystem;
|
||||
|
||||
#region Singleton
|
||||
@@ -33,7 +33,7 @@ namespace SingularityGroup.HotReload {
|
||||
if (_I == null) {
|
||||
// allow showing prompts in editor (for testing)
|
||||
if (!Application.isEditor && !PlayerEntrypoint.IsPlayerWithHotReload()) {
|
||||
throw new NotSupportedException("IsPlayerWithHotReload() is false");
|
||||
throw new NotSupportedException(Localization.Translations.Errors.IsPlayerWithHotReloadFalse);
|
||||
}
|
||||
var go = Instantiate(HotReloadSettingsObject.I.PromptsPrefab,
|
||||
new Vector3(0, 0, 0), Quaternion.identity);
|
||||
@@ -134,8 +134,7 @@ namespace SingularityGroup.HotReload {
|
||||
/// Scene must contain an EventSystem and StandaloneInputModule, otherwise clicking/tapping on the overlay does nothing.
|
||||
private void DoEnsureEventSystem() {
|
||||
if (EventSystem.current == null) {
|
||||
Log.Info($"No EventSystem is active, enabling an EventSystem inside Hot Reload {name} prefab." +
|
||||
" A Unity EventSystem and an Input module is required for tapping buttons on the Unity UI.");
|
||||
Log.Info(string.Format(Localization.Translations.Settings.NoEventSystemWarning, name));
|
||||
fallbackEventSystem.SetActive(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
class QuestionDialog : MonoBehaviour {
|
||||
|
||||
[Header("Information")]
|
||||
[Header(Localization.Translations.MenuItems.Information)]
|
||||
public Text textSummary;
|
||||
public Text textSuggestion;
|
||||
|
||||
[Header("UI controls")]
|
||||
[Header(Localization.Translations.MenuItems.UIControls)]
|
||||
public Button buttonContinue;
|
||||
public Button buttonCancel;
|
||||
public Button buttonMoreInfo;
|
||||
@@ -50,9 +51,11 @@ namespace SingularityGroup.HotReload {
|
||||
internal class Config {
|
||||
public string summary;
|
||||
public string suggestion;
|
||||
public string continueButtonText = "Continue";
|
||||
public string cancelButtonText = "Cancel";
|
||||
public string moreInfoUrl = "https://hotreload.net/documentation#handling-different-commits";
|
||||
public string continueButtonText = Localization.Translations.Dialogs.ContinueButtonText;
|
||||
public string cancelButtonText = Localization.Translations.Dialogs.CancelButtonText;
|
||||
public string moreInfoUrl = PackageConst.DefaultLocale == Locale.SimplifiedChinese ?
|
||||
"https://hotreload.net/zh/documentation/on-device#处理不同的提交" :
|
||||
"https://hotreload.net/documentation/on-device#handling-different-commits";
|
||||
}
|
||||
|
||||
/// hide this dialog
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using JetBrains.Annotations;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
internal class RetryDialog : MonoBehaviour {
|
||||
[Header("UI controls")]
|
||||
[Header(Localization.Translations.MenuItems.UIControls)]
|
||||
public Button buttonHide;
|
||||
public Button buttonRetryAutoPair;
|
||||
public Button buttonTroubleshoot;
|
||||
@@ -52,7 +53,10 @@ namespace SingularityGroup.HotReload {
|
||||
});
|
||||
|
||||
buttonTroubleshoot.onClick.AddListener(() => {
|
||||
Application.OpenURL("https://hotreload.net/documentation#connection-issues");
|
||||
var docsUrl = PackageConst.DefaultLocale == Locale.SimplifiedChinese ?
|
||||
"https://hotreload.net/zh/documentation/on-device#连接问题" :
|
||||
"https://hotreload.net/documentation/on-device#connection-issues" ;
|
||||
Application.OpenURL(docsUrl);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,9 +77,9 @@ namespace SingularityGroup.HotReload {
|
||||
// assumes that auto-pair already tried for several seconds
|
||||
// suggestions to help the user when auto-pair is failing
|
||||
var networkText = Application.isMobilePlatform ? "WiFi" : "LAN/WiFi";
|
||||
var noWifiNetwork = $"Is this device connected to {networkText}?";
|
||||
var waitForCompiling = "Wait for compiling to finish before trying again";
|
||||
var targetNetworkIsReachable = $"Make sure you're on the same {networkText} network. Also ensure Hot Reload is running";
|
||||
var noWifiNetwork = string.Format(Localization.Translations.Dialogs.IsConnected, networkText);
|
||||
var waitForCompiling = Localization.Translations.Dialogs.WaitForCompiling;
|
||||
var targetNetworkIsReachable = string.Format(Localization.Translations.Dialogs.TargetNetworkIsReachable, networkText);
|
||||
|
||||
if (Application.internetReachability != NetworkReachability.ReachableViaLocalAreaNetwork) {
|
||||
textSuggestion.text = noWifiNetwork;
|
||||
@@ -87,7 +91,7 @@ namespace SingularityGroup.HotReload {
|
||||
textSuggestion.text = targetNetworkIsReachable;
|
||||
}
|
||||
|
||||
textSummary.text = autoConnect ? "Auto-pair encountered an issue" : "Connection failed";
|
||||
textSummary.text = autoConnect ? Localization.Translations.Dialogs.AutoPairEncounteredIssue : Localization.Translations.Dialogs.ConnectionFailed;
|
||||
|
||||
if (enableDebugging && textForDebugging) {
|
||||
textForDebugging.enabled = true;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -193,4 +192,3 @@ namespace SingularityGroup.HotReload.Interop {
|
||||
RequireSecObject = 32768, // 0x00008000
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
#pragma warning disable CS0618 // obsolete warnings (stay warning-free also in newer unity versions)
|
||||
#pragma warning disable CS0618 // obsolete warnings (stay warning-free also in newer unity versions)
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -8,6 +7,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
@@ -48,7 +48,7 @@ namespace SingularityGroup.HotReload {
|
||||
InvokeInstanceMethodStatic(patchMethod, go);
|
||||
}
|
||||
} else {
|
||||
Log.Warning($"[{nameof(InvokeOnHotReloadLocal)}] {patchMethod.DeclaringType?.Name} {patchMethod.Name} failed. Make sure it's a method with 0 parameters either static or defined on MonoBehaviour.");
|
||||
Log.Warning($"[{nameof(InvokeOnHotReloadLocal)}] {patchMethod.DeclaringType?.Name} {patchMethod.Name} {Localization.Translations.Utility.MethodCallWarning}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace SingularityGroup.HotReload {
|
||||
var reloadMethod = reloadForType?.GetMethod(attrib.methodToInvoke, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
|
||||
if (reloadMethod == null) {
|
||||
Log.Warning($"[{nameof(InvokeOnHotReloadLocal)}] failed to find method {attrib.methodToInvoke}. Make sure it exists within the same class.");
|
||||
Log.Warning($"[{nameof(InvokeOnHotReloadLocal)}] {string.Format(Localization.Translations.Utility.OnHotReloadLocalWarning, attrib.methodToInvoke)}");
|
||||
return;
|
||||
}
|
||||
if (reloadMethod.IsStatic) {
|
||||
@@ -67,7 +67,7 @@ namespace SingularityGroup.HotReload {
|
||||
InvokeInstanceMethod(reloadMethod, go, null);
|
||||
}
|
||||
} else {
|
||||
Log.Warning($"[{nameof(InvokeOnHotReloadLocal)}] {reloadMethod.DeclaringType?.Name} {reloadMethod.Name} failed. Make sure it's a method with 0 parameters either static or defined on MonoBehaviour.");
|
||||
Log.Warning($"[{nameof(InvokeOnHotReloadLocal)}] {reloadMethod.DeclaringType?.Name} {reloadMethod.Name} {Localization.Translations.Utility.MethodCallWarning}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (m.GetParameters().Length != 0) {
|
||||
Log.Warning($"[{attrName}] {m.DeclaringType?.Name} {m.Name} failed. Make sure it has 0 parameters, or 1 parameter with type List<MethodPatch>. Exception:\n{e}");
|
||||
Log.Warning($"[{attrName}] {m.DeclaringType?.Name} {m.Name} {Localization.Translations.Utility.OnHotReloadWarning}\n{e}");
|
||||
} else {
|
||||
Log.Warning($"[{attrName}] {m.DeclaringType?.Name} {m.Name} failed. Exception\n{e}");
|
||||
}
|
||||
@@ -170,9 +170,9 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (m.GetParameters().Length != 0) {
|
||||
Log.Warning($"[InvokeOnHotReload] {m.DeclaringType?.Name} {m.Name} failed. Make sure it has 0 parameters, or 1 parameter with type List<MethodPatch>. Exception:\n{e}");
|
||||
Log.Warning($"[InvokeOnHotReload] {m.DeclaringType?.Name} {m.Name} {Localization.Translations.Utility.OnHotReloadWarning}\n{e}");
|
||||
} else {
|
||||
Log.Warning($"[InvokeOnHotReload] {m.DeclaringType?.Name} {m.Name} failed. Exception:\n{e}");
|
||||
Log.Warning(string.Format(Localization.Translations.Logging.InvokeOnHotReloadFailed, m.DeclaringType?.Name, m.Name, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,13 +182,12 @@ namespace SingularityGroup.HotReload {
|
||||
m.Invoke(null, new object[] { go });
|
||||
} catch (Exception e) {
|
||||
if (m.GetParameters().Length != 0) {
|
||||
Log.Warning($"[InvokeOnHotReloadLocal] {m.DeclaringType?.Name} {m.Name} failed. Make sure it has 0 parameters. Exception:\n{e}");
|
||||
Log.Warning($"[InvokeOnHotReloadLocal] {m.DeclaringType?.Name} {m.Name} {Localization.Translations.Utility.OnHotReloadLocalCallWarning}\n{e}");
|
||||
} else {
|
||||
Log.Warning($"[InvokeOnHotReloadLocal] {m.DeclaringType?.Name} {m.Name} failed. Exception:\n{e}");
|
||||
Log.Warning(Localization.Translations.Logging.InvokeOnHotReloadLocalFailed, m.DeclaringType?.Name, m.Name, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using UnityEngine;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
@@ -8,13 +7,15 @@ namespace SingularityGroup.HotReload {
|
||||
public static bool IsAssetStoreBuild => true;
|
||||
|
||||
|
||||
public const string Version = "1.13.7";
|
||||
public const string Version = "1.13.13";
|
||||
// Never higher than Version
|
||||
// Used for the download
|
||||
public const string ServerVersion = "1.13.7";
|
||||
public const string ServerVersion = "1.13.11";
|
||||
public const string PackageName = "com.singularitygroup.hotreload";
|
||||
public const string DefaultLocale = Localization.Locale.English;
|
||||
// avoids unreachable code warnings from using const
|
||||
public static string DefaultLocaleField = DefaultLocale;
|
||||
public const string LibraryCachePath = "Library/" + PackageName;
|
||||
public const string ConfigFileName = "hot-reload-config.json";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System;
|
||||
using SingularityGroup.HotReload.Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -38,4 +37,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System.IO;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
@@ -12,4 +11,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SingularityGroup.HotReload.DTO;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
|
||||
@@ -80,14 +80,14 @@ namespace SingularityGroup.HotReload {
|
||||
var secondsSinceHealthy = TimeSinceServerHealthy().TotalSeconds;
|
||||
var reconnectTimeout = 30; // seconds
|
||||
if (secondsSinceHealthy > 2) {
|
||||
Log.Info("Hot Reload was unreachable for 5 seconds, trying to reconnect...");
|
||||
Log.Info(Localization.Translations.Common.HotReloadUnreachable);
|
||||
// feedback for the user so they know why patches are not applying
|
||||
Prompts.SetConnectionState($"{ConnectionSummary.TryingToReconnect} {reconnectTimeout - secondsSinceHealthy:F0}s", false);
|
||||
Prompts.ShowConnectionDialog();
|
||||
}
|
||||
if (secondsSinceHealthy > reconnectTimeout) {
|
||||
// give up on the server, give user a way to connect to another
|
||||
Log.Info($"Hot Reload was unreachable for {reconnectTimeout} seconds, disconnecting");
|
||||
Log.Info(string.Format(Localization.Translations.Logging.HotReloadUnreachableDisconnecting, reconnectTimeout));
|
||||
var disconnectedServer = RequestHelper.ServerInfo;
|
||||
Disconnect().Forget();
|
||||
// Let user tap button to retry connecting to the same server (maybe just need to run Hot Reload again)
|
||||
@@ -114,4 +114,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR
|
||||
#define MOBILE_ANDROID
|
||||
#endif
|
||||
@@ -18,6 +17,7 @@ using UnityEngine.Networking;
|
||||
using UnityEngine;
|
||||
using Debug = UnityEngine.Debug;
|
||||
using System.IO;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
// entrypoint for Unity Player builds. Not necessary in Unity Editor.
|
||||
@@ -42,10 +42,11 @@ namespace SingularityGroup.HotReload {
|
||||
bool onlyPrefabMissing;
|
||||
if (!IsPlayerWithHotReload(out onlyPrefabMissing)) {
|
||||
if (onlyPrefabMissing) {
|
||||
Log.Warning("Hot Reload is not available in this build because one or more build settings were not supported.");
|
||||
Log.Warning(Localization.Translations.Logging.HotReloadNotAvailableBuildSettings);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Translations.LoadDefaultLocalization();
|
||||
|
||||
TryAutoConnect().Forget();
|
||||
}
|
||||
@@ -55,14 +56,14 @@ namespace SingularityGroup.HotReload {
|
||||
buildInfo = await GetBuildInfo();
|
||||
} catch (Exception e) {
|
||||
if (e is IOException) {
|
||||
Log.Warning("Hot Reload is not available in this build because one or more build settings were not supported.");
|
||||
Log.Warning(Localization.Translations.Logging.HotReloadNotAvailableBuildSettings);
|
||||
} else {
|
||||
Log.Error($"Uknown exception happened when reading build info\n{e.GetType().Name}: {e.Message}");
|
||||
Log.Error($"{Localization.Translations.Errors.UnknownExceptionReadingBuildInfo}\n{e.GetType().Name}: {e.Message}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (buildInfo == null) {
|
||||
Log.Error($"Uknown issue happened when reading build info.");
|
||||
Log.Error(Localization.Translations.Errors.BuildInfoNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ namespace SingularityGroup.HotReload {
|
||||
public static Task TryConnectToIpAndPort(string ip, int port) {
|
||||
ip = ip.Trim();
|
||||
if (buildInfo == null) {
|
||||
throw new ArgumentException("Build info not found");
|
||||
throw new ArgumentException(Localization.Translations.Logging.BuildInfoNotFound);
|
||||
}
|
||||
buildInfo.buildMachineHostName = ip;
|
||||
buildInfo.buildMachinePort = port;
|
||||
@@ -115,7 +116,7 @@ namespace SingularityGroup.HotReload {
|
||||
PlayerCodePatcher.UpdateHost(null).Forget();
|
||||
}
|
||||
|
||||
Log.Info($"Server is healthy after first handshake? {handshakeOk}");
|
||||
Log.Info(string.Format(Localization.Translations.Logging.ServerHealthyAfterHandshake, handshakeOk));
|
||||
}
|
||||
|
||||
/// on Android, streaming assets are inside apk zip, which can only be read using unity web request
|
||||
@@ -158,4 +159,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
@@ -11,6 +10,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using SingularityGroup.HotReload.DTO;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
using SingularityGroup.HotReload.Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
@@ -45,7 +45,9 @@ namespace SingularityGroup.HotReload {
|
||||
static class RequestHelper {
|
||||
internal const ushort defaultPort = 33242;
|
||||
internal const string defaultServerHost = "127.0.0.1";
|
||||
const string ChangelogURL = "https://d2tc55zjhw51ly.cloudfront.net/releases/latest/changelog.json";
|
||||
const string ChangelogURL = PackageConst.DefaultLocale == Locale.SimplifiedChinese ?
|
||||
"https://d2tc55zjhw51ly.cloudfront.net/releases/latest/changelog-zh.json" :
|
||||
"https://d2tc55zjhw51ly.cloudfront.net/releases/latest/changelog.json";
|
||||
static readonly string defaultOrigin = Path.GetDirectoryName(UnityHelper.DataPath);
|
||||
public static string origin { get; private set; } = defaultOrigin;
|
||||
|
||||
@@ -161,7 +163,7 @@ namespace SingularityGroup.HotReload {
|
||||
//Server shut down
|
||||
await Task.Delay(5000);
|
||||
} else {
|
||||
Log.Info("PollMethodPatches failed with code {0} {1} {2}", (int)result.statusCode, result.responseText, result.exception);
|
||||
Log.Info(Localization.Translations.Logging.PollMethodPatchesFailed, (int)result.statusCode, result.responseText, result.exception);
|
||||
}
|
||||
} finally {
|
||||
pollPending = false;
|
||||
@@ -189,7 +191,7 @@ namespace SingularityGroup.HotReload {
|
||||
//Server shut down
|
||||
await Task.Delay(5000);
|
||||
} else {
|
||||
Log.Info("PollPatchStatus failed with code {0} {1} {2}", (int)result.statusCode, result.responseText, result.exception);
|
||||
Log.Info(Localization.Translations.Logging.PollPatchStatusFailed, (int)result.statusCode, result.responseText, result.exception);
|
||||
}
|
||||
} finally {
|
||||
pollPatchStatusPending = false;
|
||||
@@ -229,7 +231,7 @@ namespace SingularityGroup.HotReload {
|
||||
//Server shut down
|
||||
await Task.Delay(5000);
|
||||
} else {
|
||||
Log.Info("PollAssetChanges failed with code {0} {1} {2}", (int)result.statusCode, result.responseText, result.exception);
|
||||
Log.Info(Localization.Translations.Logging.PollAssetChangesFailed, (int)result.statusCode, result.responseText, result.exception);
|
||||
}
|
||||
} finally {
|
||||
assetPollPending = false;
|
||||
@@ -249,6 +251,19 @@ namespace SingularityGroup.HotReload {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async Task<EditorsWithoutHRResponse> RequestEditorsWithoutHRRunning(int timeoutSeconds = 30) {
|
||||
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds));
|
||||
var resp = await PostJson(CreateUrl(serverInfo) + "/editorsWithoutHR", "", timeoutSeconds, cts.Token);
|
||||
if (resp.statusCode == HttpStatusCode.OK) {
|
||||
try {
|
||||
return JsonConvert.DeserializeObject<EditorsWithoutHRResponse>(resp.responseText);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static async Task<LoginStatusResponse> RequestLogin(string email, string password, int timeoutSeconds) {
|
||||
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds));
|
||||
var json = SerializeRequestBody(new Dictionary<string, object> {
|
||||
@@ -280,10 +295,10 @@ namespace SingularityGroup.HotReload {
|
||||
try {
|
||||
return JsonConvert.DeserializeObject<LoginStatusResponse>(resp.responseText);
|
||||
} catch (Exception ex) {
|
||||
return LoginStatusResponse.FromRequestError($"Deserializing response failed with {ex.GetType().Name}: {ex.Message}");
|
||||
return LoginStatusResponse.FromRequestError(string.Format(Localization.Translations.Logging.DeserializingResponseFailed, ex.GetType().Name, ex.Message));
|
||||
}
|
||||
} else {
|
||||
return LoginStatusResponse.FromRequestError(resp.responseText ?? "Request timeout");
|
||||
return LoginStatusResponse.FromRequestError(resp.responseText ?? Localization.Translations.Logging.RequestTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,4 +457,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
internal class ServerHandshake {
|
||||
@@ -97,8 +97,8 @@ namespace SingularityGroup.HotReload {
|
||||
// handle objections in order of obviousness, most obvious goes first
|
||||
if (results.HasFlag(Result.DifferentProject)) {
|
||||
await Prompts.ShowQuestionDialog(new QuestionDialog.Config {
|
||||
summary = "Hot Reload was started from a different project",
|
||||
suggestion = "Please run Hot Reload from the matching Unity project",
|
||||
summary = Localization.Translations.Dialogs.DifferentProjectSummary,
|
||||
suggestion = Localization.Translations.Dialogs.DifferentProjectSuggestion,
|
||||
continueButtonText = "OK",
|
||||
cancelButtonText = null,
|
||||
});
|
||||
@@ -109,8 +109,8 @@ namespace SingularityGroup.HotReload {
|
||||
if (results.HasFlag(Result.DifferentCommit)) {
|
||||
Prompts.SetConnectionState(ConnectionSummary.DifferencesFound);
|
||||
bool yes = await Prompts.ShowQuestionDialog(new QuestionDialog.Config {
|
||||
summary = "Editor and current build are on different commits",
|
||||
suggestion = "This can cause errors when the build was made on an old commit.",
|
||||
summary = Localization.Translations.Dialogs.DifferentCommitSummary,
|
||||
suggestion = Localization.Translations.Dialogs.DifferentCommitSuggestion,
|
||||
continueButtonText = "Connect",
|
||||
});
|
||||
if (yes) {
|
||||
@@ -188,7 +188,7 @@ namespace SingularityGroup.HotReload {
|
||||
Log.Debug("Won't send handshake request because server is not healhy");
|
||||
return results;
|
||||
}
|
||||
Log.Info("Request handshake to Hot Reload server with hostname: {0}", info.hostName);
|
||||
Log.Info(string.Format(Localization.Translations.Logging.RequestHandshakeToServer, info.hostName));
|
||||
//Log.Debug("Handshake with projectOmissionRegex: \"{0}\"", buildInfo.projectOmissionRegex);
|
||||
var response = await RequestHelper.RequestHandshake(info, buildInfo.DefineSymbolsAsHashSet,
|
||||
buildInfo.projectOmissionRegex);
|
||||
@@ -228,10 +228,10 @@ namespace SingularityGroup.HotReload {
|
||||
|
||||
if (remoteBuildTarget == null) {
|
||||
// Should never happen. Server responsed with an error when no BuildInfo at all.
|
||||
Log.Warning("Server did not declare its current Unity activeBuildTarget in the handshake response. Will assume it is {0}.", buildInfo.activeBuildTarget);
|
||||
Log.Warning(string.Format(Localization.Translations.Errors.HandshakeFailedInvalidBuildTarget, buildInfo.activeBuildTarget));
|
||||
results |= Result.QuietWarning;
|
||||
} else if (remoteBuildTarget != buildInfo.activeBuildTarget) {
|
||||
Log.Warning("Your Unity project is running on {0}. You may need to switch it to {1} for Hot Reload to work.", remoteBuildTarget, buildInfo.activeBuildTarget);
|
||||
Log.Warning(string.Format(Localization.Translations.Errors.BuildTargetMismatch, remoteBuildTarget, buildInfo.activeBuildTarget));
|
||||
results |= Result.QuietWarning;
|
||||
}
|
||||
|
||||
@@ -242,4 +242,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -55,4 +54,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"ENABLE_MONO"
|
||||
"ENABLE_MONO",
|
||||
"DEVELOPMENT_BUILD || UNITY_EDITOR"
|
||||
],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using SingularityGroup.HotReload.DTO;
|
||||
using SingularityGroup.HotReload.RuntimeDependencies;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
internal class SymbolResolver {
|
||||
@@ -32,11 +31,11 @@ namespace SingularityGroup.HotReload {
|
||||
result = assmeblies[i].GetLoadedModules()[0].ResolveType(t.metadataToken);
|
||||
if (t.isGenericParameter) {
|
||||
if (!result.IsGenericTypeDefinition) {
|
||||
throw new SymbolResolvingFailedException(t, new ApplicationException("Generic parameter did not resolve to generic type definition"));
|
||||
throw new SymbolResolvingFailedException(t, new ApplicationException(Localization.Translations.Errors.GenericParameterNotGenericType));
|
||||
}
|
||||
var genericParameters = result.GetGenericArguments();
|
||||
if (t.genericParameterPosition >= genericParameters.Length) {
|
||||
throw new SymbolResolvingFailedException(t, new ApplicationException("Generic parameter did not exist on the generic type definition"));
|
||||
throw new SymbolResolvingFailedException(t, new ApplicationException(Localization.Translations.Errors.GenericParameterDidNotExist));
|
||||
}
|
||||
result = genericParameters[t.genericParameterPosition];
|
||||
}
|
||||
@@ -96,4 +95,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using SingularityGroup.HotReload.DTO;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
internal class SymbolResolvingFailedException : Exception {
|
||||
public SymbolResolvingFailedException(SMethod m, Exception inner)
|
||||
: base($"Unable to resolve method {m.displayName} in assembly {m.assemblyName}", inner) { }
|
||||
: base(string.Format(Localization.Translations.Errors.UnableToResolveMethodInAssembly, m.displayName, m.assemblyName), inner) { }
|
||||
|
||||
public SymbolResolvingFailedException(SType t, Exception inner)
|
||||
: base($"Unable to resolve type with name: {t.typeName} in assembly {t.assemblyName}", inner) { }
|
||||
: base(string.Format(Localization.Translations.Errors.UnableToResolveTypeInAssembly, t.typeName, t.assemblyName), inner) { }
|
||||
|
||||
public SymbolResolvingFailedException(SField t, Exception inner)
|
||||
: base($"Unable to resolve field with name: {t.fieldName} in assembly {t.assemblyName}", inner) { }
|
||||
: base(string.Format(Localization.Translations.Errors.UnableToResolveFieldInAssembly, t.fieldName, t.assemblyName), inner) { }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
internal static class TaskExtensions {
|
||||
@@ -10,7 +10,7 @@ namespace SingularityGroup.HotReload {
|
||||
try {
|
||||
await task;
|
||||
if(task.IsFaulted) {
|
||||
throw task.Exception ?? new Exception("unknown exception " + task);
|
||||
throw task.Exception ?? new Exception(Localization.Translations.Common.UnknownException + " " + task);
|
||||
}
|
||||
token.ThrowIfCancellationRequested();
|
||||
}
|
||||
@@ -45,4 +45,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using System;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
@@ -223,4 +222,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
|
||||
using UnityEngine;
|
||||
|
||||
namespace SingularityGroup.HotReload {
|
||||
@@ -39,4 +38,3 @@ namespace SingularityGroup.HotReload {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user