public Client(IPEndPoint _remoteEndPoint, DateTime _connectedAt, ClientStates _clientState) { this.remoteEndPoint = _remoteEndPoint; this.connectedAt = _connectedAt; this.clientState = _clientState; this.PageHistory = new Stack <Page>(); this.KeyBuffer = new Queue <Byte>(); this.CurrentCommand = ""; this.CommandState = CommandStates.RegularRouting; this.IACState = IACStates.OutsideIAC; this._random = new Random(); this._latencyBytes = new byte[100]; this._random.NextBytes(this._latencyBytes); this._latencyPacketCount = 0; this._queuedPage = null; this._queuedPageTimer = null; this._carouselPages = new List <Tuple <int, int> >(); this._carouselPages.Add(new Tuple <int, int>(91, 0)); this._carouselPages.Add(new Tuple <int, int>(91, 1)); this._carouselPages.Add(new Tuple <int, int>(150, 0)); this._carouselPages.Add(new Tuple <int, int>(666, 0)); this._carouselPages.Add(new Tuple <int, int>(999, 3)); this._carousel = new Carousel(this); this.ShowingNotices = false; this.LastNoticeReadID = -1; }
public bool ProcessInput(byte[] Chars, int Received, out Page NextPage, out byte[] SendIAC) { var sendIAC = new List <byte>(); //Page first = null; //foreach (var item in PageHistory) // first = item; //Debug.Assert(first.Routing.Count == 1); for (int i = 0; i < Received; i++) { KeyBuffer.Enqueue(Chars[i]); } NextPage = null; int count = KeyBuffer.Count; for (int i = 0; i < count; i++) { var b = KeyBuffer.Peek(); if (b == IACCommands.IAC && IACState == IACStates.OutsideIAC) { if (Options.IACEnabled) { IACState = IACStates.InsideIAC; } KeyBuffer.Dequeue(); continue; } if (b == IACCommands.IAC && IACState == IACStates.InsideIAC) { Debugger.Break(); // This is an escaped 255 KeyBuffer.Dequeue(); continue; } if (b == IACCommands.DO && IACState == IACStates.InsideIAC) { IACState = IACStates.Doing; KeyBuffer.Dequeue(); continue; } if (IACState == IACStates.Doing) { if (b == IACOptions.CUSTOM_LATENCY) { sendIAC.AddRange(_latencyBytes); KeyBuffer.Dequeue(); IACState = IACStates.OutsideIAC; if (_latencyPacketCount == 0) { _latencyStart = DateTime.Now; _latencyPacketCount++; Console.WriteLine("Starting LAT test. One LAT is 10 bytes->server + 100 bytes->client (To: " + string.Format("{0}", LogAddress) + ")"); } else { double tot = (DateTime.Now - _latencyStart).TotalMilliseconds; double avg = Math.Round(tot / _latencyPacketCount, 0); Console.WriteLine(_latencyPacketCount + " LATs in " + tot.ToString() + "ms = avg " + avg.ToString() + "ms (To: " + string.Format("{0}", LogAddress) + ")"); _latencyPacketCount++; } continue; } if (b == IACOptions.SUPPRESS_GOAHEAD) { sendIAC.Add(IACCommands.IAC); sendIAC.Add(IACCommands.WILL); sendIAC.Add(IACOptions.SUPPRESS_GOAHEAD); KeyBuffer.Dequeue(); IACState = IACStates.OutsideIAC; } else if (b == IACOptions.NEW_ENVIRON) { sendIAC.Add(IACCommands.IAC); sendIAC.Add(IACCommands.WILL); sendIAC.Add(IACOptions.NEW_ENVIRON); KeyBuffer.Dequeue(); IACState = IACStates.OutsideIAC; } else { // If it's not an option we support, we send IAC WONT <OPTION> sendIAC.Add(IACCommands.IAC); sendIAC.Add(IACCommands.WONT); sendIAC.Add(IACOptions.NEW_ENVIRON); KeyBuffer.Dequeue(); IACState = IACStates.OutsideIAC; } continue; } if (CommandState == CommandStates.InsideStarPageCommand) { if (b == '*') { CommandState = CommandStates.InsideFastTextCommand; KeyBuffer.Dequeue(); continue; } if (b >= '0' && b <= '9') { KeyBuffer.Dequeue(); CurrentCommand += Convert.ToChar(b).ToString(); //Console.WriteLine(string.Format("Inside Star Page Command, Adding {0}; CurrentCommand: '{1}' (", // b.ToString("X2"), CurrentCommand) + string.Format("{0}", LogAddress) + ")"); continue; } if (b == ENTER) { //Console.WriteLine(string.Format("Exiting Star Page Command; CurrentCommand: '{0}' (", CurrentCommand) // + string.Format("{0}", LogAddress) + ")"); KeyBuffer.Dequeue(); if (CurrentCommand == "00") // Previous page { CommandState = CommandStates.RegularRouting; CurrentCommand = ""; if (PageHistory.Count > 1) { PageHistory.Pop(); } NextPage = PageHistory.Peek(); Debug.Assert(PageHistory.Count > 0); SendIAC = sendIAC.ToArray(); return(true); } else { int pageNo; int.TryParse(CurrentCommand, out pageNo); NextPage = Page.Load(pageNo, 0, _carousel, LastSeen); if (NextPage.PageNo != pageNo) { NextPage = Page.Load(1, 0, _carousel, LastSeen); } PageHistory.Push(NextPage); CommandState = CommandStates.RegularRouting; CurrentCommand = ""; SendIAC = sendIAC.ToArray(); return(true); } } KeyBuffer.Dequeue(); CommandState = CommandStates.RegularRouting; CurrentCommand = ""; //Console.WriteLine(string.Format("Exiting Star Page Command, Invalid {0}; CurrentCommand: '{1}' (", // b.ToString("X2"), CurrentCommand) + string.Format("{0}", LogAddress) + ")"); continue; } if (CommandState == CommandStates.RegularRouting) { if (b == '*') { //Console.WriteLine(string.Format("Entering Star Page Command; CurrentCommand: '{0}' (", CurrentCommand) // + string.Format("{0}", LogAddress) + ")"); CommandState = CommandStates.InsideStarPageCommand; KeyBuffer.Dequeue(); continue; } if (ShowingNotices && b == ENTER) { var np = Notice.GetNextNotice(PageHistory.Peek(), ClientHash, ref ShowingNotices, ref LastNoticeReadID); if (np != null) { NextPage = np; PageHistory.Push(NextPage); KeyBuffer.Dequeue(); SendIAC = sendIAC.ToArray(); return(true); } } //Console.WriteLine(string.Format("Outside Commands, Processing {0} (", b.ToString("X2")) // + string.Format("{0}", LogAddress) + ")"); var route = CurrentPage.Routing.FirstOrDefault(r => r.KeyCode == b); if (route != null) { if (CurrentPage.PageType == PageTypes.TeleSoftware && route.NextPageNo != null && route.NextFrameNo != null) { NextPage = Page.Load((int)route.NextPageNo, (int)route.NextFrameNo, _carousel, LastSeen); PageHistory.Push(NextPage); KeyBuffer.Dequeue(); SendIAC = sendIAC.ToArray(); return(true); } else if (route.GoesToPageNo >= 0 && route.GoesToFrameNo >= 0 && route.GoesToFrameNo <= 25) { NextPage = Page.Load(route.GoesToPageNo, route.GoesToFrameNo, _carousel, LastSeen); PageHistory.Push(NextPage); KeyBuffer.Dequeue(); SendIAC = sendIAC.ToArray(); return(true); } KeyBuffer.Dequeue(); SendIAC = sendIAC.ToArray(); return(false); } KeyBuffer.Dequeue(); } if (CommandState == CommandStates.InsideFastTextCommand) { b = KeyBuffer.Peek(); if (b >= '0' && b <= '9') { KeyBuffer.Dequeue(); CurrentCommand += Convert.ToChar(b).ToString(); continue; } if (b == ENTER) { KeyBuffer.Dequeue(); int col; if (!int.TryParse(CurrentCommand, out col)) { col = -1; } if (col < 0 || col > 7 || PageHistory.Count == 0 || PageHistory.Peek().Routing == null) { CommandState = CommandStates.RegularRouting; CurrentCommand = ""; continue; } byte colour = Convert.ToByte(col | 0x80); foreach (var route in PageHistory.Peek().Routing) { if (route.KeyCode == colour) { if (route.GoesToPageNo >= 0 && route.GoesToFrameNo >= 0 && route.GoesToFrameNo <= 25) { NextPage = Page.Load(route.GoesToPageNo, route.GoesToFrameNo, _carousel, LastSeen); PageHistory.Push(NextPage); CommandState = CommandStates.RegularRouting; CurrentCommand = ""; SendIAC = sendIAC.ToArray(); return(true); } } } CommandState = CommandStates.RegularRouting; CurrentCommand = ""; continue; } KeyBuffer.Dequeue(); CommandState = CommandStates.RegularRouting; CurrentCommand = ""; //Console.WriteLine(string.Format("Exiting Star Page Command, Invalid {0}; CurrentCommand: '{1}' (", // b.ToString("X2"), CurrentCommand) + string.Format("{0}", LogAddress) + ")"); continue; } } SendIAC = sendIAC.ToArray(); return(false); }