Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS Support #189

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

iOS Support #189

wants to merge 11 commits into from

Conversation

SakulFlee
Copy link
Owner

Fixes #107

@SakulFlee SakulFlee self-assigned this Dec 10, 2024
@SakulFlee SakulFlee linked an issue Dec 10, 2024 that may be closed by this pull request
@github-actions github-actions bot added the Godot Godot related label Dec 10, 2024
@SakulFlee SakulFlee mentioned this pull request Dec 10, 2024
@Vitorsilveira31
Copy link

Running on Godot on this branch, I encountered a few errors. Here are the details along with a video demonstrating them.

Screen.Recording.2024-12-10.at.23.19.34.mp4

Here are the errors I got

// CHAT

E 0:00:18:0466   void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver): System.InvalidOperationException: JsonTypeInfo metadata for type 'ChatMessagePacket' was not provided by TypeInfoResolver of type 'JsonSourceGenContext'. If using source generation, ensure that all root types passed to the serializer have been annotated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
  <C++ Error>    System.InvalidOperationException
  <C++ Source>   :0 @ void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver)
  <Stack Trace>  :0 @ void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver)
                 :0 @ string System.Text.Json.JsonSerializer.Serialize(object, System.Type, System.Text.Json.Serialization.JsonSerializerContext)
                 PacketSerializer.cs:24 @ string PacketSerializer.ToJSON(object)
                 ChatMessagePacket.cs:14 @ string ChatMessagePacket.ToJSON()
                 Chat.cs:34 @ void Chat.SendMessage(string)
                 Chat.cs:63 @ void Chat.OnChatTextEditChanged()
                 Chat_ScriptMethods.generated.cs:79 @ bool Chat.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&)
                 CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(nint, Godot.NativeInterop.godot_string_name*, Godot.NativeInterop.godot_variant**, int, Godot.NativeInterop.godot_variant_call_error*, Godot.NativeInterop.godot_variant*)

// GAME

E 0:00:05:0900   void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver): System.InvalidOperationException: JsonTypeInfo metadata for type 'GamePacketPlayer' was not provided by TypeInfoResolver of type 'JsonSourceGenContext'. If using source generation, ensure that all root types passed to the serializer have been annotated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
  <C++ Error>    System.InvalidOperationException
  <C++ Source>   :0 @ void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver)
  <Stack Trace>  :0 @ void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver)
                 :0 @ string System.Text.Json.JsonSerializer.Serialize(object, System.Type, System.Text.Json.Serialization.JsonSerializerContext)
                 PacketSerializer.cs:24 @ string PacketSerializer.ToJSON(object)
                 GamePacket.cs:16 @ GamePacket..ctor(GamePacketType, object)
                 Game.cs:205 @ Player Game.spawnPlayer(string, Godot.Vector2)
                 Game.cs:154 @ Player Game.spawnPlayerRandomLocation(string)
                 Game.cs:43 @ void Game+<>c__DisplayClass5_0.<_Ready>b__1(ushort)
                 WebRTCPeer_ScriptSignals.generated.cs:182 @ void WebRTCPeer.RaiseGodotClassSignalCallbacks(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs)
                 ScriptManagerBridge.cs:455 @ void Godot.Bridge.ScriptManagerBridge.RaiseEventSignal(nint, Godot.NativeInterop.godot_string_name*, Godot.NativeInterop.godot_variant**, int, Godot.NativeInterop.godot_bool*)
E 0:00:05:0937   void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver): System.InvalidOperationException: JsonTypeInfo metadata for type 'GamePacketPlayer' was not provided by TypeInfoResolver of type 'JsonSourceGenContext'. If using source generation, ensure that all root types passed to the serializer have been annotated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
  <C++ Error>    System.InvalidOperationException
  <C++ Source>   :0 @ void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver)
  <Stack Trace>  :0 @ void System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NoMetadataForType(System.Type, System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver)
                 :0 @ string System.Text.Json.JsonSerializer.Serialize(object, System.Type, System.Text.Json.Serialization.JsonSerializerContext)
                 PacketSerializer.cs:24 @ string PacketSerializer.ToJSON(object)
                 GamePacket.cs:16 @ GamePacket..ctor(GamePacketType, object)
                 Game.cs:191 @ void Game.<spawnPlayer>b__17_1(string, Godot.Vector2)
                 Player_ScriptSignals.generated.cs:55 @ void Player.RaiseGodotClassSignalCallbacks(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs)
                 ScriptManagerBridge.cs:455 @ void Godot.Bridge.ScriptManagerBridge.RaiseEventSignal(nint, Godot.NativeInterop.godot_string_name*, Godot.NativeInterop.godot_variant**, int, Godot.NativeInterop.godot_bool*)

