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.
Related
I have Pinger Application that gets all ping informations of servers written in the Servers.txt file
Half of them working servers, half of them not. I want to make my application write working servers to the another .txt file called WorkingServers.txt located in C:\Program Files\Servers folder
Here is my code:
using System;
using System.IO;
using System.Threading;
namespace AnchovyMultiPing
{
class Program
{
static void Main(string[] args)
{
var servers = File.ReadAllLines(#"C:\Program Files\Servers\Servers.txt");
foreach (var line in servers)
{
string currentServer = line;
if (args == null) throw new ArgumentNullException("args");
var waiter = new ManualResetEventSlim(false);
var pingData = new MultiPing(new[] { line }, waiter, 300);
waiter.Wait();
Console.WriteLine(pingData.GetPingInformation());
}
Console.WriteLine();
Console.WriteLine("- * - * - The Job is Done - * - * -");
Console.ReadLine();
}
}
}
and MultiPing.cs:
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading;
namespace AnchovyMultiPing
{
internal sealed class MultiPing : AbstractMultiPing
{
private int Timeout { get; set; }
private string[] Hosts { get; set; }
private int _count;
private ManualResetEventSlim Waiter { get; set; }
private readonly byte[] _buffer = Encoding.ASCII.GetBytes("aaa");
private Dictionary<string, long> _table = new Dictionary<string, long>();
private class Parameters
{
public String Host { get; set; }
public ManualResetEventSlim Event { get; set; }
}
public MultiPing(string[] hosts, ManualResetEventSlim waiter, int timeout = 12000)
{
Hosts = hosts;
Waiter = waiter;
Timeout = timeout;
RequestTime();
}
public override IMultiPings RequestTime()
{
try
{
_count = 0;
_table = new Dictionary<string, long>();
foreach (string host in Hosts)
{
using (var pingSender = new Ping())
{
pingSender.PingCompleted += PingCompletedCallback;
var options = new PingOptions(64, true);
try
{
pingSender.SendAsync(host, Timeout, _buffer, options,
new Parameters {Host = host, Event = Waiter});
}
catch
{
_count += 1;
if (_count == Hosts.Length)
Waiter.Set();
}
}
}
}
catch (MultiPingException ex)
{
Console.Write("RequestTime Exception");
Console.ReadKey();
}
return this;
}
//[MethodImpl(MethodImplOptions.Synchronized)] leaving this in favour of the operating system scheduler for better performance.
private void PingCompletedCallback(object sender, PingCompletedEventArgs e)
{
try
{
_count += 1;
PingReply reply = e.Reply;
if (reply != null && reply.Address != null && reply.Address.ToString() != "0.0.0.0")
{
if (_count > 0)
{
try
{
if (!_table.ContainsKey(reply.Address.ToString()))
_table.Add(((Parameters) e.UserState).Host, reply.RoundtripTime);
}
catch (NullReferenceException ex)
{
// catch null exception
throw new MultiPingException("Ping round trip time is null");
}
}
}
if (_count == Hosts.Length)
{
((Parameters) e.UserState).Event.Set();
}
if (e.Error != null)
{
Console.WriteLine("Ping failed:");
Console.WriteLine(e.Error.ToString());
((ManualResetEventSlim) e.UserState).Set();
}
}
catch (MultiPingException ex)
{
Console.Write("Exception");
Console.ReadKey();
}
}
public override String GetPingInformation()
{
var build = new StringBuilder();
foreach (string host in _table.Keys)
{
build.AppendLine(string.Format("{0} : {1}", host, _table[host]));
}
return build.ToString();
}
public override String GetIp()
{
string ip = "";
long time = -1L;
foreach (string host in _table.Keys)
{
long roundTime = _table[host];
if ((time == -1L) || (roundTime >= 0 && roundTime < time))
{
time = roundTime;
ip = host;
}
}
return ip;
}
}
}
Declare new string at the beginning var log = string.Empty; At the end of the iteration add the server name to it, if the ping is successful. I don't know how the MultiPing class looks like, so I added artificial IsSuccessful, but what I mean is something like this:
waiter.Wait();
if(pingData.IsSuccessful)
{
log += line;
}
Console.WriteLine(pingData.GetPingInformation());
Then as the last line of your program save everything to the other file.
File.AppendAllText("C:\Program Files\Servers\WorkingServers.txt", log);
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}");
}
}
}
It's a form application.
I'am using:
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Security.Principal;
This is my code:
Process NewProcess = new Process();
public Form1()
{
InitializeComponent();
NewProcess.StartInfo.UseShellExecute = false;
NewProcess.StartInfo.CreateNoWindow = true;
NewProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
}
Checks if the user is the administrator
public bool IsUserAdmin()
{
bool isAdmin;
try
{
WindowsIdentity user = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(user);
isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
}
catch(UnauthorizedAccessException)
{
isAdmin = false;
}
catch(Exception)
{
isAdmin = false;
}
return isAdmin;
}
Stop broadcasting
public void StopBroadcasting()
{
NewProcess.StartInfo.FileName = "netsh";
NewProcess.StartInfo.Arguments = "wlan Stop hostednetwork";
try
{
using (Process execute = Process.Start(NewProcess.StartInfo))
{
execute.WaitForExit();
SetLanDetails();
}
}
catch
{
}
}
Seting up lan details
public void SetLanDetails()
{
NewProcess.StartInfo.FileName = "netsh";
NewProcess.StartInfo.Arguments = "wlan set hostednetwork mode=allow ssid="+textBox1.Text+" key="+ textBox2.Text;
try
{
using (Process execute = Process.Start(NewProcess.StartInfo))
{
execute.WaitForExit();
StartBroadcasting();
}
}
catch
{
}
}
Starting broadcasting
public void StartBroadcasting()
{
NewProcess.StartInfo.FileName = "netsh";
NewProcess.StartInfo.Arguments = "wlan start hostendnetwork";
try
{
using (Process execute = Process.Start(NewProcess.StartInfo))
{
execute.WaitForExit();
buttonStart.Text = "Stop";
}
}
catch
{
}
}
Stop process
public void StopProcess()
{
NewProcess.StartInfo.FileName = "netsh";
NewProcess.StartInfo.Arguments = "wlan stop hostendnetwork";
try
{
using (Process execute = Process.Start(NewProcess.StartInfo))
{
execute.WaitForExit();
}
}
catch
{
}
}
Start button click
private void buttonStart_Click(object sender, EventArgs e)
{
if(buttonStart.Text=="Start")
{
StopBroadcasting();
buttonStart.Text = "Stop";
}
else
{
StopProcess();
buttonStart.Text = "Start";
}
}
I can't understand why it's not working. Did I forgot somthing? I didn't find a reason for this.
I am trying to create a simple steam bot with SteamKit2 and C#, but am running into issues connecting. This code will ask me for all credentials, but never do anything else after that (wont even reach the end of the program, think its stuck in the while loop)
Code (http://hastebin.com/idikidixaq.cs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SteamKit2;
using ProtoBuf;
namespace chatbot
{
class Program
{
static string user, pass;
static SteamClient steamClient;
static CallbackManager manager;
static SteamUser steamUser;
static bool running = true;
static void Main(string[] args)
{
Console.Title = "Chat Bot\n\n";
Console.Write("Enter Username: ");
user = Console.ReadLine();
Console.Write("Enter Password: ");
pass = Console.ReadLine();
SteamLogIn(user, pass);
Console.ReadKey();
}
static void SteamLogIn(string u, string p)
{
steamClient = new SteamClient();
manager = new CallbackManager(steamClient);
steamUser = steamClient.GetHandler<SteamUser>();
new Callback<SteamClient.ConnectedCallback>(onConnected, manager);
new Callback<SteamUser.LoggedOnCallback>(onLogOn, manager);
steamClient.Connect();
while (running)
{
manager.RunWaitCallbacks(TimeSpan.FromSeconds(1));
}
}
static void onConnected(SteamClient.ConnectedCallback callback)
{
if(callback.Result != EResult.OK)
{
Console.WriteLine("Error! {0}", callback.Result);
running = false;
return;
}
Console.WriteLine("Connected to Steam.\nLogging In...\n");
steamUser.LogOn(new SteamUser.LogOnDetails
{
Username = user,
Password = pass,
});
}
static void onLogOn(SteamUser.LoggedOnCallback callback)
{
Console.WriteLine(callback);
}
}
}
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