public static INxtpRequest Create(Client Client, byte Version, byte[] Data, int DataSize) { foreach (Type type in GetTypes()) { INxtpRequest creator = null; INxtpRequest request = null; try { creator = (INxtpRequest)Activator.CreateInstance(type); } catch { // Any error means this class can't handle the protocol, // so try the next class } try { bool testMode = false; if (creator != null && Data != null && DataSize == 4) { var text = (Encoding.ASCII.GetString(Data, 0, 4) ?? "").Trim().ToUpper(); testMode = text == "TEST"; } if (creator != null && (testMode || creator.Version == Version)) { request = creator.Deserialize(Client, Data, DataSize); } } catch { // Any error means this is the correct class for the protocol, // but we had an error handling it, so return immediately return(null); } return(request); } // No classes can handle the protocol return(null); }
public virtual INxtpRequest Deserialize(Client Client, byte[] Data, int DataSize) { INxtpRequest rv = null; // Explicitly check for test mode bool testMode = false; if (Data != null && Data.Length >= 4 && DataSize == 4) { var text = (Encoding.ASCII.GetString(Data, 0, 4) ?? "").Trim().ToUpper(); testMode = text == "TEST"; } // Test mode always validates if (testMode) { foreach (var tz in TimeZoneInfo.GetSystemTimeZones()) { string id = tz.Id; if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { TZConvert.TryIanaToWindows(tz.Id, out id); } if (id == "GMT Standard Time") { this.TimeZoneCode = id.Replace(" ", ""); this.ZoneInfo = tz; return(this); } } } // Must be at least one byte for version if (Data == null || Data.Length <= 0 || Data.Length < DataSize || Data[0] != Version) { return(rv); } // Must be at least three bytes excluding payload if (Data.Length < 3) { return(rv); } // Must be three bytes longer than payload int payloadLength = Data[1]; int dataLength = payloadLength + 3; if (DataSize < dataLength) { return(rv); } // Checksum for all bytes except last must match last byte byte cs = ChecksumSeed; for (int i = 0; i < dataLength - 1; i++) { cs ^= Data[i]; } if (Data[dataLength - 1] != cs) { return(rv); } // Get timezone and see if it is in the current server list string zone = (Encoding.ASCII.GetString(Data, 2, payloadLength) ?? "").Replace(" ", "").Trim().ToLower(); zone = TimezoneList.ResolveAlias(zone); if (string.IsNullOrWhiteSpace(zone)) { return(rv); } TimeZoneInfo zoneMatched = null; var zones = TimeZoneInfo.GetSystemTimeZones(); if (zone == "phoebustime") { var rnd = new Random(); int i = rnd.Next(0, zones.Count); this.TimeZoneCode = zone; this.ZoneInfo = zones[i]; return(this); } foreach (var tz in zones) { string id = tz.Id; if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { TZConvert.TryIanaToWindows(tz.Id, out id); } if (zone == id.Replace(" ", "").ToLower()) { zoneMatched = tz; break; } } if (zoneMatched == null) { return(rv); } // Passed validation, set timezone this.Client = Client; this.TimeZoneCode = zone; this.ZoneInfo = zoneMatched; return(this); }