// RPC

E 0:00:11:0043   process_simplify_path: Duplicate remote cache ID 1 for peer 1
  <C++ Error>    Condition "peers_info[p_from].recv_nodes.has(id)" is true.
  <C++ Source>   modules/multiplayer/scene_cache_interface.cpp:110 @ process_simplify_path()

@Vitorsilveira31
Copy link

Vitorsilveira31 commented Dec 11, 2024

iOS Testing:
Unfortunately, due to the bug I mentioned in this comment #107 (comment), I couldn’t properly generate the project for iOS. The build fails with a runtime error indicating that necessary files are not being found. The specific error during the build is:

MSB3030: Could not copy the file "/Users/[username]/.nuget/packages/microsoft.netcore.app.runtime.nativeaot.ios-arm64/9.0.0/runtimes/ios-arm64/native/icudt.dat" because it was not found.
/Users/[username]/.nuget/packages/godot.net.sdk/4.3.0/Sdk/iOSNativeAOT.targets(18,5)

Because of this, I had to revert the project to .NET 8.0. However, when running the project and testing the Ping Pong demo, it still doesn’t work as expected.

Screen.Recording.2024-12-11.at.00.16.46.mov

The console showed the following errors:

[MatchMaker] Own UUID: e88089d1-58d7-4a0e-92cb-9a91102f8a89
[MatchMaker] Host UUID: e88089d1-58d7-4a0e-92cb-9a91102f8a89
[MatchMaker] Is Host: False
[WebRTC] ICE Server: stun.l.google.com:19302 (NO credentials)
[WebRTC] ICE Server: stun1.l.google.com:19302 (NO credentials)
[WebRTC] ICE Server: stun2.l.google.com:19302 (NO credentials)
[WebRTC] ICE Server: stun3.l.google.com:19302 (NO credentials)
[WebRTC] ICE Server: stun4.l.google.com:19302 (NO credentials)
ERROR: System.TypeInitializationException: A type initializer threw an exception. To determine which type, inspect the InnerException's StackTrace property.
 ---> System.TypeInitializationException: A type initializer threw an exception. To determine which type, inspect the InnerException's StackTrace property.
 ---> System.NotSupportedException: 'Org.BouncyCastle.Security.DigestUtilities+DigestAlgorithm[]' is missing native code or metadata. This can happen for code that is not compatible with trimming or AOT. Inspect and fix trimming and AOT related warnings that were generated when the app was published. For more information see https://aka.ms/nativeaot-compatibility
   at System.Reflection.Runtime.General.TypeUnifier.WithVerifiedTypeHandle(RuntimeArrayTypeInfo, RuntimeTypeInfo) + 0xb0
   at System.Reflection.Runtime.General.TypeUnifier.GetArrayTypeWithTypeHandle(RuntimeTypeInfo) + 0x34
   at System.Reflection.Runtime.TypeInfos.RuntimeTypeInfo.MakeArrayType() + 0x18
   at System.Array.InternalCreate(RuntimeType, Int32, Int32*, Int32*) + 0x108
   at System.Array.CreateInstance(Type, Int32) + 0xa8
   at System.RuntimeType.GetEnumValues() + 0xdc
   at System.Enum.GetValues(Type) + 0x3c
   at Org.BouncyCastle.Utilities.Enums.GetEnumValues(Type) + 0x60
   at Org.BouncyCastle.Utilities.Enums.GetArbitraryValue(Type) + 0x24
   at Org.BouncyCastle.Security.DigestUtilities..cctor() + 0xbc
   at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0x15c
   --- End of inner exception stack trace ---
   at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0x260
   at System.Runtime.CompilerServices.ClassConstructorRunner.CheckStaticClassConstructionReturnGCStaticBase(StaticClassConstructionContext*, Object) + 0x18
   at Org.BouncyCastle.Security.DigestUtilities.GetDigest(String) + 0x3c
   at Org.BouncyCastle.Security.SecureRandom.CreatePrng(String, Boolean) + 0x2c
   at Org.BouncyCastle.Security.SecureRandom..ctor() + 0x2c
   at Org.BouncyCastle.Math.BigInteger..cctor() + 0x145c
   at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0x15c
   --- End of inner exception stack trace ---
   at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0x260
   at System.Runtime.CompilerServices.ClassConstructorRunner.CheckStaticClassConstructionReturnNonGCStaticBase(StaticClassConstructionContext*, IntPtr) + 0x18
   at Org.BouncyCastle.Math.BigInteger..ctor(Int32, Byte[]) + 0x30
   at Org.BouncyCastle.Asn1.Sec.SecNamedCurves.FromHex(String) + 0x64
   at Org.BouncyCastle.Asn1.Sec.SecNamedCurves.Secp256r1Holder.CreateParameters() + 0x34
   at Org.BouncyCastle.Asn1.X9.X9ECParametersHolder.get_Parameters() + 0x64
   at Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByOid(DerObjectIdentifier) + 0xa8
   at Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName(String) + 0x58
   at Org.BouncyCastle.Asn1.X9.ECNamedCurveTable.GetByName(String) + 0x40
   at SIPSorcery.Net.DtlsUtils.CreateSelfSignedEcdsaCert(String, String) + 0x74
   at SIPSorcery.Net.DtlsUtils.CreateSelfSignedTlsCert(String, String, AsymmetricKeyParameter, Boolean) + 0x48
   at SIPSorcery.Net.DtlsUtils.CreateSelfSignedTlsCert(Boolean) + 0x34
   at SIPSorcery.Net.RTCPeerConnection..ctor(RTCConfiguration, Int32, PortRange, Boolean) + 0x414
   at WebRTCPeer.makePeer(RTCConfiguration config) + 0x84
   at WebRTCPeer.<_Ready>d__30.MoveNext() + 0x90
