How to get Fiddler or Charles to capture traffic from Unity 2018 IL2CPP apps - unity3d

I have built apps with Unity 5 and with Unity 2017, and am able to use Fiddler or Charles to capture network traffic successfully. However, When I build a Unity 2018 app using IL2CPP (the other apps were built with .Net), the app works (successfully sending network traffic), but the app seems to somehow bypass the Fiddler (or Charles) proxy. That is, Fiddler and Charles are unable to show the network traffic from the Unity 2018 IL2CPP app, even though it can show traffic from Unity 5 and Unity 2017 apps.
Note that everything works with Unity 5 and Unity 2017, and, that the SSL settings, etc. have been setup previously. Also, I have used the Fiddler "WinConfig" to EnableLoopback for the Unity 2018 app.
My question is: What do I need to do to get a Unity 2018 IL2CPP app to show traffic in Fiddler or Charles?
Update:
Here is some sample code that shows that HttpClient requests don't go through the proxy, but other (Unity) webrequests do go through the proxy:
public class RequestTest : MonoBehaviour
{
public UnityEngine.UI.Text text;
void Update()
{
if (Input.GetKeyUp(KeyCode.P))
{
StartCoroutine(yieldPing());
}
if (Input.GetKeyUp(KeyCode.O))
{
asyncPing();
}
}
private IEnumerator yieldPing()
{
Debug.Log("This request shows up in Fiddler");
text.text = "UWR in Coroutine";
using (UnityWebRequest uwr = UnityWebRequest.Get("https://www.google.com/"))
{
yield return uwr.SendWebRequest();
}
}
private async void asyncPing()
{
await awaitPing();
}
private async System.Threading.Tasks.Task<bool> awaitPing()
{
Debug.Log("This request also shows up in Fiddler");
UnityWebRequest uwr = UnityWebRequest.Get("https://www.google.com/");
text.text = "UWR in async await";
uwr.SendWebRequest().completed += delegate
{
uwr.Dispose();
};
Debug.Log("This request does NOT show up in Fiddler???");
text.text += "\nHttpClient in async await";
using (System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient())
{
using (System.Net.Http.HttpRequestMessage httpRequest = new System.Net.Http.HttpRequestMessage())
{
httpRequest.RequestUri = new System.Uri("http://www.youtube.com/");
httpRequest.Method = System.Net.Http.HttpMethod.Get;
using (System.Net.Http.HttpResponseMessage httpResponse = await httpClient.SendAsync(httpRequest, System.Net.Http.HttpCompletionOption.ResponseHeadersRead))
{
var responseCode = (int)httpResponse.StatusCode;
// We will get a 304 if the content has not been modified
// If there is new, good content, then we will get a 200
return (responseCode == 200);
}
}
}
}
}
Here are the Unity Player Settings:

Unity has acknowledged that this is a problem:
https://fogbugz.unity3d.com/default.asp?1222589_u6qsndet3umnp50u
https://issuetracker.unity3d.com/issues/httpclient-ignores-windows-proxy
It appears that during the "IL2CPP" code generation process, the generated code changes the HttpClient to not use the local proxy.
The code below was copied from here, and seems to overcome the Unity IL2CPP bug:
// might be overly complicated, there is an option to wrap the existing proxy here...
class myWebProxy : System.Net.IWebProxy
{
private System.Net.IWebProxy wrappedProxy;
private System.Net.ICredentials creds;
private void init()
{
wrappedProxy = null;
creds = CredentialCache.DefaultCredentials;
}
public myWebProxy()
{
init();
}
public myWebProxy(System.Net.IWebProxy theWrappedProxy)
{
init();
wrappedProxy = theWrappedProxy;
}
public System.Net.ICredentials Credentials
{
get
{
if (wrappedProxy != null)
{
return wrappedProxy.Credentials;
}
else
{
return creds;
}
}
set
{
if (wrappedProxy != null)
{
wrappedProxy.Credentials = value;
}
else
{
creds = value;
}
}
}
public Uri GetProxy(Uri destination)
{
if (wrappedProxy != null /* todo or Uri == certain Uri */)
{
return wrappedProxy.GetProxy(destination);
}
else
{
// hardcoded proxy here..
return new Uri("http://seeplusplus:8080");
}
}
public bool IsBypassed(Uri host)
{
if (wrappedProxy != null)
{
return wrappedProxy.IsBypassed(host);
}
else
{
return false;
}
}
}
// in your code use your new proxy
HttpClientHandler aHandler = new HttpClientHandler();
// use your proxy!
aHandler.Proxy = new myWebProxy();
HttpClient client = new HttpClient(aHandler);

