public void Synchronize(HGame game) { foreach (ModuleInfo module in GetInitializedModules()) { module.Instance.Synchronize(game); } }
private static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += UnhandledException; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Settings = LoadSettings(); if (args.Length > 0 && args[0].EndsWith(".swf")) { var clientInfo = new FileInfo(Path.GetFullPath(args[0])); using (var game = new HGame(clientInfo.FullName)) { game.Disassemble(); game.DisableHostChecks(); game.InjectKeyShouter(4001); game.InjectEndPointShouter(4000); game.InjectEndPoint("127.0.0.1", (int)Settings["ConnectionListenPort"]); string moddedClientPath = Path.Combine(clientInfo.DirectoryName, "MOD_" + clientInfo.Name); using (var fileOutput = File.Open(moddedClientPath, FileMode.Create)) using (var output = new FlashWriter(fileOutput)) { game.Assemble(output, CompressionKind.ZLIB); } MessageBox.Show($"File has been modified/re-assembled successfully at '{moddedClientPath}'.", "Tanji - Alert!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); } return; } Eavesdropper.Certifier = new CertificateManager("Tanji", "Tanji Certificate Authority"); Eavesdropper.Overrides.AddRange(((string)Settings["ProxyOverrides"]).Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); Application.Run(new MainFrm()); }
public Program(string[] args) { _baseDirectory = AppDomain.CurrentDomain.BaseDirectory; In = new Incoming(); Out = new Outgoing(); Options = HBOptions.Parse(args); if (string.IsNullOrWhiteSpace(Options.FetchRevision)) { Game = new HGame(Options.GameInfo.FullName); if (Options.Compression == null) { Options.Compression = Game.Compression; } } if (string.IsNullOrWhiteSpace(Options.OutputDirectory)) { if (Options.GameInfo == null) { Options.OutputDirectory = Environment.CurrentDirectory; } else { Options.OutputDirectory = Options.GameInfo.DirectoryName; } } else { Options.OutputDirectory = Path.Combine( Environment.CurrentDirectory, Options.OutputDirectory); } }
public void Synchronize(HGame game) { foreach (ISynchronizer synchronizer in _synchronizers) { synchronizer.Synchronize(game); } }
public FindMessageDialog(HGame game) { _game = game; InitializeComponent(); HashTxt.DataBindings.Add("Text", this, nameof(Hash), false, DataSourceUpdateMode.OnPropertyChanged); }
public override void ModifyGame(HGame game) { Debug.WriteLine("[WpfModule] ModifyGame"); base.ModifyGame(game); disassembledGame = true; }
static string DumpHeaders(HGame game, bool isDumpingOutgoing) { IReadOnlyDictionary <ushort, ASClass> messageClasses = (isDumpingOutgoing ? game.OutgoingMessages : game.IncomingMessages); IOrderedEnumerable <KeyValuePair <string, List <ushort> > > organizedHeaders = GetOrganizedHeadersByHashCount(game, messageClasses); string headersDump = string.Empty; string unusedHeadersDump = string.Empty; string messageType = (isDumpingOutgoing ? "Outgoing" : "Incoming"); var unusedHeaders = new List <KeyValuePair <string, List <ushort> > >(); foreach (KeyValuePair <string, List <ushort> > organizedHeader in organizedHeaders) { if (organizedHeader.Value.Count == 1) { if (isDumpingOutgoing) { UniqueOutMessageHashCount++; } else { UniqueInMessageHashCount++; } } string messageHash = organizedHeader.Key; foreach (ushort header in organizedHeader.Value) { ASClass messageClass = messageClasses[header]; string messageName = messageClass.Instance.QualifiedName.Name; ASMethod messageCtor = messageClass.Instance.Constructor; string dump = $"{messageType}[{header}, {messageHash}] = {messageName}{messageCtor}"; if (!isDumpingOutgoing) { ASClass inMsgParser = game.GetIncomingMessageParser(messageClass); dump += ($", Parser: {inMsgParser.Instance.QualifiedName.Name}"); } dump += "\r\n"; if (!game.IsMessageReferenced(messageClass)) { unusedHeadersDump += ("[Dead]" + dump); } else { headersDump += dump; } } } if (!string.IsNullOrWhiteSpace(unusedHeadersDump)) { headersDump += unusedHeadersDump; } return(headersDump.Trim()); }
public static Task <HGame> GetGameAsync(string revision) { return(ReadContentAsync(HHotel.Com.ToUri("images"), $"/gordon/{revision}/Habbo.swf", async content => { var game = new HGame(await content.ReadAsStreamAsync().ConfigureAwait(false)); game.Disassemble(); return game; })); }
static void HandleArguments(string[] args) { if (args.Length < 1) { args = GetArguments(); } string path = Path.GetFullPath(args[0]); if (!path.EndsWith(".swf") || !File.Exists(path)) { args = GetArguments(); } Game = new HGame(path); Game.LoggerCallback = LoggerCallback; FileDirectory = Path.GetDirectoryName(path); for (int i = 1; i < args.Length; i++) { string argument = args[i]; switch (argument.ToLower()) { case "-updateh": { IsDumpingHeaders = true; IsUpdatingHeaders = true; PreviousGame = new HGame(args[++i]); OutgoingHeadersPath = args[++i]; IncomingHeadersPath = args[++i]; break; } case "-rsa": { Exponent = Convert.ToInt32(args[++i], 16); Modulus = args[++i]; break; } case "-compress": { IsCompressingClient = true; break; } case "-dumph": { IsDumpingHeaders = true; break; } } } }
private void Fetch() { var flashClientUrl = string.Empty; using (var client = new WebClient()) { client.Headers[HttpRequestHeader.UserAgent] = CHROME_USER_AGENT; using (var gameDataStream = new StreamReader(client.OpenRead(EXTERNAL_VARIABLES_URL))) { while (!gameDataStream.EndOfStream) { string line = gameDataStream.ReadLine(); if (!line.StartsWith("flash.client.url")) { continue; } int urlStart = (line.IndexOf('=') + 1); flashClientUrl = ("http:" + line.Substring(urlStart) + "Habbo.swf"); int revisionStart = (line.IndexOf("gordon/") + 7); string revision = line.Substring(revisionStart, (line.Length - revisionStart) - 1); if (Options.FetchRevision == "?") { Options.FetchRevision = revision; } else { flashClientUrl = flashClientUrl.Replace( revision, Options.FetchRevision); } break; } } var remoteUri = new Uri(flashClientUrl); Options.GameInfo = new FileInfo(Path.Combine(Options.OutputDirectory, remoteUri.LocalPath.Substring(8))); Options.OutputDirectory = Directory.CreateDirectory(Options.GameInfo.DirectoryName).FullName; Console.Write($"Downloading Client({Options.FetchRevision})..."); client.DownloadFile(remoteUri, Options.GameInfo.FullName); ConsoleEx.WriteLineFinished(); } Game = new HGame(Options.GameInfo.FullName); if (Options.Compression == null) { Options.Compression = Game.Compression; } }
public override void ModifyGame(HGame game) { Debug.WriteLine($"[WpfModuleLoader] ModifyGame (loaded = {loaded})"); base.ModifyGame(game); if (loaded) { Attach(); } else { deferredAttach = true; } }
private Task InjectGameClientAsync(object sender, RequestInterceptedEventArgs e) { if (!e.Uri.Query.StartsWith("?" + _randomQuery)) { return(Task.CompletedTask); } Eavesdropper.RequestInterceptedAsync -= InjectGameClientAsync; Uri remoteUrl = e.Request.RequestUri; string clientPath = Path.Combine(Master.DataDirectory.FullName, $@"Modified Clients\{remoteUrl.Host}\{remoteUrl.LocalPath}"); if (!File.Exists(clientPath)) { _ui.SetStatusMessage(Constants.INTERCEPTING_CLIENT); Eavesdropper.ResponseInterceptedAsync += InterceptGameClientAsync; } else { _ui.SetStatusMessage(Constants.DISASSEMBLING_CLIENT); using var game = new HGame(clientPath); game.Disassemble(); _ui.SetStatusMessage(Constants.GENERATING_MESSAGE_HASHES); game.GenerateMessageHashes(Path.Combine(Master.ProgramDirectory.FullName, "Hashes.ini")); //We don't need this stuff in HabboGallery foreach (HMessage message in game.Out.Concat(game.In)) { message.Class = null; message.Parser = null; message.Structure = null; message.References.Clear(); } Master.In = game.In; Master.Out = game.Out; Task interceptConnectionTask = InterceptConnectionAsync(); e.Request = WebRequest.Create(new Uri(clientPath)); TerminateProxy(); } return(Task.CompletedTask); }
public bool ModifyGame(HGame game) { bool possiblyModified = false; ModuleItem[] moduleItems = Contractor.GetModuleItems(); foreach (ModuleItem moduleItem in moduleItems) { if (moduleItem.IsInitialized && moduleItem.Extension != null) { moduleItem.Extension?.ModifyGame(game); possiblyModified = true; } } return(possiblyModified); }
protected virtual async Task <bool> VerifyGameClientAsync(string path, byte[] data) { var game = new HGame(data); game.Location = path; try { if (game.IsCompressed) { SetState(TanjiState.DecompressingClient); await Task.Factory.StartNew(game.Decompress) .ConfigureAwait(false); } if (game.IsCompressed) { return(false); } else { UI.Game = game; } SetState(TanjiState.DisassemblingClient); UI.Game.Disassemble(); SetState(TanjiState.GeneratingMessageHashes); UI.Game.GenerateMessageHashes(); return(true); } catch (Exception ex) { WriteLog(ex); return(false); } finally { if (UI.Game != game) { game.Dispose(); } } }
private bool TryGetStructurePiece(ASMultiname multiname, ASClass @class, out char piece) { ASMultiname returnValueType = multiname; if (@class != null) { returnValueType = GetTraitType(@class, multiname) ?? GetTraitType(@class.Instance, multiname); } switch (returnValueType.Name.ToLower()) { case "int": case "readint": case "gettimer": piece = 'i'; break; case "byte": case "readbyte": piece = 'b'; break; case "double": case "readdouble": piece = 'd'; break; case "string": case "readstring": piece = 's'; break; case "boolean": case "readboolean": piece = 'B'; break; case "array": piece = char.MinValue; break; default: { if (!IsOutgoing && !HGame.IsValidIdentifier(returnValueType.Name, true)) { piece = 'i'; // This reference call is most likely towards 'readInt' } else { piece = char.MinValue; } break; } } return(piece != char.MinValue); }
private async Task <bool> VerifyGameClientAsync(string path, byte[] data) { var game = new HGame(data); game.Location = path; try { if (game.IsCompressed) { State = DECOMPRESSING_CLIENT; await Task.Factory.StartNew(game.Decompress) .ConfigureAwait(false); } if (game.IsCompressed) { return(false); } else { Master.Game = game; } State = DISASSEMBLING_CLIENT; Master.Game.Disassemble(); State = GENERATING_MESSAGE_HASHES; Master.Game.GenerateMessageHashes(); return(true); } catch (Exception ex) { Master.Log(ex); return(false); } finally { if (Master.Game != game) { game.Dispose(); } } }
private static void PatchClient(FileInfo clientInfo) { using (var game = new HGame(clientInfo.FullName)) { game.Disassemble(); game.DisableHostChecks(); game.InjectKeyShouter(4001); game.InjectEndPointShouter(4000); game.InjectEndPoint("127.0.0.1", (int)Settings["ConnectionListenPort"]); string moddedClientPath = Path.Combine(clientInfo.DirectoryName, "MOD_" + clientInfo.Name); using (var fileOutput = File.Open(moddedClientPath, FileMode.Create)) using (var output = new FlashWriter(fileOutput)) { game.Assemble(output, CompressionKind.ZLIB); } MessageBox.Show($"File has been modified/re-assembled successfully at '{moddedClientPath}'.", "Tanji - Alert!", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); } }
public bool ModifyGame(HGame game) { bool possiblyModified = false; ModuleItem[] moduleItems = Contractor.GetModuleItems(); if (Contractor.RemoteModule != null) { Contractor.RemoteModule.SendPacketAsync(1, game.Location); } foreach (ModuleItem moduleItem in moduleItems) { if (moduleItem.IsInitialized && moduleItem.Instance != null) { moduleItem.Instance?.ModifyGame(game); possiblyModified = true; } } return(possiblyModified); }
public string GenerateHash() { if (!string.IsNullOrWhiteSpace(Hash)) { return(Hash); } using (var output = new HashWriter(false)) { output.Write(IsOutgoing); if (!HGame.IsValidIdentifier(Class.QName.Name, true)) { output.Write(Class.Instance, true); output.Write(Class.Instance.Constructor); output.Write(References.Count); foreach (HReference reference in References) { output.Write(reference.IsStatic); output.Write(reference.IsAnonymous); output.Write(reference.MethodRank); output.Write(reference.InstructionRank); output.Write(reference.FromMethod); output.Write(reference.FromClass.Constructor); output.Write(reference.FromClass.Instance.Constructor); } if (!IsOutgoing && Parser != null) { output.Write(Parser.Instance, true); } } else { output.Write(Class.QName.Name); } return(Hash = output.GenerateHash()); } }
static IOrderedEnumerable <KeyValuePair <string, List <ushort> > > GetOrganizedHeadersByHashCount(HGame game, IReadOnlyDictionary <ushort, ASClass> messageClasses) { var unorganizedHeaders = new Dictionary <string, List <ushort> >(); foreach (ushort header in messageClasses.Keys) { ASClass messageClass = messageClasses[header]; string messageHash = game.GetMessageHash(messageClass); if (!unorganizedHeaders.ContainsKey(messageHash)) { unorganizedHeaders[messageHash] = new List <ushort>(); } if (!unorganizedHeaders[messageHash].Contains(header)) { unorganizedHeaders[messageHash].Add(header); } } return(unorganizedHeaders.OrderBy(kvp => kvp.Value.Count)); }
static string UpdateHeaders(string headersPath, HGame current, HGame previous, bool isUpdatingOutgoing) { IReadOnlyDictionary <ushort, ASClass> curMsgClasses = (isUpdatingOutgoing ? current.OutgoingMessages : current.IncomingMessages); IReadOnlyDictionary <ushort, ASClass> preMsgClasses = (isUpdatingOutgoing ? previous.OutgoingMessages : previous.IncomingMessages); string value = File.ReadAllText(headersPath); MatchEvaluator replacer = delegate(Match match) { bool isOut = isUpdatingOutgoing; string endValue = match.Groups["end"].Value; string headerValue = match.Groups["header"].Value; ushort preHeader = 0; if (!ushort.TryParse(headerValue, out preHeader) || !preMsgClasses.ContainsKey(preHeader)) { if (headerValue != "0000") { return($"-1{endValue} //Invalid Header '{headerValue}'"); } else { return("-1" + endValue); } } ASClass msgClass = preMsgClasses[preHeader]; string hash = previous.GetMessageHash(msgClass); bool isDead = false; string result = string.Empty; IReadOnlyList <ASClass> curSimilars = current.GetMessages(hash); if (curSimilars == null) { return($"-1{endValue} //No Matches {msgClass.Instance.QualifiedName.Name}[{headerValue}]"); } else { ASClass curMsgClass = curSimilars[0]; isDead = !current.IsMessageReferenced(curMsgClass); if (curSimilars.Count == 1) { ushort curHeader = current.GetMessageHeader(curMsgClass); result = $"{curHeader}{endValue} //{headerValue}"; } else { result = $"-1{endValue} //Duplicate Matches {msgClass.Instance.QualifiedName.Name}[{headerValue}] | {hash}"; } } if (isDead) { result += " | Dead Message(0 References)"; } return(result); }; value = Regex.Replace(value, "( |)//(.*?)\r\n", "\r\n", RegexOptions.Singleline).Trim(); if (value.Contains("-1")) { value = Regex.Replace(value, @"-\b1\b", "0000", RegexOptions.Multiline); } value = Regex.Replace(value, @"(\b(?<header>\d{1,4})\b)(?<end>[^\r|$]*)", replacer, RegexOptions.Multiline); return(value); }
private void Compare(string[] args) { using (var game_1 = new HGame(args[0])) using (var game_2 = new HGame(args[1])) { game_1.Disassemble(); game_2.Disassemble(); var matchedHashes = new List <string>(); var oldUnmatched = new Dictionary <string, List <ASMethod> >(); var unmatchedMethods = new Dictionary <string, List <ASMethod> >(); foreach (ASMethod method in game_1.ABCFiles[0].Methods) { using (var hasher = new HashWriter(false)) { hasher.Write(method); string hash = hasher.GenerateMD5Hash(); List <ASMethod> methods = null; if (!unmatchedMethods.TryGetValue(hash, out methods)) { methods = new List <ASMethod>(); unmatchedMethods.Add(hash, methods); } methods.Add(method); } } foreach (ASMethod method in game_2.ABCFiles[0].Methods) { using (var hasher = new HashWriter(false)) { hasher.Write(method); string hash = hasher.GenerateMD5Hash(); if (unmatchedMethods.ContainsKey(hash)) { matchedHashes.Add(hash); unmatchedMethods.Remove(hash); } else if (!matchedHashes.Contains(hash)) { List <ASMethod> methods = null; if (!oldUnmatched.TryGetValue(hash, out methods)) { methods = new List <ASMethod>(); oldUnmatched.Add(hash, methods); } methods.Add(method); } } } var changes = string.Empty; foreach (string hash in unmatchedMethods.Keys) { changes += $"[{hash}]\r\n{{\r\n"; foreach (ASMethod method in unmatchedMethods[hash]) { changes += $" {(method.Container?.QName.Name ?? "Anonymous")}\r\n"; changes += $" {method.ToAS3()}\r\n\r\n"; } changes += $"}}\r\n"; } } }
public Outgoing(HGame game, string identifiersPath) : base(game, identifiersPath) { }
public void LoadMessages(HGame game) { var defs = new List <MessageDefinition>(); HashSet <string> definedIncoming = new HashSet <string>(), definedOutgoing = new HashSet <string>(); foreach (var messageItem in game.InMessages.Values .Concat(game.OutMessages.Values)) { var ids = messageItem.IsOutgoing ? module.Installer.Out : (Identifiers)module.Installer.In; var def = new MessageDefinition() { IsOutgoing = messageItem.IsOutgoing, Group = messageItem.IsOutgoing ? "Outgoing" : "Incoming", Header = messageItem.Id, Name = ids.GetName(messageItem.Id) ?? string.Empty, Hash = messageItem.Hash, ClassName = messageItem.ClassName, ParserName = messageItem.ParserName, IsBlocked = module.IsBlocked(messageItem.Id, messageItem.IsOutgoing) }; if (messageItem.Structure != null) { string structure = ""; if (messageItem.Structure.Length > 0) { for (int i = 0; i < messageItem.Structure.Length; i++) { if (i > 0) { structure += ","; } switch (messageItem.Structure[i].ToLower()) { case "boolean": structure += "bool"; break; case "byte": structure += "byte"; break; case "short": case "ushort": structure += "short"; break; case "int": structure += "int"; break; case "string": structure += "str"; break; case "bytearray": structure += "byte array"; break; default: structure += messageItem.Structure[i]; break; } } } else { structure = "-"; } def.Structure = structure; } (def.IsOutgoing ? definedOutgoing : definedIncoming).Add(def.Name); defs.Add(def); } var inProperties = typeof(Incoming).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty); foreach (var prop in inProperties) { if (definedIncoming.Add(prop.Name)) { defs.Add(new MessageDefinition() { IsOutgoing = false, Group = "Incoming", Name = prop.Name }); } } var outProperties = typeof(Outgoing).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty); foreach (var prop in outProperties) { if (definedOutgoing.Add(prop.Name)) { defs.Add(new MessageDefinition() { IsOutgoing = true, Group = "Outgoing", Name = prop.Name }); } } Dispatcher.InvokeAsync(() => { foreach (var def in defs.OrderBy(x => x.Name)) { messageDefinitions.Add(def); } }); }
public Incoming(HGame game, string identifiersPath) : base(game, identifiersPath) { }
void IModule.ModifyGame(HGame game) { var unresolved = new Dictionary <string, IList <string> >(); foreach (PropertyInfo property in GetAllProperties(GetType())) { var messageIdAtt = property.GetCustomAttribute <MessageIdAttribute>(); if (string.IsNullOrWhiteSpace(messageIdAtt?.Hash)) { continue; } ushort[] ids = game.GetMessageIds(messageIdAtt.Hash); if (ids != null) { property.SetValue(this, ids[0]); } else { if (!unresolved.TryGetValue(messageIdAtt.Hash, out IList <string> users)) { users = new List <string>(); unresolved.Add(messageIdAtt.Hash, users); } users.Add("Property: " + property.Name); } } foreach (DataCaptureAttribute dataCaptureAtt in _unknownDataAttributes) { if (string.IsNullOrWhiteSpace(dataCaptureAtt.Identifier)) { continue; } ushort[] ids = game.GetMessageIds(dataCaptureAtt.Identifier); if (ids != null) { AddCallback(dataCaptureAtt, ids[0]); } else { var identifiers = (dataCaptureAtt.IsOutgoing ? Out : (Identifiers)In); if (identifiers.TryGetId(dataCaptureAtt.Identifier, out ushort id)) { AddCallback(dataCaptureAtt, id); } else { if (!unresolved.TryGetValue(dataCaptureAtt.Identifier, out IList <string> users)) { users = new List <string>(); unresolved.Add(dataCaptureAtt.Identifier, users); } users.Add(dataCaptureAtt.GetType().Name + ": " + dataCaptureAtt.Method.Name); } } } if (unresolved.Count > 0) { throw new HashResolvingException(game.Revision, unresolved); } ModifyGame(game); }
public void WritePacketLog(DataInterceptedEventArgs args, bool isOutgoing) { HMessage pkt = args.Packet; HGame game = MainUI.ConnectionPg.Game; ReadOnlyDictionary <ushort, ASClass> msgClasses = (isOutgoing ? game.OutgoingMessages : game.IncomingMessages); ASClass msgClass = null; msgClasses.TryGetValue(pkt.Header, out msgClass); Color highlight = (isOutgoing ? OutgoingHighlight : IncomingHighlight); if (DisplayTimestamp) { WriteHighlight($"[{DateTime.Now.ToLongTimeString()}]\r\n", SpecialHighlight); } if (DisplayHash) { string hash = game.GetMessageHash(msgClass); WriteHighlight($"[{hash}]\r\n", SpecialHighlight); } WriteHighlight((isOutgoing ? "Outgoing" : "Incoming"), highlight); if (args.IsBlocked && DisplayBlocked) { WriteHighlight("[Blocked]", SpecialHighlight); } else if (!args.IsOriginal) { WriteHighlight("[Replaced]", SpecialHighlight); } string arrow = (isOutgoing ? "->" : "<-"); WriteHighlight($"({pkt.Header}, {pkt.Length}", highlight); if (DisplayClassName && msgClass != null) { WriteHighlight(", ", highlight); WriteHighlight((msgClass?.Instance.Name.Name) ?? "???", SpecialHighlight); } if (!isOutgoing && DisplayParserName && msgClass != null && !_invalidParsers.Contains(pkt.Header)) { ASClass parserClass = game .GetIncomingMessageParser(msgClass); if (parserClass != null) { WriteHighlight($", ", highlight); WriteHighlight(parserClass.Instance.Name.Name, SpecialHighlight); } else { _invalidParsers.Add(pkt.Header); } } WriteHighlight($") {arrow} {pkt}\r\n", highlight); if (DisplayStructure && isOutgoing) { WriteStructureLog(pkt, msgClass); } }
public Identifiers(HGame game, string identifiersPath) : this() { Load(game, identifiersPath); }
public virtual void ModifyGame(HGame game) { }
private async Task ReceiveRemoteContractorDataAsync() { try { HMessage packet = await _remoteContractor.ReceivePacketAsync().ConfigureAwait(false); if (packet == null) { Environment.Exit(0); } #region Switch: packet.Header switch (packet.Header) { case 0: { _initStep++; _hotel = (HHotel)packet.ReadShort(); break; } case 1: { _initStep++; _in = new Incoming(); _out = new Outgoing(); string location = packet.ReadString(); if (!string.IsNullOrWhiteSpace(location)) { _game = new HGame(location); _game.Disassemble(); _game.GenerateMessageHashes(); if (packet.Readable > 0) { string hashesPath = packet.ReadString(); _in.Load(_game, hashesPath); _out.Load(_game, hashesPath); } _module.ModifyGame(_game); } break; } case 2: { _initStep++; _gameData = new HGameData(packet.ReadString()); _module.ModifyGameData(_gameData); break; } case 3: { _initStep++; var connection = (ContractorProxy)_connection; connection.Port = packet.ReadShort(); connection.Host = packet.ReadString(); connection.Address = packet.ReadString(); break; } case 4: case 5: { var destination = (HDestination)(packet.Header - 4); string stamp = packet.ReadString(); int step = packet.ReadInteger(); bool isBlocked = packet.ReadBoolean(); int dataLength = packet.ReadInteger(); byte[] data = packet.ReadBytes(dataLength); var interPacket = new HMessage(data, destination); var args = new DataInterceptedEventArgs(interPacket, step, (destination == HDestination.Server)); try { if (destination == HDestination.Server) { _module.HandleOutgoing(args); } else { _module.HandleIncoming(args); } } finally { await SendInterceptedDataResponseAsync( stamp, args).ConfigureAwait(false); } break; } } #endregion if (_initStep == 4) { _initializationSource?.SetResult(true); } } finally { Task receiveRemContDataTask = ReceiveRemoteContractorDataAsync(); } }