--- End of stack trace from previous location ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x30
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state) + 0x28
   at Godot.GodotSynchronizationContext.ExecutePendingContinuations() + 0x4c
   at Godot.GodotTaskScheduler.Activate() + 0x30
   at WebRTC Match Maker Godot Project!<BaseAddress>+0xb03b74
at: void Godot.NativeInterop.ExceptionUtils.LogException(System.Exception) (:0)

@SakulFlee
Copy link
Owner Author

Running on Godot on this branch, I encountered a few errors. Here are the details along with a video demonstrating them.
Screen.Recording.2024-12-10.at.23.19.34.mp4

Here are the errors I got

(...)

Oh, my bad! I totally forgot to apply those changes also to the custom packages inside Demos.
PingPong should work just fine.
Will fix those in a sec :)

@SakulFlee
Copy link
Owner Author

iOS Testing (...)

This will be a problem. Org.BouncyCastle doesn't support AoT at all, and it seems unclear if they ever will, given it's targeted towards older .NET versions and aims for backwards compatibility ... thus it's unlikely they will add support for something new like AoT.

SIPSorcery, the underlying WebRTC library, depends on it.
So it's nothing we can easily change.

I am not sure if I asked this, but is AoT required for iOS to work?
Is there any way to get it done without AoT?

@SakulFlee
Copy link
Owner Author

Fixed the Game and Chat Demo.
All others should work fine.

I don't know where the RPC specific error is coming from, but it also doesn't seem to be breaking anything ... might be a Godot 4.3 issue as it didn't happen beforehand.

@Vitorsilveira31
Copy link

Tested the demos and they seem to work well! Unfortunately, AOT is a must for iOS due to platform restrictions, which are mainly in place for security reasons

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Godot Godot related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

iOS support
2 participants