Related

How can I reconnect a Photon Bolt client after it disconnects?

I'm trying to make a Photon Bolt game that connects two devices. The problem is that the Client tends to get disconnected a lot, an it doesn't reconnect automatically. I've tried using methods like ReconnectAndRejoin, but it seems like it only works in PUN. Right now I'm using this custom solution, without success:
[BoltGlobalBehaviour(BoltNetworkModes.Client)]
public class InitialiseGameClient : Photon.Bolt.GlobalEventListener
{
private bool disconnected;
public void Update(){
if(disconnected){
Reconnect();
}
}
public override void Disconnected(BoltConnection connection)
{
disconnected = true;
}
public void Reconnect(){
BoltLauncher.StartClient();
PlayerPrefs.DeleteAll();
if (BoltNetwork.IsRunning && BoltNetwork.IsClient)
{
foreach (var session in BoltNetwork.SessionList)
{
UdpSession udpSession = session.Value as UdpSession;
if (udpSession.Source != UdpSessionSource.Photon)
continue;
PhotonSession photonSession = udpSession as PhotonSession;
string sessionDescription = String.Format("{0} / {1} ({2})",
photonSession.Source, photonSession.HostName, photonSession.Id);
RoomProtocolToken token = photonSession.GetProtocolToken() as RoomProtocolToken;
if (token != null)
{
sessionDescription += String.Format(" :: {0}", token.ArbitraryData);
}
else
{
object value_t = -1;
object value_m = -1;
if (photonSession.Properties.ContainsKey("t"))
{
value_t = photonSession.Properties["t"];
}
if (photonSession.Properties.ContainsKey("m"))
{
value_m = photonSession.Properties["m"];
}
sessionDescription += String.Format(" :: {0}/{1}", value_t, value_m);
}
ServerConnectToken connectToken = new ServerConnectToken
{
data = "ConnectTokenData"
};
Debug.Log((int)photonSession.Properties["t"]);
var propertyID = PlayerPrefs.GetInt("PropertyID", 2);;
if((int)photonSession.Properties["t"] == propertyID){
BoltMatchmaking.JoinSession(photonSession, connectToken);
disconnected = false;
}
}
}
}
}
With this method I'm trying to use the same code used to connect the the client for the first time in the reconnect function, and keep trying until the client manages to connect. However it seems that the code never executes, even if the disconnect function gets triggered (the reconnect doesn't). Is there any Bolt integrated function that helps with reconnecting? Thanks in advance.
You need to shutdown bolt, then try reconnecting. Even if you don't get the below exception, it's just an example and you should shutdown and do BoltLauncher.StartClient() etc.
BoltException: Bolt is already running, you must call BoltLauncher.Shutdown() before starting a new instance of Bolt.

How to setting firebase remote config for unity?

