Share to Facebook from Android - c#

I have problem share to facebook from android use unity C#.
When I try, when debug, it's always need user access token to share, and when share it's just share to tester and admin.
When I try on device it's just show "this application will be access to your email ..." and after that nothing happened.
This is my code:
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Facebook;
public class PTShare : MonoBehaviour {
private string lastResponse = "";
public OTSprite shareBtn;
// Use this for initialization
void Awake () {
CallFBInit ();
}
void Start () {
shareBtn = GameObject.Find ("share").GetComponent<OTSprite>();
}
// Update is called once per frame
void Update () {
if (Input.GetMouseButtonDown (0)) {
if(OT.Over(shareBtn)) {
FB.Login("email,publish_actions", LoginCallback);
CallFBFeed();
}
}
}
public static IEnumerator GetAppAccessToken() {
//Debug.Log("asking FB for App AccessToken");
string url = string.Format("https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_ id={0}&client_secret={1}",
"1443575049241638",
"efde01d85ba62e4d81708b4189419d5c");
WWW fbRequest = new WWW(url);
// Wait for download to complete
yield return fbRequest;
string accessToken = fbRequest.text;
Debug.Log("got token: " + accessToken);
accessToken = accessToken.Substring(accessToken.IndexOf("=") + 1);
Debug.Log("trimmed token: " + accessToken);
//FB.UserId = accessToken;
return true;
}
public string FeedToId = "";
public string FeedLink = "http://gambrenggames.com/game-detail/junes-potion/2";
public string FeedLinkName = "June's Potion";
public string FeedLinkCaption = "I play June's Potion friends! Can you play it?";
public string FeedLinkDescription = "";
public string FeedPicture = "http://gambrenggames.com/website/images/game-icon/05540225032014.png";
public string FeedMediaSource = "";
public string FeedActionName = "";
public string FeedActionLink = "";
public string FeedReference = "";
public bool IncludeFeedProperties = false;
private Dictionary<string, string[]> FeedProperties = new Dictionary<string, string[]>();
private void CallFBFeed()
{
Dictionary<string, string[]> feedProperties = null;
if (IncludeFeedProperties)
{
feedProperties = FeedProperties;
}
FB.Feed(
toId: FeedToId,
link: FeedLink,
linkName: FeedLinkName,
linkCaption: FeedLinkCaption,
linkDescription: FeedLinkDescription,
picture: FeedPicture,
mediaSource: FeedMediaSource,
actionName: FeedActionName,
actionLink: FeedActionLink,
reference: FeedReference,
properties: feedProperties,
callback: Callback
);
}
private Texture2D lastResponseTexture;
public string ApiQuery = "";
void Callback(FBResult result)
{
lastResponseTexture = null;
// Some platforms return the empty string instead of null.
if (!String.IsNullOrEmpty(result.Error))
lastResponse = "Error Response:\n" + result.Error;
else if (!ApiQuery.Contains("/picture"))
lastResponse = "Success Response:\n" + result.Text;
else
{
lastResponseTexture = result.Texture;
lastResponse = "Success Response:\n";
}
}
private bool isInit = false;
private void CallFBInit()
{
FB.Init(OnInitComplete, OnHideUnity);
}
private void OnInitComplete()
{
Debug.Log("FB.Init completed: Is user logged in? " + FB.IsLoggedIn);
isInit = true;
}
private void OnHideUnity(bool isGameShown)
{
Debug.Log("Is game showing? " + isGameShown);
}
private void CallFBLogin()
{
FB.Login("email,publish_actions", LoginCallback);
}
void LoginCallback(FBResult result)
{
if (result.Error != null)
lastResponse = "Error Response:\n" + result.Error;
else if (!FB.IsLoggedIn)
{
lastResponse = "Login cancelled by Player";
}
else
{
lastResponse = "Login was successful!";
}
}
private void CallFBLogout()
{
FB.Logout();
}
}

FB.Login is async method and FB.Feed (maybe?) requires Login.
So try call CallFBFeed(); inside LoginCallback method. Like that:
void Update () {
if (Input.GetMouseButtonDown (0)) {
if(OT.Over(shareBtn)) {
if (FB.IsLoggedIn)
{
CallFBFeed();
}
else
{
FB.Login("email,publish_actions", LoginCallback);
}
}
}
}
void LoginCallback(FBResult result)
{
if (result.Error != null)
lastResponse = "Error Response:\n" + result.Error;
else if (!FB.IsLoggedIn)
{
lastResponse = "Login cancelled by Player";
}
else
{
lastResponse = "Login was successful!";
CallFBFeed();
}
}
But it can be problem with android device (i had "magic" with fb login on some old devices) or settings and your code is ok

Related

