public HMessage Compose(IEnumerator <Token> e, bool isOutgoing, bool consumeToken = true) { if (Game == null) { throw new Exception("The game has not been disassembled, unable to parse packet"); } ushort header; if (consumeToken) { e.AssertTokenType("header", new[] { TokenType.Integer, TokenType.Identifier }); } else { e.Current.AssertTokenType("header", new[] { TokenType.Integer, TokenType.Identifier }); } if (e.Current.Type == TokenType.Integer) { header = ushort.Parse(e.Current.Value); } else { string messageName = e.Current.Value; var identifiers = isOutgoing ? (Identifiers)Out : In; if (!identifiers.TryGetId(messageName, out header)) { throw new Exception($"Unknown {(isOutgoing ? "outgoing" : "incoming")} message name: {messageName}"); } } var packet = new HMessage(header); while (e.MoveNext()) { if (e.Current.Type == TokenType.NewLine || e.Current.Type == TokenType.SequenceTerminator) { break; } switch (e.Current.Type) { case TokenType.Identifier: { var identifier = e.Current.Value.ToLower(); switch (identifier) { case "true": packet.WriteBoolean(true); break; case "false": packet.WriteBoolean(false); break; case "b": // byte { e.AssertTokenType("':'", TokenType.Colon); byte[] bytes = new byte[1] { e.ParseByte() }; packet.WriteBytes(bytes); } break; case "s": // short { e.AssertTokenType("':'", TokenType.Colon); packet.WriteShort((ushort)e.ParseShort()); } break; case "i": // int { e.AssertTokenType("':'", TokenType.Colon); packet.WriteInteger(e.ParseInt()); } break; case "a": // byte array { e.AssertTokenType("':'", TokenType.Colon); byte[] bytes = e.ParseByteArray(); packet.WriteInteger(bytes.Length); packet.WriteBytes(bytes); } break; default: throw new Exception($"Unexpected identifier '{identifier}'"); } } break; case TokenType.Subtract: case TokenType.Integer: { bool negate = e.Current.Type == TokenType.Subtract; if (negate) { e.AssertTokenType("integer", TokenType.Integer); } var s = (negate ? "-" : "") + e.Current.Value; if (!int.TryParse(s, out int value)) { throw new Exception($"Invalid integer value: {s}"); } packet.WriteInteger(value); } break; case TokenType.String: packet.WriteString(e.Current.Value); break; case TokenType.ByteArray: { byte[] bytes = ParserExtensions.ParseByteArray(e.Current); packet.WriteBytes(bytes); } break; case TokenType.NewLine: break; default: throw new Exception($"Unexpected token type {e.Current.Type}"); } } return(packet); }
private async Task ReceiveRemoteModuleDataAsync() { try { HMessage packet = await RemoteModule.ReceivePacketAsync().ConfigureAwait(false); if (packet == null) { DataAwaiters.Values.ToList().ForEach(awaiter => { if (awaiter != null) { awaiter.SetResult(null); } }); RemoteModule = null; Task grabRemoteModuleTask = GrabRemoteModuleAsync(); return; } var response = new HMessage(packet.Header); #region Switch: packet.Header switch (packet.Header) { default: response = null; break; case 0: { response.WriteShort((ushort)Hotel); break; } case 1: { response.WriteString(Game?.Location); if (!string.IsNullOrWhiteSpace(Game?.Location)) { response.WriteString(Path.GetFullPath("Hashes.ini")); } break; } case 2: { response.WriteString(GameData.Source); break; } case 3: { response.WriteShort(Connection.Port); response.WriteString(Connection.Host); response.WriteString(Connection.Address); break; } case 4: { if (Connection != null) { int dataLength = packet.ReadInteger(); byte[] data = packet.ReadBytes(dataLength); await Connection.SendToClientAsync( data).ConfigureAwait(false); response = null; } break; } case 5: { if (Connection != null) { int dataLength = packet.ReadInteger(); byte[] data = packet.ReadBytes(dataLength); await Connection.SendToServerAsync( data).ConfigureAwait(false); response = null; } break; } case 6: case 7: { string stamp = packet.ReadString(); if (DataAwaiters.ContainsKey(stamp)) { var destination = (HDestination)(packet.Header - 6); 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)); args.IsBlocked = isBlocked; DataAwaiters[stamp].SetResult(args); response = null; } break; } } #endregion if (response != null) { await RemoteModule.SendPacketAsync(response).ConfigureAwait(false); } } finally { if (RemoteModule != null) { Task receiveRemModuDataTask = ReceiveRemoteModuleDataAsync(); } } }