lets to the point, so i want to make some configuration with my game to show Ads but I avoid to update game version too much, because of that I choose firebase remote config with this I can update setting/configuration without update the game version.
there is document for this but not very clear for newbie like me, you can check it here https://firebase.google.com/docs/remote-config/use-config-unity
I already make the script like on doc, but I don't understand how its work on show data because error string format, which is what I know on this firebase console is int format
the script like this :
public static _FirebaseRemoteConfig instance;
private void Awake()
{
instance = this;
}
Firebase.DependencyStatus dependencyStatus = Firebase.DependencyStatus.UnavailableOther;
// Use this for initialization
void Start()
{
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
InitializeFirebase();
}
else
{
Debug.LogError(
"Could not resolve all Firebase dependencies: " + dependencyStatus);
}
});
}
public void InitializeFirebase()
{
System.Collections.Generic.Dictionary<string, object> defaults =
new System.Collections.Generic.Dictionary<string, object>();
defaults.Add("config_test_string", "default local string");
defaults.Add("config_test_int", 1);
defaults.Add("config_test_float", 1.0);
defaults.Add("config_test_bool", false);
Firebase.RemoteConfig.FirebaseRemoteConfig.SetDefaults(defaults);
Debug.Log("Remote config ready!");
}
public void FetchFireBase()
{
FetchDataAsync();
}
public void ShowData()
{
Debug.Log("maxCountToShowAdmob: " +
Firebase.RemoteConfig.FirebaseRemoteConfig.GetValue("MaxCountShowIntersitialAds").LongValue);
}
// Start a fetch request.
public Task FetchDataAsync()
{
Debug.Log("Fetching data...");
System.Threading.Tasks.Task fetchTask = Firebase.RemoteConfig.FirebaseRemoteConfig.FetchAsync(
TimeSpan.Zero);
return fetchTask.ContinueWith(FetchComplete);
}
void FetchComplete(Task fetchTask)
{
if (fetchTask.IsCanceled)
{
Debug.Log("Fetch canceled.");
}
else if (fetchTask.IsFaulted)
{
Debug.Log("Fetch encountered an error.");
}
else if (fetchTask.IsCompleted)
{
Debug.Log("Fetch completed successfully!");
}
var info = Firebase.RemoteConfig.FirebaseRemoteConfig.Info;
switch (info.LastFetchStatus)
{
case Firebase.RemoteConfig.LastFetchStatus.Success:
Firebase.RemoteConfig.FirebaseRemoteConfig.ActivateFetched();
Debug.Log(String.Format("Remote data loaded and ready (last fetch time {0}).",
info.FetchTime));
break;
case Firebase.RemoteConfig.LastFetchStatus.Failure:
switch (info.LastFetchFailureReason)
{
case Firebase.RemoteConfig.FetchFailureReason.Error:
Debug.Log("Fetch failed for unknown reason");
break;
case Firebase.RemoteConfig.FetchFailureReason.Throttled:
Debug.Log("Fetch throttled until " + info.ThrottledEndTime);
break;
}
break;
case Firebase.RemoteConfig.LastFetchStatus.Pending:
Debug.Log("Latest Fetch call still pending.");
break;
}
}

Xamarin.Auth fails to complete with Trakt

I'm building an app as Trakt client using Xamarin. To authenticate users, I use Xamarin.Auth because its cross-platform. However, after the authentication succeeds, it doesn't call Completed event handler. The event is only called once I click on the Back button but it returns a null Account object and false IsAuthenticated.
I'm wondering if its because the redirect uri is invalid.
Please see my code below.
[assembly: ExportRenderer(typeof(LoginView), typeof(LoginViewRenderer))]
namespace ShowsCalendar.Droid.ViewRenderer
{
public class LoginViewRenderer : PageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
var context = Forms.Context;
var baseAddress = ConfigHelper.TraktAPIURL;
var auth = new OAuth2Authenticator(
clientId: ConfigHelper.ClientID,
redirectUrl: new Uri("urn:ietf:wg:oauth:2.0:oob"),
scope: "",
authorizeUrl: new Uri(baseAddress + "/oauth/authorize?response_type=code")
);
auth.AllowCancel = true;
auth.Completed += AuthenticateCompleted;
var intent = auth.GetUI(context);
context.StartActivity(intent);
}
private void AuthenticateCompleted(object sender, AuthenticatorCompletedEventArgs e)
{
if (!e.IsAuthenticated)
{
return;
}
App.AccessToken = e.Account.Properties["access_token"].ToString();
AccountStore.Create().Save(e.Account, "Trakt");
}
}
}

Can't login with facebook in Windows Phone App

It was working fine before but It's not working even though I haven't changed anything in my Facebook related code. It is giving this error:
App doesn't give permission to given URL : The settings of app doesn't allow one or more of the given URL's. URLs must be Website's URL or Canvas URL...
Here is my FacebookLoginPage.cs:
namespace MyApp.Pages
{
public partial class FacebookLoginPage : PhoneApplicationPage
{
private string message;
public FacebookLoginPage()
{
InitializeComponent();
message = String.Empty;
this.Loaded += FacebookLoginPage_Loaded;
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
NavigationService.GoBack();
base.OnBackKeyPress(e);
}
private async void FacebookLoginPage_Loaded(object sender, RoutedEventArgs e)
{
if (String.IsNullOrEmpty(App.AccessToken))
{
App.isAuthenticated = true;
await Authenticate();
}
}
private FacebookSession session;
private async Task Authenticate()
{
//Facebook logini kontroli eğer login olduysa AccessToken ve bilgileri çeker.
try
{
if (App.FacebookSessionClient.LoginInProgress == true && !String.IsNullOrEmpty(message))
{
App.FacebookSessionClient.LoginInProgress = false;
}
else
{
session = await App.FacebookSessionClient.LoginAsync("user_about_me,read_stream");
App.AccessToken = session.AccessToken;
App.appSettings["accessToken"] = App.AccessToken;
App.appSettings.Save();
App.FacebookId = session.FacebookId;
Dispatcher.BeginInvoke(() => NavigationService.Navigate(new Uri("/Pages/MainPage.xaml?token=" + App.AccessToken, UriKind.Relative)));
}
}
catch (InvalidOperationException)
{
message = "failed";
App.FacebookSessionClient.LoginInProgress = true;
NavigationService.GoBack();
}
}
}
}
What might be the probelm?
When I added facebook.com to Oauth part of Advanced Setting in my Facebook App, the problem solved. Thanks to the following link: Windows Phone 8 Facebook Login Given URL is not allowed by the application

