Hey I'm new to coding C# and I'm trying to code a C# IRC Bot and I want to make a GUI for it so I can send chat from the GUI but I'm having problems doing so.
First off I'm opening two things, the Console app and a winform.
This code is executed within another class:
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Here is the main code (I did not code it all):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace IRCBot
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
class IrcBot
{
// Irc server to connect
public static string SERVER = File.ReadAllText("server.txt");
// Irc server's port (6667 is default port)
private static int PORT = 6667;
// User information defined in RFC 2812 (Internet Relay Chat: Client Protocol) is sent to irc server
private static string USER = "USER LeeSharp Bot v1 * :I'm a C# IRC bot made by LeeIzaZombie";
// Bot's nickname
private static string NICK = File.ReadAllText("nickname.txt");
// Channel to join
private static string CHANNEL = File.ReadAllText("channel.txt");
// StreamWriter is declared here so that PingSender can access it
public static StreamWriter writer;
static void Main(string[] args)
{
NetworkStream stream;
TcpClient irc;
string inputLine;
StreamReader reader;
string nickname;
try
{
irc = new TcpClient(SERVER, PORT);
stream = irc.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
// Start PingSender thread
PingSender ping = new PingSender();
ping.Start();
Console.WriteLine("Connecting to " + SERVER);
Console.WriteLine("Port: " + PORT);
writer.WriteLine(USER);
writer.Flush();
Console.WriteLine("Nickname: " + NICK + ".");
writer.WriteLine("NICK " + NICK);
writer.Flush();
Console.WriteLine("Now joining " + CHANNEL);
writer.WriteLine("JOIN " + CHANNEL);
writer.Flush();
while (true)
{
while ((inputLine = reader.ReadLine()) != null)
{
if (inputLine.EndsWith("JOIN :" + CHANNEL))
{
nickname = inputLine.Substring(1, inputLine.IndexOf("!") - 1);
writer.WriteLine("PRIVMSG " + CHANNEL + " :" + "Hi " + nickname +
" and welcome to " + CHANNEL + " !");
writer.Flush();
// Sleep to prevent flooding :P
Thread.Sleep(2000);
}
if (inputLine.Contains(" is no longer AFK"))
{
writer.WriteLine("PRIVMSG " + CHANNEL + " :Welcome back! :D");
writer.Flush();
// Sleep to prevent excess flood
Thread.Sleep(2000);
}
if (inputLine.Contains("leebot go away"))
{
nickname = inputLine.Substring(1, inputLine.IndexOf("!") - 1);
if (nickname == "LeeIzaZombie")
{
writer.WriteLine("QUIT");
writer.Flush();
}
// Sleep to prevent excess flood
Thread.Sleep(2000);
}
/* if (inputLine.EndsWith(" joined the game."))
{
nickname = inputLine.Substring(1, inputLine.IndexOf(" joined") - 1);
nickname2 = nickname.Substring(1, nickname.IndexOf("PRIVMSG") - 1);
writer.WriteLine("PRIVMSG " + CHANNEL + " :Hey, " + nickname2 + " welcome to $server!");
writer.Flush();
// Sleep to prevent excess flood
Thread.Sleep(2000);
}*/
if (inputLine.Contains("Hey LeeBot"))
{
writer.WriteLine("PRIVMSG " + CHANNEL + " :Hey, what up?");
writer.Flush();
// Sleep to prevent excess flood
Thread.Sleep(2000);
}
Thread.Sleep(5);
if (inputLine.EndsWith("JOIN :" + CHANNEL))
{
nickname = inputLine.Substring(1, inputLine.IndexOf("!") - 1);
inputLine = nickname + " joined " + CHANNEL;
}
Console.WriteLine(inputLine);
}
// Close all streams
writer.Close();
reader.Close();
irc.Close();
}
}
catch (Exception e)
{
// Show the exception, sleep for a while and try to establish a new connection to irc server
Console.WriteLine(e.ToString());
Thread.Sleep(5000);
string[] argv = { };
Main(argv);
}
}
}
}
What I've tried to do was make a button in the Form and a Textbox and I wanted to make the button add the text into the writer in the IrcBot class like:
writer.WriteLine("PRIVMSG " + CHANNEL + " :" + textbox.Text);
writer.Flush();
But I can't get the variable "CHANNEL" from the Form, but I manualy changed it to test the writer and the writer did not work.
Basicaly I want the Form to use the console's writer, and I have no idea how to do it.
You can't access it because it's private. Change it to public and you should be able to access it from your Form1 class.
As CHANNEL is static you should access it with the class name, like this:
IrcBot.writer.WriteLine("PRIVMSG " + IrcBot.CHANNEL + " :" + textbox.Text);
IrcBot.writer.Flush();
Related
I need to develop an application that is able to put out some commands after connecting to an ip with Telnet, and then just logs the ongoing responds;
So I have tried package like PrimS.Telnet and Minimalistic.Telnet; The thing is it works with other telnet servers, but not with this one; All I get are echo's in uppercases:
While when I use Putty (which I can't automate) it does give the right respond:
I have to press one enter first before getting that weird glitch character away
Is this something normal? Am I missing something here why I can't use my C# application with this server?
edit 1: I already found out that my C# does not support some telnet commands that would ask not to echo text back (see Telnet Commands). So my question is how to I parse those telnet commands so I can send them?
Ok small example for you. Method AskReceive sends a command and waits 200 mileseconds for the answer. It uses Stream to send and receive. If you send clearTextWriter.WriteLine(commandline) you are sending a string command to your device.
using System;
using System.IO;
using System.Net.Sockets;
namespace CommonCore.Classes.Helper
{
class TelnetDevice01
{
static int connectionTimeout = 1300;
string AskReceive(string commandline, ref string _log)
{
_log += "> " + commandline + Environment.NewLine;
clearTextWriter.WriteLine(commandline);
string _str;
System.Threading.Thread.Sleep(200);
_str = clearTextReader.ReadLine();
_log += "< " + _str + Environment.NewLine;
return _str;
}
void ExitError(string str, ref string _log, ref string _error)
{
_error = str;
_log += "!! Error : " + str + Environment.NewLine + Environment.NewLine;
clearTextWriter.WriteLine("QUIT");
}
StreamReader clearTextReader = null;
StreamWriter clearTextWriter = null;
public void ConnectTelnet(string login, string password, string server, int port,
out string log, out string resume, out string error
)
{
string _response = "";
resume = "";
error = "";
log = "";
TcpClient client = new TcpClient();
//Make the connection with timeout
if (!client.ConnectAsync(server, port).Wait(connectionTimeout))
{
//log = ex.ExceptionToString();
error = $"Could not connect '{server}' at port '{port}'";
log += Environment.NewLine + error + Environment.NewLine;
resume = Environment.NewLine + $"[FAIL] Port={port}. Could not connect '{server}' at port '{port}'" + Environment.NewLine;
return;
}
using (client)
{
using (NetworkStream stream = client.GetStream())
using (clearTextReader = new StreamReader(stream))
using (clearTextWriter = new StreamWriter(stream) { AutoFlush = true })
{
log += Environment.NewLine + Environment.NewLine + "## Connected" + Environment.NewLine;
//Read the start response line like "User:" ?'
string connectResponse = clearTextReader.ReadLine();
log += "< " + connectResponse + Environment.NewLine;
if (!connectResponse.StartsWith("login"))
{
ExitError(_response, ref log, ref error);
resume = Environment.NewLine + $"Expecting 'login'";
return;
}
//Send login
if (!(_response = AskReceive(login, ref log)).StartsWith("password"))
{
ExitError(_response, ref log, ref error);
resume = Environment.NewLine + $"Asnswer should have been 'password'";
return;
}
// Is asking for password, let's send the pass now
if (!(_response = AskReceive(password, ref log)).StartsWith("Login OK"))
{
ExitError(_response, ref log, ref error);
resume = Environment.NewLine + $"Answer should have been 'Login OK'";
return;
}
//Send CMD SMDR
_response = AskReceive($"SMDR", ref log);
//Check if the answer is what you want
// like _response.Contains("blabla")
}
}
}
}
}
I have a client and a server application and want to send serialized small objects from the client to the server via a Named Pipe. It works very well, apart from the very first transfer: It takes up to two seconds every time after i started the applications. Following transfers are almost instant.
Here is my Server Code:
class PipeServer
{
public static string PipeName = #"OrderPipe";
public static async Task<Order> Listen()
{
using (NamedPipeServerStream pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
{
await Task.Factory.FromAsync(pipeServer.BeginWaitForConnection, pipeServer.EndWaitForConnection, null);
using (StreamReader reader = new StreamReader(pipeServer))
{
string text = await reader.ReadToEndAsync();
var order = JsonConvert.DeserializeObject<Order>(text);
Console.WriteLine(DateTime.Now + ": Order recieved from Client: " + order.Zertifikat.Wkn + " with price " + order.PriceItem.Price + " with time " + order.PriceItem.Time);
return order;
}
}
}
}
And here is the client:
class PipeClient
{
public static string PipeName = #"OrderPipe";
private static async Task SendAwait(Order order, int timeOut = 10)
{
using (NamedPipeClientStream pipeStream = new NamedPipeClientStream(".", PipeName, PipeDirection.Out, PipeOptions.Asynchronous))
{
pipeStream.Connect(timeOut);
Console.WriteLine(DateTime.Now + ": Pipe connection to Trader established.");
using (StreamWriter sw = new StreamWriter(pipeStream))
{
string orderSerialized = JsonConvert.SerializeObject(order);
await sw.WriteAsync(orderSerialized);
Console.WriteLine(DateTime.Now + ": Order sent.");
// flush
await pipeStream.FlushAsync();
}
}
}
public static async void SendOrder(Order order)
{
try
{
await SendAwait(order);
}
catch (TimeoutException)
{
Console.WriteLine("Order was not sent because Server could not be reached.");
}
catch (IOException e)
{
Console.WriteLine("Order was not sent because an Exception occured: " + e.Message);
}
}
}
The data being transfered is kind of a stock exchange order which is also highly time sensitive, so for me it is crucial that also the very first order works without delay.
Is there any other way to make also the first usage of the named pipe as fast as the other ones? Some sort of precompiling?
I really want to avoid additional threads checking if the connection can be established and sending dummy data every x seconds just to "warm up" the respective objects which cause the delay.
(BTW: Code is not from me, I got it from here!)
I am trying to make a server that will accept clients, and will communicate with them until they say "exit".
the problem is, after 5-8 clients, the server decides that he don't want to accept any more clients, and when a client is connected.. I simply don't see a "client connected : 123.242.123.13:92313" in the console.
anyone knows the problem?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace GatherServer
{
class Program
{
public static int connections = 0, team1 = 0, team2 = 0, playing = 12;
public static string lbleader = "";
public static bool isleader = false;
static TcpListener myList = new TcpListener(IPAddress.Any, 7846);
static void Listeners()
{
string charname = "";
bool inque = false;
Socket socketForClient = myList.AcceptSocket();
if(socketForClient.Connected)
{
Console.WriteLine("Client Connected: " + socketForClient.RemoteEndPoint);
NetworkStream networkStream = new NetworkStream(socketForClient);
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream);
while (true)
{
string newString = streamReader.ReadLine();
if (newString.Contains("#") && inque == false)
{
if (newString.Contains("Leader"))
{
newString = newString.Replace("Leader","");
if (!isleader)
{
isleader = true;
lbleader = newString;
charname = lbleader;
Console.WriteLine(lbleader + " is the gather leader");
}
}
inque = true;
charname = newString;
connections++;
Console.WriteLine("connections: " + connections + " | from: "+charname);
}
if (newString == "exit")
{
if (charname == lbleader)
{
isleader = false;
Console.WriteLine(lbleader + " Left, there is not active leader");
}
else
Console.WriteLine(charname + " has left the game: "+socketForClient.RemoteEndPoint);
if (inque == true)
connections--;
break;
}
else
{
streamWriter.WriteLine(connections.ToString());
streamWriter.Flush();
if (connections == 12)
{
if (!isleader)
{
lbleader = charname;
Console.WriteLine(lbleader + " is the gather leader");
isleader = true;
}
Random rnd = new Random();
int team = rnd.Next(1, 3); // creates a number between 1 and 2
if(team == 1)
{
if (team1 < 6)
{
team1++;
Console.WriteLine(newString + " " + socketForClient.RemoteEndPoint + " assigned to Team 1");
streamWriter.WriteLine("team1"+lbleader);
streamWriter.Flush();
inque = false;
playing--;
break;
}
else
{
Console.WriteLine(newString + " " + socketForClient.RemoteEndPoint + " assigned to Team 2");
team2++;
streamWriter.WriteLine("team2" + lbleader);
streamWriter.Flush();
inque = false;
playing--;
break;
}
}
if(team == 2)
{
if (team2 < 6)
{
Console.WriteLine(newString + " " + socketForClient.RemoteEndPoint + " assigned to Team 2");
team2++;
streamWriter.WriteLine("team2" + lbleader);
streamWriter.Flush();
inque = false;
playing--;
break;
}
else
{
Console.WriteLine(newString + " " + socketForClient.RemoteEndPoint + " assigned to Team 1");
team1++;
streamWriter.WriteLine("team1" + lbleader);
streamWriter.Flush();
inque = false;
playing--;
break;
}
}
}
}
}
if (playing == 0)
{
connections = playing;
playing = 12;
lbleader = null;
isleader = false;
}
Console.WriteLine("playing:" + playing);
Console.WriteLine("connections: " + connections);
inque = false;
streamWriter.Close();
streamReader.Close();
networkStream.Close();
socketForClient.Close();
}
}
static void Main(string[] args)
{
myList.Start();
Console.WriteLine("Sever is up and running...");
for(int i=0; i<1000;i++)
{
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
}
}
}
}
Basically, what I want to do is to give each client a thread of its own. but after 5-8 connections, the server Socket socketForClient = myList.AcceptSocket(); not working, I think its because I am running out of threads.. but I have no clue why, there should be 1000 threads open when only 5 to 8 connections are made.
please help!
Found out what was the problem, I was highlighting some stuff in the server console, which caused the server to pause.
I am running Console_Application-A in which I am calling another Console_Application-B (in which I am creating log file for Error/Exception).
But when I am running Console_Application-B individually its working properly but when I am running Console_Application-A at that time I am getting an Exception when Application need to write an Error in log file.(Error.txt).
IOException: The process cannot access the file 'Error.txt' because it
is being used by another process
please guide me in this issue.
Code for Writing Error log
public static bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
catch (Exception e)
{
string filePath =Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Error.txt";
FileInfo FInfo = new FileInfo(filePath);
var FileState = IsFileLocked(FInfo);
while (FileState){
FileState = IsFileLocked(FInfo);
}
if (!FileState){
using (StreamWriter writer = new StreamWriter(filePath, true))
{
writer.WriteLine("Message :" + e.Message + "<br/>" + Environment.NewLine + "StackTrace :" + e.StackTrace +"" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
writer.Dispose();
}
}
}
There is no need first to check if the file is locked and then access it, as between the check and the access some other process may still get a lock on the file.
using System;
using System.IO;
class DirAppend
{
public static void Main()
{
using (StreamWriter w = File.AppendText("log.txt"))
{
Log("Test1", w);
Log("Test2", w);
}
using (StreamReader r = File.OpenText("log.txt"))
{
DumpLog(r);
}
}
public static void Log(string logMessage, TextWriter w)
{
w.Write("\r\nLog Entry : ");
w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(),
DateTime.Now.ToLongDateString());
w.WriteLine(" :");
w.WriteLine(" :{0}", logMessage);
w.WriteLine ("-------------------------------");
}
public static void DumpLog(StreamReader r)
{
string line;
while ((line = r.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
Source - https://msdn.microsoft.com/en-us/library/3zc0w663(v=vs.110).aspx
I'm programming a video player in C# (the video works fine) and what I need now is to get the libvlc logs as well as my custom logs to print them in a file.
I use NLog which handles the libvlc logs (with nVLC) and I raise an event for my custom logs, and in buth cases this function is called :
private static void tracerlogs(string erreur, VLCControl.ControleUtilisateurVLC.LogLevels LvLog)
{
string path = "logs.txt";//Sera redéfini dans l'appli
if (!File.Exists(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine(erreur + " " + LvLog.ToString());
sw.Close();
}
}
else
{
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(erreur + " " + LvLog.ToString());
sw.Close();
}
}
Console.WriteLine(erreur + " " + LvLog.ToString());
}
The problem is that I'm getting at random times a System.IO.IOException telling that "the process cannot access the file because it is being used by another process". Although I do close my StreamWriter (which should normally not be useful in a using block)... This makes my app crash. Does anyone have any idea why it does this ?
I finally solved it by adding a resource : as there was a conflict between different threads trying to access this function, I wrapped this :
private static void tracerlogs(string erreur, VLCControl.ControleUtilisateurVLC.LogLevels LvLog)
{
lock (LockLog) {
string path = "logs.txt";//Sera redéfini dans l'appli
if (!File.Exists(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine(erreur + " " + LvLog.ToString());
sw.Close();
}
}
else
{
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(erreur + " " + LvLog.ToString());
sw.Close();
}
}
Console.WriteLine(erreur + " " + LvLog.ToString());
}
}
And I declare a public static readonly object LockLog = new Object(); in my class. This works just fine ! Thanks to those who told me that this had to see with threading.