I am getting 6 errors, it looks like all of them are in IEnumerators [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 months ago.
Improve this question
Here are the errors.
I am creating a firebase login and sign up unity project.
I have commented some of the lines because I havent programmed it yet. I am following this tutorial : https://www.youtube.com/watch?v=9-ZS7-I_CfQ
I have 2 scripts, firebaseManager and authUI manager.
Here is my firebaseManager script:
using UnityEngine;
using System.Collections;
using Firebase;
using Firebase.Auth;
using TMPro;
public class FirebaseManager : MonoBehaviour
{
public static FirebaseManager instance;
[Header("Firebase")]
public FirebaseAuth auth;
public FirebaseUser user;
[Space(5f)]
[Header("Login References")]
[SerializeField]
private TMP_InputField loginEmail;
[SerializeField]
private TMP_InputField loginPassword;
[SerializeField]
private TMP_Text loginOutputText;
[Space(5f)]
[Header("Register References")]
[SerializeField]
private TMP_InputField registerUsername;
[SerializeField]
private TMP_InputField registerEmail;
[SerializeField]
private TMP_InputField registerPassword;
[SerializeField]
private TMP_InputField registerConfirmPassword;
[SerializeField]
private TMP_Text registerOutputText;
private void Awake()
{
DontDestroyOnLoad(gameObject);
if (instance == null)
{
instance = this;
}
else if (instance != this)
{
Destroy(instance.gameObject);
instance = this;
}
}
private void Start()
{
StartCoroutine(CheckAndFixDependancies());
}
private IEnumerator CheckAndFixDependancies()
{
var checkAndFixDependanciesTask = FirebaseApp.CheckAndFixDependenciesAsync();
yield return new WaitUntil(predicate: () => checkAndFixDependanciesTask.IsCompleted);
var dependancyResult = checkAndFixDependanciesTask.Result;
if (dependancyResult == DependencyStatus.Available)
{
InitializeFirebase();
}
else
{
Debug.LogError($"Could not resolve all firebase dependancies: {dependancyResult}");
}
}
private void InitializeFirebase()
{
auth = FirebaseAuth.DefaultInstance;
StartCoroutine(CheckAutoLogin());
auth.StateChanged += AuthStateChanged;
AuthStateChanged(this, null);
}
private IEnumerator CheckAutoLogin()
{
yield return new WaitForEndOfFrame();
if (user != null)
{
var reloadUserTask = user.ReloadAsync();
yield return new WaitUntil(predicate: () => reloadUserTask.IsCompleted);
AutoLogin();
}
else
{
AuthUIManager.instance.LoginScreen();
}
}
private void AutoLogin()
{
if (user != null)
{
if (user.IsEmailVerified)
{
GameManager.instance.ChangeScene(1);
}
else
{
StartCoroutine(SendVerificationEmail());
}
}
else
{
AuthUIManager.instance.LoginScreen();
}
}
private void AuthStateChanged(object sender, System.EventArgs eventArgs)
{
if (auth.CurrentUser != user)
{
bool signedIn = user != auth.CurrentUser && auth.CurrentUser != null;
if (!signedIn && user != null)
{
Debug.Log("Signed Out");
// Write signed out user code here
}
user = auth.CurrentUser;
if (signedIn)
{
Debug.Log($"Signed In: {user.DisplayName}");
}
}
}
public void ClearOutputs()
{
loginOutputText.text = "";
registerOutputText.text = "";
}
public void LoginButton()
{
StartCoroutine(LoginLogic(loginEmail.text, loginPassword.text));
}
public void RegisterButton()
{
StartCoroutine(RegisterLogic(registerUsername.text, registerEmail.text, registerPassword.text, registerConfirmPassword.text));
}
private IEnumerator LoginLogic(string _email, string _password)
{
Credential credential = EmailAuthProvider.GetCredential(_email, _password);
var loginTask = auth.SignInWithCredentialAsync(credential);
yield return new WaitUntil(predicate: () => loginTask.IsCompleted);
if (loginTask.Exception != null)
{
FirebaseException firebaseException = (FirebaseException)loginTask.Exception.GetBaseException();
AuthError error = (AuthError)firebaseException.ErrorCode;
string output = "Unknown Error, Please Try Again";
switch (error)
{
case AuthError.MissingEmail:
output = "Please Enter Your Email";
break;
case AuthError.MissingPassword:
output = "Please Enter Your Password";
break;
case AuthError.InvalidEmail:
output = "Invalid Email";
break;
case AuthError.WrongPassword:
output = "Incorrect Password";
break;
case AuthError.UserNotFound:
output = "Account Does Not Exist";
break;
}
loginOutputText.text = output;
}
else
{
if (user.IsEmailVerified)
{
yield return new WaitForSeconds(1f);
GameManager.instance.ChangeScene(1);
}
else
{
StartCoroutine(SendVerificationEmail());
}
}
}
private IEnumerator RegisterLogic(string _username, string _email, string _password, string _confirmPassword)
{
if (_username == "")
{
registerOutputText.text = "Please Enter A Username";
}
else if (_password != _confirmPassword)
{
registerOutputText.text = "Passwords Do Not Match!";
}
// else if (_username.ToLower() == "bad word")
// {
// registerOutputText.text = "That Username Is Innapropriate";
// }
else
{
var registerTask = auth.CreateUserWithEmailAndPasswordAsync(_email, _password);
yield return new WaitUntil(predicate: () => registerTask.IsCompleted);
if (registerTask.Exception != null)
{
FirebaseException firebaseException = (FirebaseException)registerTask.Exception.GetBaseException();
AuthError error = (AuthError)firebaseException.ErrorCode;
string output = "Unknown Error, Please Try Again";
switch (error)
{
case AuthError.InvalidEmail:
output = "Invalid Email";
break;
case AuthError.EmailAlreadyInUse:
output = "Email Is Already In Use";
break;
case AuthError.WeakPassword:
output = "Weak Password. Please include capital letters, numbers and special symbols.";
break;
case AuthError.MissingEmail:
output = "Please Enter Your Email";
break;
case AuthError.MissingPassword:
output = "Please Enter Your Password";
break;
}
registerOutputText.text = output;
}
else
{
UserProfile profile = new UserProfile
{
DisplayName = _username,
PhotoUrl = new System.Uri("https://t4.ftcdn.net/jpg/02/29/75/83/360_F_229758328_7x8jwCwjtBMmC6rgFzLFhZoEpLobB6L8.jpg");
};
var defaultUserTask = user.UpdateUserProfileAsync(profile);
yield return new WaitUntil(predicate: () => defaultUserTask.IsCompleted);
if (defaultUserTask.Exception != null)
{
user.DeleteAsync();
FirebaseException firebaseException = (FirebaseException)defaultUserTask.Exception.GetBaseException();
AuthError error = (AuthError)firebaseException.ErrorCode;
string output = "Unknown Error, Please Try Again";
switch (error)
{
case AuthError.Cancelled:
output = "Update User Cancelled";
break;
case AuthError.SessionExpired:
output = "Session Expired";
break;
}
registerOutputText.text = output;
}
else
{
Debug.Log($"Firebase User Created Successfuly: {user.DisplayName} ({user.UserId})");
StartCoroutine(SendVerificationEmail());
}
}
}
}
private IEnumerator SendVerificationEmail()
{
if (user != null)
{
var emailTask = user.SendEmailVerificationAsync();
yield return new WaitUntil(predicate: () => emailTask.IsCompleted);
if (emailTask.Exception != null)
{
FirebaseException firebaseException = (FirebaseException)emailTask.Exception.GetBaseException();
AuthError error = (AuthError)firebaseException.ErrorCode;
string output = "Unkown Error, Try Again!";
switch (error)
{
case AuthError.Cancelled:
output = "Verification Task Was Cancelled";
break;
case AuthError.InvalidRecipientEmail:
output = "Invalid Email";
break;
case AuthError.TooManyRequests:
output = "Too Many Requests";
break;
}
AuthUIManager.instance.AwaitVerification(false, user.Email, output);
}
else
{
AuthUIManager.instance.AwaitVerification(true, user.Email, null);
Debug.Log("Email Sent Successfully");
}
}
}
public void UpdateProfilePicture(string _newPfpURL)
{
StartCoroutine(UpdateProfilePictureLogic(_newPfpURL));
}
private IEnumerator UpdateProfilePictureLogic(string _newPfpURL)
{
if (user != null)
{
UserProfile profile = new UserProfile();
try
{
UserProfile _profile = new UserProfile
{
PhotoUrl = new System.Uri(_newPfpURL),
};
profile = _profile;
}
catch
{
// LobbyManager.instance.Output("Error Fetching Image, Make Sure Your Link Is Valid!");
yield break;
}
var pfpTask = user.UpdateProfileAsync(profile);
yield return new WaitUntil(predicate: () => pfpTask.IsCompleted);
if (pfpTask.Exception != null)
{
Debug.LogError($"Updating Profile Picture was unsuccessful: {pfpTask.Exception}");
}
else
{
LobbyManager.instance.ChangePfpSuccess();
Debug.Log("Profile Image Updated Successfully");
}
}
}
}
Here is my AuthUIManager script:
using TMPro;
using UnityEngine;
public class AuthUIManager : MonoBehaviour
{
public static AuthUIManager instance;
[Header("References")]
[SerializeField]
private GameObject checkingForAccountUI;
[SerializeField]
private GameObject loginUI;
[SerializeField]
private GameObject registerUI;
[SerializeField]
private GameObject verifyEmailUI;
[SerializeField]
private TMP_Text verifyEmailText;
private void Awake()
{
if (instance == null)
{
instance = this;
}
else if (instance != this)
{
Destroy(gameObject);
}
}
private void ClearUI()
{
loginUI.SetActive(false);
registerUI.SetActive(false);
verifyEmailUI.SetActive(false);
FirebaseManager.instance.ClearOutputs();
checkingForAccountUI.SetActive(false);
}
public void LoginScreen()
{
ClearUI();
loginUI.SetActive(true);
}
public void RegisterScreen()
{
ClearUI();
registerUI.SetActive(true);
}
public void AwaitVerification(bool _emailSent, string _email, string _output)
{
ClearUI();
verifyEmailUI.SetActive(true);
if (_emailSent)
{
verifyEmailText.text = $"Sent Email!\nPleaseVerify {_email}";
}
else
{
verifyEmailText.text = $"Email Not Sent: {_output}\nPlease Verify {_email}";
}
}
}
In your FirebaseManager script you've put a semicolon ; at the end of line 264 instead of a comma ,.
Additionally you've put a desperate closed curly bracket } at the end of the file, which is not necessary.
All other errors basically originate from these two problems.

Is there a way to create a timeout to an attempt to connection with Xamarin.Forms?

I'm trying to develop a warning if I try to connect to a specific SSID and some waiting time has passed. I've tried with a Timer class but there is some issues with Task and Threads I can't resolve.
This is my Wifi class in Xamarin.Droid
public class Wifi : Iwifi
{
private Context context;
private static WifiManager _manager;
private MyReceiver _receiver;
public void Initialize()
{
context = Android.App.Application.Context;
_manager = (WifiManager)context.GetSystemService(Context.WifiService);
_receiver = new MyReceiver();
}
public void Register()
{
IntentFilter intents = new IntentFilter();
intents.AddAction(WifiManager.ScanResultAction);
intents.AddAction(WifiManager.NetworkStateChangedAction);
context.RegisterReceiver(_receiver, intents);
}
public void Unregister()
{
context.UnregisterReceiver(_receiver);
}
public void ScanWirelessDevices()
{
_manager.StartScan();
}
public string GetConnectionSSID()
{
return _manager.ConnectionInfo.SSID;
}
public void ConnectToSSID(string SSID, string pwd)
{
if (!_manager.IsWifiEnabled)
{
_manager.SetWifiEnabled(true);
}
WifiConfiguration wifiConfiguration = new WifiConfiguration();
wifiConfiguration.Ssid = '"' + SSID + '"';
if (pwd.Empty)
{
wifiConfiguration.AllowedKeyManagement.Set((int)KeyManagementType.None);
}
else
{
//Configuration for protected Network
}
var addNet = _manager.AddNetwork(wifiConfiguration);
if (addNet == -1)
{
_manager.Disconnect();
_manager.EnableNetwork(addNet, true);
_manager.Reconnect();
return;
}
var list = _manager.ConfiguredNetworks;
foreach (WifiConfiguration conf in list)
{
if (conf.Ssid.Equals('"' + SSID + '"'))
{
_manager.Disconnect();
_manager.EnableNetwork(conf.NetworkId, true);
_manager.Reconnect();
return;
}
}
}
public class MyReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action.Equals(WifiManager.ScanResultAvailableAction))
{
IList<ScanResult> scanResult = _manager.ScanResult;
App.Networks.NetworksList.Clear();
foreach (ScanResult result in scanResult)
{
App.Networks.NetworksList.Add(result.Ssid);
}
}
}
}
}
Then this is a part of App class in Xamarin.Forms
public partial class App: Application
{
private static ...
.
.
.
private static string _selectedSSID;
private static MainDetail _pageDetail;
public static IWifi WifiManager { get; } = DependencyService.Get<Iwifi>();
public static string SelectedSSID { get { return _selectedSSID; } set { _selectedSSID = value; } }
public static MainDetail PageDetail { get { return _pageDetail; } }
public App()
{
InitializeComponent();
WifiManager.Initialize();
WifiManager.Register();
InitViews();
MainPage = _mainPage;
Connectivity.ConnectivityChanged += NetworkEvents;
NetSearch();
}
.
.
.
public void NetSearch()
{
Task.Run(async () =>
{
while (true)
{
WifiManager.ScanWirelessDevices();
await Task.Delay(Utility.SCAN_WIFI_TIMER); //waiting 31000 milliseconds because of Scanning throttling
}
});
}
public void NetworkEvents(object sender, ConnectivityChangedEventArgs e)
{
MainMaster master = (MainMaster)_mainPage.Master;
if (e.NetworkAccess == NetworkAccess.Unknown)
{
Debug.WriteLine("Network Access Unknown " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.None)
{
Debug.WriteLine("Network Access None " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.Local)
{
Debug.WriteLine("Network Access Local " + e.ToString());
}
if (e.NetworkAccess == NetworkAccess.Internet)
{
if(selectedSSID == Wifimanager.GetConnectionInfo())
{
//WE CONNECTED!!
//Now I want to stop the Timeout Timer to attempt
}
}
if (e.NetworkAccess == NetworkAccess.ConstrainedInternet)
{
Debug.WriteLine("Network Access Constrainde Internet " + e.ToString());
}
}
}
And part of Detail page class in which I start the event of connection and where I want to start also the timeout timer
public partial class MainDetail : ContentPage
{
.
.
.
public void OnItemListClicked(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
ImageCell item = (ImageCell)e.SelectedItem;
App.SelectedSSID = item.Text;
App.WifiManager.ConnectToSSID(item.Text, "");
ActivityIndicator(true);
//Now the timer should start.
//And call PageDetail.ActivityIndicator(false) and warning the user if the timeout go to 0.
listView.SelectedItem = null;
}
}
I tried with the Timers Timer class but doesn't work.. any suggestion?
Ok I figured a solution! Instead of using Thread and Task, I used Device.StartTimer.
In the event on the DetailPage I wrote:
public void OnItemListClicked(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
ImageCell item = (ImageCell)e.SelectedItem;
App.SelectedSSID = item.Text;
App.WifiManager.ConnectToSSID(item.Text, "");
ActivityIndicator(true);
Device.StartTimer(TimeSpan.FromSeconds(10), () => //Waiting 10 second then if we are not connected fire the event.
{
Device.BeginInvokeOnMainThread(() =>
{
if (App.IsLogout) //variable I use to check if I can do the logout or not
{
ActivityIndicator(false);
App.SelectedSSID = "";
//My message to users "Fail to connect"
}
});
return false;
});
listView.SelectedItem = null;
}

The Contents of my String are Lost When I Pass it to Another Method as a Parameter?

I am trying to create a Regular Expression system as part of my program. When I pass emailSub (which is a String version of an InputField for the user's email) into other functions within the program, the emailSub goes from the email address (e.g: emailaddress#emailprovider.com) to null (I know this because the output of a Debug.Log before being passed is the email address and Debug.Log-ing it after passing it comes back with " ". This means that when it reaches the length check (IsEmailValid) it is less than 6 characters so all email addresses are rejected as invalid.
How can I fix this problem?
Thanks.
using System.Text.RegularExpressions;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;
using System;
public class RegEx : MonoBehaviour
{
public InputField emailField;
public Button acceptSubmissionButton;
public string emailSub;
public void Start()
{
var input = gameObject.GetComponent<InputField>();
var se = new InputField.SubmitEvent();
se.AddListener(SubmitName);
input.onEndEdit = se;
}
private void SubmitName(string arg0)
{
Debug.Log(arg0);
emailSub = arg0;
Debug.Log(emailSub);
}
public void Sequencer(string emailSub)
{
Debug.Log(emailSub);
IsEmailValid(emailSub);
Main(emailSub);
}
public static bool IsEmailValid(string emailSub)
{
if (emailSub.Length <= 6)
{
Debug.Log(emailSub + "1");
return false;
}
if (string.IsNullOrWhiteSpace(emailSub))
{
Debug.Log(emailSub + "2");
return false;
}
try
{
emailSub = Regex.Replace(emailSub, #"(#)(.+)$", DomainMapper, RegexOptions.None,
TimeSpan.FromMilliseconds(200));
string DomainMapper(Match match)
{
var idnConversion = new IdnMapping();
var processDomainName = idnConversion.GetAscii(match.Groups[2].Value);
Debug.Log(emailSub + "3");
return match.Groups[1].Value + processDomainName;
}
}
catch (RegexMatchTimeoutException e)
{
return false;
}
catch (ArgumentException e)
{
return false;
}
try
{
Debug.Log(emailSub + "4");
return Regex.IsMatch(emailSub, #"^(([0-9a-z]((\.(?!\.))(?<=[0-9a-z])#))" + #"(([0-9a-z][-0-
9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase,
TimeSpan.FromMilliseconds(250));
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
public static void Main(string emailSub)
{
if (RegEx.IsEmailValid(emailSub))
{
Debug.Log($"Valid: {emailSub}");
Debug.Log(emailSub + "5");
}
else
{
Debug.Log($"Invalid: {emailSub}");
Debug.Log(emailSub + "6");
}
}
}
The answer below was written by the person who asked the original question, but they wrote it as a replacement of the question, not in answer.
I fixed the problem, the program takes the contents of a text field and decides whether the text is in a valid email format or not. The problem was that the functions were running before the SubmitName() had updated the contents of arg0. Here is the working code:
using System.Text.RegularExpressions;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;
using System;
public class RegEx : MonoBehaviour
{
public InputField emailField;
public Button acceptSubmissionButton;
public string emailSub;
public void Start()
{
var input = gameObject.GetComponent<InputField>();
var se = new InputField.SubmitEvent();
se.AddListener(SubmitName);
input.onEndEdit = se;
}
private void SubmitName(string arg0)
{
Debug.Log(arg0);
IsEmailValid(arg0);
ValidCheck(arg0);
}
public void Sequencer(string emailSub)
{
Debug.Log(emailSub);
IsEmailValid(emailSub);
ValidCheck(emailSub);
}
public static bool IsEmailValid(string arg0)
{
if (arg0.Length <= 6)
{
return false;
}
try
{
return Regex.IsMatch(arg0, #"^(?("")("".+?(?<!\\)""#)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])#))" + #"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)); // The pattern is taken from an article written by Microsoft. https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
public static void ValidCheck(string arg0)
{
if (IsEmailValid(arg0))
{
Debug.Log($"Valid: {arg0}");
}
else
{
Debug.Log($"Invalid: {arg0}");
}
}
}

Failing to connect to steam with SteamKit2

I am making a trade offer bot in C# using SteamKit2, and most of the time it is successfully connecting to steam. But some of the time it just freezes when I have it output "Connecting to Steam..." right before client.connect(); is called. It happens often enough that it needs to be fixed, but I don't know what the problem is. Here is my code (a lot was taken from a SteamKit2 tutorial):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SteamKit2;
namespace ATO
{
class OfferSender
{
string username;
string password;
SteamClient client;
CallbackManager manager;
SteamUser user;
bool isRunning = false;
public OfferSender()
{
}
public void login()
{
Console.Write("Please enter your username: ");
username = Console.ReadLine();
Console.Write("Please enter your password: ");
password = Console.ReadLine();
client = new SteamClient();
manager = new CallbackManager(client);
user = client.GetHandler<SteamUser>();
new Callback<SteamClient.ConnectedCallback>(OnConnected, manager);
new Callback<SteamUser.LoggedOnCallback>(OnLoggedOn, manager);
isRunning = true;
Console.WriteLine("\nConnecting to Steam...\n");
client.Connect();
while(isRunning)
{
manager.RunWaitCallbacks(TimeSpan.FromSeconds(1));
}
Console.ReadKey();
}
public void OnConnected(SteamClient.ConnectedCallback callback)
{
if (callback.Result != EResult.OK)
{
Console.WriteLine("Error connecting to Steam: {0}", callback.Result);
isRunning = false;
return;
}
Console.WriteLine("Connected to steam.\nLogging in {0}...\n", username);
user.LogOn(new SteamUser.LogOnDetails {
Username = username,
Password = password
});
}
public void OnLoggedOn(SteamUser.LoggedOnCallback callback)
{
if (callback.Result == EResult.AccountLogonDenied)
{
Console.WriteLine("This account is SteamGuard protected.");
return;
}
if(callback.Result != EResult.OK)
{
Console.WriteLine("Unable to log in to steam {0}\n", callback.Result);
isRunning = false;
return;
}
Console.WriteLine("successfully logged in!");
Environment.Exit(0);
}
}
}
How do I fix this?
Well, after banging my head against the keyboard I finaly spoted that Steam would be requesting an AuthCode like any other new computer or browser login.
And that's it...
The code below handles either AuthCode and TwoFactor authentications:
https://github.com/SteamRE/SteamKit/tree/master/Samples/5.SteamGuard
You need to handle some more callbacks.
Here is how do I log into steam with my bot.
SteamBot.cs
using System;
using SteamKit2;
using System.Collections.Generic;
namespace StackOverflow
{
class SteamBot
{
CallbackManager m_CallbackManager;
SteamUser m_SteamUser;
SteamClient m_SteamClient;
SteamFriends m_SteamFriends;
SteamID m_SteamID;
Dictionary<string, string> m_Config;
public bool isLoggedOn { get; private set; }
public bool isReady { get; private set; }
public SteamBot(string pUsername, string pPassword)
{
isLoggedOn = false;
isReady = false;
m_Config = new Dictionary<string, string>();
m_Config.Add("username", pUsername);
m_Config.Add("password", pPassword);
Init();
RegisterCallbacks();
Connect();
}
private void Init()
{
m_SteamClient = new SteamClient();
m_CallbackManager = new CallbackManager(m_SteamClient);
m_SteamFriends = m_SteamClient.GetHandler<SteamFriends>();
m_SteamUser = m_SteamClient.GetHandler<SteamUser>();
}
private void RegisterCallbacks()
{
m_CallbackManager.Subscribe<SteamClient.ConnectedCallback>(OnConnected);
m_CallbackManager.Subscribe<SteamClient.DisconnectedCallback>(OnDisconnected);
m_CallbackManager.Subscribe<SteamUser.LoggedOnCallback>(OnLoggedOn);
m_CallbackManager.Subscribe<SteamUser.LoggedOffCallback>(OnLoggedOff);
m_CallbackManager.Subscribe<SteamUser.AccountInfoCallback>(OnAccountInfo);
}
public void WaitForCallbacks()
{
m_CallbackManager.RunWaitCallbacks(TimeSpan.FromSeconds(1));
}
public string GetConfigValue(string pKey)
{
return m_Config[pKey];
}
public void Connect()
{
m_SteamClient.Connect();
isReady = true;
}
void OnConnected(SteamClient.ConnectedCallback pData)
{
Console.WriteLine("Connected to Steam! Logging in '{0}'...", GetConfigValue("username"));
SteamUser.LogOnDetails details = new SteamUser.LogOnDetails
{
Username = GetConfigValue("username"),
Password = GetConfigValue("password"),
};
m_SteamUser.LogOn(details);
m_SteamID = m_SteamClient.SteamID;
}
void OnDisconnected(SteamClient.DisconnectedCallback pData)
{
m_SteamClient.Disconnect();
}
void OnLoggedOff(SteamUser.LoggedOffCallback pData)
{
isLoggedOn = false;
}
void OnLoggedOn(SteamUser.LoggedOnCallback pData)
{
if (pData.Result != EResult.OK)
{
Console.WriteLine("Unable to login to Steam: {0} / {1}", pData.Result, pData.ExtendedResult);
return;
}
Console.WriteLine("Successfully logged on!");
isLoggedOn = true;
}
void OnAccountInfo(SteamUser.AccountInfoCallback pData)
{
//Announce to all friends that we are online
m_SteamFriends.SetPersonaState(EPersonaState.Online);
}
}
}
Program.cs
namespace StackOverflow
{
class Program
{
static void Main(string[] args)
{
SteamBot bot = new SteamBot("botname", "password");
while(true)
{
if(bot.isReady)
{
bot.WaitForCallbacks();
}
}
}
}
}
You need to add Steam Directory.Initialize().Wait(); before you attempt to connect so SteamKit can update its internal list of servers, as explained here.

Unity3D - Could't invoke RPC function because the networkView doesn't exist

So, I am working on a Unity project in which I need to implement client/server functionality.
The client has its own "scene" and the server has its own scene as well. The server code and a networkView are attached to the Main Camera in their scene. The code is as follows:
using UnityEngine;
using System.Collections;
using System.Net;
using System.Collections.Generic;
public class NetworkManagerCS : MonoBehaviour {
public int loadlevel;
public int connectPort = 25000;
public string hostname;
public string GameName = "Historical Grounds";
private bool refreshing;
private HostData[] hostData;
private Dictionary<string, string> playerList = new Dictionary<string, string>();
string textToEdit = "Type text here";
// This is for debuggin purposes only!! Will be deprecated
public void OnGUI() {
if (Network.peerType == NetworkPeerType.Disconnected) {
GUILayout.Label("Connection status: Disconnected");
GUILayout.BeginVertical();
if (GUILayout.Button("Connect as client"))
{
ConnectToServer();
}
if (GUILayout.Button("Start Server"))
{
Network.InitializeServer(4, connectPort, true);
MasterServer.RegisterHost(GameName, "Tutorial Game", "This is a turn based shooter");
//Network.Instantiate(camera, transform.position, transform.rotation, 0);
}
GUILayout.EndVertical();
}
else
{
// Connecting...
if (Network.peerType == NetworkPeerType.Connecting)
{
GUILayout.Label("Connection status: Connecting");
}
// Clientside buttons
else if (Network.peerType == NetworkPeerType.Client)
{
GUILayout.Label("Connection status: Client!");
GUILayout.Label("Ping to server: " + Network.GetAveragePing(Network.connections[0]));
textToEdit = GUILayout.TextField(textToEdit, 25);
if( GUILayout.Button("Attack Server")) {
float[] args = new float[3];
args[0] = float.Parse(textToEdit);
args[1] = 4.123f;
args[2] = 23.2f;
networkView.RPC("AttackServer", RPCMode.AllBuffered, args);
}
}
// Serverside
else if (Network.peerType == NetworkPeerType.Server)
{
GUILayout.Label("Connection status: Server!");
GUILayout.Label("Hostname is:" + System.Net.Dns.GetHostName() );
GUILayout.Label("Connections: " + Network.connections.Length);
}
// Disconnect happens in both server and client
if (GUILayout.Button("Disconnect"))
{
Network.Disconnect(200);
}
}
}
// AKA While(true)
public void Update() {
/*
* If we have a "refreshing" flag, then we poll the master server
* until we get a length larger than 0. Then, we connect to server.
*/
if(refreshing) {
if (MasterServer.PollHostList().Length > 0) {
refreshing = false;
Debug.Log(MasterServer.PollHostList().Length);
hostData = MasterServer.PollHostList();
ConnectToServer();
}
}
}
/*
* If hostData does not exist, refresh
* Otherwise, connect to the first game you see.
*
* This is the "dumb" approach, but I assume that there are not going to be more
* than one game running at a time...
*/
public void ConnectToServer() {
if (hostData == null) {
MasterServer.RequestHostList(GameName);
refreshing = true;
} else {
Network.Connect(hostData[0]);
}
}
/*
* Keeping this here so that I will remember to add system info sends
*/
public void OnConnectedToServer()
{
//Application.LoadLevel(loadlevel);
}
/*
* DEBUG FUNCTION!!! This will be called when someone disconnected from
* the msater server
*/
public void OnDisconnectedFromServer(NetworkDisconnection info) {
if (info == NetworkDisconnection.LostConnection) {
if (Network.peerType == NetworkPeerType.Client) {
Debug.Log ("Client has lost connection");
} else {
Debug.Log ("Server has lost connection");
}
} else {
Debug.Log ("Disconnected Successfully");
}
}
/*
* Lawl, fail....
*/
public void OnFailedToConnect(NetworkConnectionError error)
{
Debug.LogError(error.ToString());
Network.Disconnect(400);
}
/*
* The purpose of this function is to assign a monster to a player
* Once all monsters have been assigned, I guess the Update() function will
* RPC to the phones that they are ready to play.
*/
public void OnPlayerConnected(NetworkPlayer player) {
networkView.RPC("assignPlayer", RPCMode.All, player);
}
/*
* Not interesting... Server initialized..
*/
public void OnServerInitialized()
{
//Application.LoadLevel(loadlevel);
Debug.Log("Server Started");
}
void OnMasterServerEvent(MasterServerEvent msg) {
if (msg == MasterServerEvent.RegistrationSucceeded){
Debug.Log("Registered Server!");
Network.isMessageQueueRunning = true;
}
}
/*void OnPlayerDisconnected(NetworkPlayer player) {
Transform playerTransform = GameObject.Find("Player_" + player.guid);
if (playerTransform != null) {
Destroy (playerTransform.gameObject);
}
Network.RemoveRPCs(player);
Network.DestroyPlayerObjects(player);
}*/
// Testers - Should deprecate
/*[RPC]
public void AttackServer(float[] args) {
foreach (float value in args) {
Debug.Log ("Server is under attack with force " + value);
}
}*/
// RPC's Server Side
[RPC]
public void sendLifeCount(NetworkPlayer player) {
Debug.Log("Sending Life Count to " + player.ipAddress);
}
[RPC]
public void isDead(NetworkPlayer player) {
Debug.Log("You're dead! " + player.ipAddress);
}
[RPC]
public void unlockScreen(NetworkPlayer player) {
Debug.Log("Unlocking screen for.." + player.ipAddress);
}
[RPC]
public void assignPlayer(NetworkPlayer player) {
playerList.Add(player.guid, "1");
Debug.Log(playerList[player.guid]);
Debug.Log("Player connected from: " + player.ipAddress + ":" + player.port);
Debug.Log("The player on IP " + player.ipAddress + " has been assigned the x monster");
}
public Object networkprefab { get; set; }
}
The client on the other hand, is in another scene and its code is here: (no networkView attached, due to problems...
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Text.RegularExpressions;
public center code herelass InputField : MonoBehaviour {
// Client-server bullshit
private int loadlevel;
private HostData[] hostData;
private bool refreshing;
public string GameName = "Historical Grounds";
private bool connected;
public Canvas mainCanvas;
public Canvas gameCanvas;
public Button Connect;
public Text nameFieldInput;
public Text nameField;
public Text Error;
private string userName;
void Awake()
{
if (connected)
{
mainCanvas.enabled = false;
gameCanvas.enabled = true;
}
else {
mainCanvas.enabled = true;
gameCanvas.enabled = false;
}
Debug.Log(connected);
}
public void Update()
{
/*
* If we have a "refreshing" flag, then we poll the master server
* until we get a length larger than 0. Then, we connect to server.
*/
if (refreshing)
{
if (MasterServer.PollHostList().Length > 0)
{
refreshing = false;
Debug.Log(MasterServer.PollHostList().Length);
hostData = MasterServer.PollHostList();
ConnectToServer();
}
}
}
public void onConnect()
{
ConnectToServer();
}
public void OnConnectedToServer()
{
var viewID = Network.AllocateViewID();
}
public void ConnectToServer()
{
if (hostData == null)
{
MasterServer.RequestHostList(GameName);
refreshing = true;
}
else
{
if (Switch())
{
connected = true;
Network.Connect(hostData[0]);
}
}
}
private bool Switch(){
userName = nameFieldInput.text;
Debug.Log(userName);
if(Validate(userName)){
nameField.text = userName;
mainCanvas.enabled = false;
gameCanvas.enabled = true;
connected = true;
return true;
} else {
Error.text = "Invalid name!" + "\n" + "Name should be 2-8 characters and start with a capital letter";
return false;
}
}
private bool Validate(string input){
string pattern = #"^[A-Z][A-Za-z0-9][A-Za-z0-9]+";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
return true;
}
return false;
}
public void OnDisconnectedFromServer(NetworkDisconnection info)
{
if (info == NetworkDisconnection.LostConnection)
{
if (Network.peerType == NetworkPeerType.Client)
{
Debug.Log("Client has lost connection");
}
else
{
Debug.Log("Server has lost connection");
}
}
else
{
Debug.Log("Disconnected Successfully");
}
}
public void OnFailedToConnect(NetworkConnectionError error)
{
Debug.LogError(error.ToString());
Debug.Log("FAIL!");
}
public void OnDisconnectedFromServer()
{
connected = false;
Debug.Log("Lawl Disconnected");
}
}
TL;DR: I keep getting that error message when trying to invoke an RPC ( fire() ) from the client to the server. Anyone know why?
Thanks!!

Categories

Resources