Parse.com - iOS push notifications and Unity integration

I notice that Parse Unity support still doesn't provide push notification for iOS.
Has anyone implemented a Unity plugin or another solution to support iOS Push Notifications via Parse?
(Cross posted on Unity Answers.)
It's actually possible now, using a ParseObject to mock up the ParseInstallation object.
Gist here: https://gist.github.com/gfosco/a3d092651c32ba3385e6
Explanation in the Parse Google Group: https://groups.google.com/d/msg/parse-developers/ku8-r91_o6s/6ioQ9T2TP7wJ
Attach this script to a GameObject, replace the important parts with your own:
using UnityEngine;
using System.Collections;
using Parse;
public class PushBehaviorScript : MonoBehaviour {
bool tokenSent = false;
public ParseObject currentInstallation = null;
void Start () {
if (PlayerPrefs.HasKey ("currentInstallation")) {
string objId = PlayerPrefs.GetString ("currentInstallation");
currentInstallation = ParseObject.CreateWithoutData ("_Installation", objId);
}
if (currentInstallation == null) {
#if UNITY_IPHONE && !UNITY_EDITOR
NotificationServices.RegisterForRemoteNotificationTypes (RemoteNotificationType.Alert | RemoteNotificationType.Badge | RemoteNotificationType.Sound);
#endif
}
}
void FixedUpdate () {
if (!tokenSent && currentInstallation == null) {
#if UNITY_IPHONE && !UNITY_EDITOR
byte[] token = NotificationServices.deviceToken;
if(token != null) {
tokenSent = true;
string tokenString = System.BitConverter.ToString(token).Replace("-", "").ToLower();
Debug.Log ("OnTokenReived");
Debug.Log (tokenString);
ParseObject obj = new ParseObject("_Installation");
obj["deviceToken"] = tokenString;
obj["appIdentifier"] = "com.parse.unitypush";
obj["deviceType"] = "ios";
obj["timeZone"] = "UTC";
obj["appName"] = "UnityPushTest";
obj["appVersion"] = "1.0.0";
obj["parseVersion"] = "1.3.0";
obj.SaveAsync().ContinueWith(t =>
{
if (obj.ObjectId != null) {
PlayerPrefs.SetString ("currentInstallation", obj.ObjectId);
}
});
}
#endif
}
}
}
To implement iOS push with parse.com You need to get the token from apple first. Then save Current instalation
Unity does have this functionality build in now.
//push notification
bool tokenSent = false;
void RegisterForPush()
{
Debug.Log("Register for push");
tokenSent = false;
#if UNITY_IOS
UnityEngine.iOS.NotificationServices.RegisterForNotifications(NotificationType.Alert |
NotificationType.Badge |
NotificationType.Sound, true);
#endif
}
void Update () {
if (!tokenSent) {
byte[] token = UnityEngine.iOS.NotificationServices.deviceToken;
if (token != null) {
// send token to a provider
tokenSent = true;
string hexToken = "%" + System.BitConverter.ToString(token).Replace('-', '%');
#if UNITY_IOS
ParseManager.instance.RegisterForPush(hexToken);
#endif
}
}
}
And inside ParseManager (or whatever class you use to manage parse>client communication)
public void RegisterForPush(string token) {
Debug.Log("Parse updating instalation");
ParseInstallation instalation = ParseInstallation.CurrentInstallation;
instalation["deviceToken"] = token;
instalation["user"] = ParseUser.CurrentUser.ObjectId;
instalation["timeZoneOffset"] = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
instalation.SaveAsync();
}
Tested on Unity 5.1.2 and iOS 8.4