Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Net.Sockets;
- namespace SimpleChat
- {
- class Listener
- {
- private Socket mListener;
- public int Port { get; set; }
- public bool Listening { get; set; }
- public List<Client> Connections = new List<Client>();
- public Listener(ushort pPort)
- {
- try
- {
- Port = pPort;
- mListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- mListener.Bind(new IPEndPoint(IPAddress.Any, Port));
- mListener.Listen(10);
- mListener.BeginAccept(new AsyncCallback(OnConnect), mListener);
- Listening = true;
- Log.WriteLine(ELogLevel.Info, "Server started at [{0}]", Port);
- }
- catch (SocketException ex)
- {
- Log.WriteLine(ELogLevel.Exception, ex.Message);
- Listening = false;
- }
- }
- private void OnConnect(IAsyncResult ar)
- {
- if (!Listening) return;
- try
- {
- Socket lSock = mListener.EndAccept(ar);
- Client nClient = new Client(lSock);
- nClient.OnDisconnect += new Client.DPassClient(nClient_OnDisconnect);
- nClient.OnPacketReceived += new Client.DPassPacket(nClient_OnPacketReceived);
- Log.WriteLine(ELogLevel.Info, "Client connected: {0}", nClient.Host);
- AddConnection(nClient);
- nClient.SendPacket(PacketCreator.ChannelList());
- }
- catch (SocketException ex)
- {
- Log.WriteLine(ELogLevel.Exception, ex.Message);
- }
- finally
- {
- mListener.BeginAccept(new AsyncCallback(OnConnect), mListener); //start listening again
- }
- }
- void nClient_OnPacketReceived(Client pClient, Packet pPacket)
- {
- switch (pPacket.Opcode)
- {
- default:
- Console.WriteLine("Unhandled packet {0} : {1}", pPacket.Opcode, HexTools.ToStringFromAscii(pPacket.InnerBuffer));
- break;
- case 1: //authenciate
- OnAuthenciateRequest(pClient, pPacket);
- break;
- case 2: //joined channel
- OnChannelJoined(pClient, pPacket);
- break;
- case 3:
- OnChannelChat(pClient, pPacket);
- break;
- }
- }
- void OnChannelChat(Client pClient, Packet pPacket)
- {
- if (pClient.User == null) return;
- byte id = 0;
- string message = "";
- if (!pPacket.ReadByte(out id) ||
- !pPacket.ReadString(out message))
- {
- Log.WriteLine(ELogLevel.Warn, "Could not read channelchat message from {0}", pClient.User.Username);
- return;
- }
- if (message.StartsWith("/"))
- {
- //command
- HandleUserCommand(pClient, message.Substring(1, message.Length - 1));
- return;
- }
- //TODO: filter?
- if (id > Program.Channels.Count) return; //invalid channel id
- Channel chan = Program.Channels.Find(d => d.ID == id);
- if (chan == null) return;
- Packet chat = PacketCreator.ChannelChat(id, pClient.User.Nick, message);
- foreach (User user in chan.Users)
- {
- user.mClient.SendPacket(chat);
- }
- }
- void HandleUserCommand(Client pClient, string pCommand)
- {
- if (pClient.User == null) return;
- string[] command = pCommand.Split(' ');
- switch (command[0].ToLower())
- {
- default:
- Console.WriteLine("Invalid command used {0}", command[0]);
- break;
- case "nick":
- if (command.Length < 2) return;
- //todo: duplicate nicks!
- string oldnick = pClient.User.Nick;
- pClient.User.Nick = command[1];
- foreach (Channel chan in pClient.User.Channels)
- {
- Packet newnick = PacketCreator.ChannelInfo(chan.ID, oldnick + " is now known as " + command[1], 1);
- Packet userlist = PacketCreator.UserList(chan.ID, chan.Users);
- foreach (User chanuser in chan.Users)
- {
- chanuser.mClient.SendPacket(newnick);
- chanuser.mClient.SendPacket(userlist);
- }
- }
- break;
- }
- }
- void OnAuthenciateRequest(Client pClient, Packet pPacket)
- {
- string username = "";
- string password = "";
- if (!pPacket.ReadString(out username) ||
- !pPacket.ReadString(out password))
- {
- Log.WriteLine(ELogLevel.Warn, "Someone messed with authenciation");
- pClient.Disconnect();
- }
- //TODO: authenciate correctly
- User mUser = new User();
- mUser.Username = username;
- mUser.Nick = username;
- pClient.SetUser(mUser);
- }
- void OnChannelJoined(Client pClient, Packet pPacket)
- {
- if (pClient.User == null) return;
- byte ID = 0xff;
- if (!pPacket.ReadByte(out ID))
- {
- Log.WriteLine(ELogLevel.Warn, "Could not read joining channel ID");
- return;
- }
- if(ID > Program.Channels.Count){
- Log.WriteLine(ELogLevel.Warn, "Player joined channel out of range");
- return;
- }
- Channel joined = Program.Channels[ID];
- joined.AddUser(pClient.User);
- Log.WriteLine(ELogLevel.Debug, "Client joined {0}", joined.Name);
- }
- void nClient_OnDisconnect(Client pClient)
- {
- RemoveConnection(pClient);
- if (pClient.User != null)
- {
- if (pClient.User.Channels.Count > 0)
- pClient.User.Channels.ForEach(d => d.RemoveUser(pClient.User));
- }
- Log.WriteLine(ELogLevel.Info, "Client disconnected {0}", pClient.Host);
- }
- public void RemoveConnection(Client pCon)
- {
- lock (Connections)
- {
- Connections.Remove(pCon);
- }
- }
- public void AddConnection(Client pCon)
- {
- lock (Connections)
- {
- Connections.Add(pCon);
- }
- }
- public bool Stop()
- {
- if (!Listening) return true;
- try
- {
- mListener.Close();
- return true;
- }
- catch (SocketException ex)
- {
- Log.WriteLine(ELogLevel.Exception, ex.Message);
- return false;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement