/// <summary> /// Add items to the queue, /// will only add if it doesn't /// already exist /// </summary> /// <param name="item"></param> public void enqueue(T item) { lock (locker) { try { //check if the job already exists in the list by comparing the job type and targetid if (!this.data.Any(x => x.Type == item.Type && x.TargetID == item.TargetID)) { data.Add(item); int ci = data.Count - 1; // child index; start at end while (ci > 0) { int pi = (ci - 1) / 2; // parent index if (data[ci].CompareTo(data[pi]) >= 0) { break; // child item is larger than (or equal) parent so we're done } T tmp = data[ci]; data[ci] = data[pi]; data[pi] = tmp; ci = pi; } //notify(); } } catch (Exception x) { Combot.ConsoleMessage(x.Message.ToString(), ConsoleColor.Red); Combot.ConsoleMessage(x.GetType().FullName, ConsoleColor.Red); } } }
/// <summary> /// Data being received from a client /// </summary> /// <param name="cSocket">Socket of the client to receive data from</param> public static void incomingData(object cSocket) { Socket clientSocket = (Socket)cSocket; byte[] Buffer; int readBytes; for (; ;) { try { Buffer = new byte[clientSocket.SendBufferSize]; readBytes = clientSocket.Receive(Buffer); if (readBytes > 0) { Packet p = new Packet(Buffer); dataManager(p); } } catch (SocketException sx) { Combot.ConsoleMessage("{0} has disconnected: {1}", ConsoleColor.DarkGray, removeClientInfo(clientSocket).ToString(), sx.Message.ToString()); return; } } }
/// <summary> /// Method that starts listening for clients /// </summary> public static void Start() { Combot.ConsoleMessage("Starting server", ConsoleColor.DarkGray); listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _clients = new List <ClientData>(); IPEndPoint ip = new IPEndPoint(IPAddress.Parse(Packet.getIp4Address()), 1069); listenerSocket.Bind(ip); //Start listening for connections in a new thread so the application can continue Thread ListenThread = new Thread(listenThread); ListenThread.Start(); Combot.ConsoleMessage("Success, listening IP:{0}:1069", ConsoleColor.DarkGray, Packet.getIp4Address()); /* * * This an event timer that sends a * PriorityQueue Notify method every * ten seconds. * * */ System.Timers.Timer notifyTimer = new System.Timers.Timer(1000); notifyTimer.Elapsed += notifyEvent; notifyTimer.Enabled = true; }
/// <summary> /// Notifies clients of pending jobs in the queue /// </summary> public void notify() { lock (notifyLocker) { try { PurgeOld(); if (_clients.Count > 0 && data.Count > 0) { foreach (T item in data.Where(x => x.Assigned == false)) { item.Assigned = true; ClientData c; //make a list of people whose id from rejectors does not belong in the list List <ClientData> cTemp = _clients.Where(x => !item.Rejectors.Contains(x.clientId)).ToList(); if (item.Args == "spell") { c = cTemp.Where(x => !x.IsCasting).First(); c.IsCasting = true; } else { c = cTemp.Where(x => !x.IsBusy).First(); c.IsBusy = true; } Packet p = new Packet(PacketType.job, "server", item); p.Gdata.Add("server"); p.Gdata.Add(item.ToString()); /*Combot.ConsoleMessage("Status before sending packet: {0}, {1}", * ConsoleColor.DarkMagenta, c.IsBusy, c.IsCasting);*/ c.clientSocket.Send(p.toBytes()); /*Combot.ConsoleMessage("Status after sending packet: {0}, {1}", * ConsoleColor.DarkMagenta, c.IsBusy, c.IsCasting);*/ } /*Combot.ConsoleMessage("Pending jobs: {0}", * ConsoleColor.DarkGray, jobQueue.ToPost());*/ } } catch (Exception x) { Combot.ConsoleMessage(x.Message.ToString(), ConsoleColor.Red); Combot.ConsoleMessage(x.GetType().FullName, ConsoleColor.Red); } } }
/// <summary> /// Returns true if the job was removed /// </summary> /// <param name="jobID">Guid of the job to remove</param> /// <returns></returns> public void Remove(Guid jobID) { lock (locker) { try { int li = data.Count - 1; // last index (before removal) foreach (T j in data) { if (j.ID == jobID) { data.Remove(j); break; } } --li; // last index (after removal) int pi = 0; // parent index. start at front of pq while (true) { int ci = pi * 2 + 1; // left child index of parent if (ci > li) { break; // no children so done } int rc = ci + 1; // right child if (rc <= li && data[rc].CompareTo(data[ci]) < 0) // if there is a rc (ci + 1), and it is smaller than left child, use the rc instead { ci = rc; } if (data[pi].CompareTo(data[ci]) <= 0) { break; // parent is smaller than (or equal to) smallest child so done } T tmp = data[pi]; data[pi] = data[ci]; data[ci] = tmp; // swap parent and child pi = ci; } } catch (Exception x) { Combot.ConsoleMessage(x.Message.ToString(), ConsoleColor.Red); Combot.ConsoleMessage(x.GetType().FullName, ConsoleColor.Red); } } }
public static void Main(string[] args) { A: if (Stealth.Client.GetConnectedStatus()) { Combot.ConsoleMessage("Connected to Stealth UO profile", ConsoleColor.DarkGray); Routine.init(); // Run each routine in a new thread Server.Start(); // Starts server } else { Combot.ConsoleMessage("Selected profile is not online, retrying in 5 seconds", ConsoleColor.DarkGray); Thread.Sleep(5000); goto A; } }
/// <summary> /// Manages a packet sent from /// a client and does something /// based on what type of packet /// was sent /// </summary> /// <param name="p">a packet, /// caught by incomingData</param> public static void dataManager(Packet p) { try { switch (p.packetType) { case PacketType.chat: foreach (ClientData c in _clients) { c.clientSocket.Send(p.toBytes()); } break; case PacketType.job: switch (p.Gdata[1]) { case "accepted": //set job to assigned Job acceptJob = jobQueue.Find(p.packetJobID); acceptJob.Assigned = true; Combot.ConsoleMessage("{0} accepted the job", ConsoleColor.DarkGreen, p.Gdata[0]); break; case "complete": //remove the job jobQueue.Remove(p.packetJobID); Combot.ConsoleMessage("{0} completed a job", ConsoleColor.Green, p.Gdata[0]); break; case "rejected": Job rejectJob = jobQueue.Find(p.packetJobID); rejectJob.Assigned = false; ClientData rejectClient = _clients.Where(x => x.id == p.senderId).First(); var id = rejectClient.clientId; rejectJob.Rejectors.Add(id); if (rejectJob.Rejectors.Count == _clients.Count) { rejectJob.Rejectors.Clear(); } Combot.ConsoleMessage("{0} rejected the job, reason: {1}", ConsoleColor.DarkYellow, p.Gdata[0], p.Gdata[2]); break; case "add": //client wants to add a job jobQueue.enqueue(p.packetJob); break; default: //when all else fails Combot.ConsoleMessage("{0} sent a job packet I could not interpret", ConsoleColor.Yellow, p.Gdata[0]); break; } break; case PacketType.registration: foreach (ClientData c in _clients) { if (c.id == p.Gdata[0].ToString()) { c.clientName = p.Gdata[1].ToString(); c.clientId = Convert.ToUInt32(p.Gdata[2]); Combot.ConsoleMessage("{0} has connected to the server", ConsoleColor.Gray, c.clientName); } } break; case PacketType.status: switch (p.Gdata[1]) { case "IsCasting": ClientData _clientCasting = _clients.Where(x => x.id == p.senderId).First(); _clientCasting.IsCasting = p.status; /*Combot.ConsoleMessage("{0} {1} {2}", * ConsoleColor.DarkCyan, _clientCasting.clientName, p.Gdata[1], p.status);*/ break; case "IsBusy": ClientData _clientBusy = _clients.Where(x => x.id == p.senderId).First(); _clientBusy.IsBusy = p.status; /*Combot.ConsoleMessage("{0} {1} {2}", * ConsoleColor.DarkCyan, _clientBusy.clientName, p.Gdata[1], p.status);*/ break; default: break; } break; default: Combot.ConsoleMessage("{0} sent a packet I could not interpret", ConsoleColor.Yellow, p.Gdata[0]); break; } } catch (Exception x) { Combot.ConsoleMessage(x.Message.ToString(), ConsoleColor.Red); Combot.ConsoleMessage(x.GetType().FullName, ConsoleColor.Red); } }