baseline: OpenMU upstream b5a0961 (fresh source)

This commit is contained in:
Acentech Dev
2026-07-14 19:00:35 +03:00
parent 450402e47d
commit 36fc125d5c
11968 changed files with 748705 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
</configuration>

View File

@@ -0,0 +1,103 @@
// <copyright file="CapturedConnectionExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
/// <summary>
/// Extensions for <see cref="ICapturedConnection"/>.
/// </summary>
public static class CapturedConnectionExtensions
{
private static char _fieldSeparator = ';';
/// <summary>
/// Saves the captured packets to the file in a CSV format.
/// </summary>
/// <param name="connection">The connection.</param>
/// <param name="path">The path.</param>
public static void SaveToFile(this ICapturedConnection connection, string path)
{
using var file = File.OpenWrite(path);
using var writer = new StreamWriter(file);
writer.WriteLine(connection.StartTimestamp);
foreach (var packet in connection.PacketList)
{
writer.Write(packet.Timestamp.Ticks);
writer.Write(_fieldSeparator);
writer.Write(packet.ToServer);
writer.Write(_fieldSeparator);
writer.Write(packet.Size);
writer.Write(_fieldSeparator);
writer.WriteLine(packet.PacketData);
}
}
/// <summary>
/// Loads the packets from the file.
/// </summary>
/// <param name="packetList">The packet list.</param>
/// <param name="path">The path.</param>
/// <returns>The <see cref="ICapturedConnection.StartTimestamp"/>.</returns>
public static DateTime LoadFromFile(this BindingList<Packet> packetList, string path)
{
using var stream = File.OpenRead(path);
using var reader = new StreamReader(stream);
DateTime.TryParse(reader.ReadLine(), out var start);
while (!reader.EndOfStream)
{
var currentLine = reader.ReadLine();
var splittedLine = currentLine?.Split(_fieldSeparator);
if (splittedLine is { Length: > 3 }
&& long.TryParse(splittedLine[0], out var ticks)
&& bool.TryParse(splittedLine[1], out var toServer)
&& int.TryParse(splittedLine[2], out var size)
&& TryParseArray(splittedLine[3], size, out var data))
{
packetList.Add(new Packet(new TimeSpan(ticks), data, toServer));
}
else
{
Debug.Fail($"Invalid line: {currentLine}");
}
}
return start;
}
/// <summary>
/// Tries to parse the byte array string.
/// </summary>
/// <param name="arrayString">The array string.</param>
/// <param name="data">The resulting byte array.</param>
/// <returns>The success of the parsing.</returns>
public static bool TryParseArray(string arrayString, out byte[] data)
{
return TryParseArray(arrayString, 0, out data);
}
private static bool TryParseArray(string arrayString, int specifiedLength, out byte[] data)
{
var bytesAsString = arrayString.Split(' ');
var arrayLength = specifiedLength == 0 ? bytesAsString.Length : specifiedLength;
data = new byte[arrayLength];
if (bytesAsString.Length != arrayLength)
{
return false;
}
for (int i = 0; i < bytesAsString.Length; i++)
{
data[i] = byte.Parse(bytesAsString[i], System.Globalization.NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return true;
}
}

View File

@@ -0,0 +1,29 @@
// <copyright file="ClientConnectedEventArgs.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
/// <summary>
/// The event args for the <see cref="LiveConnectionListener.ClientConnected"/>.
/// </summary>
/// <seealso cref="System.EventArgs" />
public class ClientConnectedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="ClientConnectedEventArgs"/> class.
/// </summary>
/// <param name="connection">The connection.</param>
public ClientConnectedEventArgs(LiveConnection connection)
{
this.Connection = connection;
}
/// <summary>
/// Gets the connection.
/// </summary>
/// <value>
/// The connection.
/// </value>
public LiveConnection Connection { get; }
}

View File

@@ -0,0 +1,48 @@
// <copyright file="FieldExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using MUnique.OpenMU.Network.Packets;
/// <summary>
/// Extensions for <see cref="Field"/>s.
/// </summary>
public static class FieldExtensions
{
/// <summary>
/// Gets the field size in bytes.
/// </summary>
/// <param name="field">The field.</param>
/// <returns>The size of the field in bytes.</returns>
internal static int? GetFieldSizeInBytes(this Field field)
{
switch (field.Type)
{
case FieldType.Byte:
case FieldType.Enum:
case FieldType.Boolean:
return 1;
case FieldType.Float:
return sizeof(float);
case FieldType.IntegerLittleEndian:
case FieldType.IntegerBigEndian:
return sizeof(int);
case FieldType.Double:
return sizeof(double);
case FieldType.LongLittleEndian:
case FieldType.LongBigEndian:
return sizeof(long);
case FieldType.ShortLittleEndian:
case FieldType.ShortBigEndian:
return sizeof(short);
case FieldType.String:
case FieldType.StructureArray:
case FieldType.Binary:
return field.LengthSpecified ? field.Length : (int?)null;
default:
return null;
}
}
}

View File

@@ -0,0 +1,28 @@
// <copyright file="ICapturedConnection.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.ComponentModel;
/// <summary>
/// Interface for a captured connection.
/// </summary>
public interface ICapturedConnection
{
/// <summary>
/// Gets the name of the connection.
/// </summary>
string Name { get; }
/// <summary>
/// Gets the packets of the connection.
/// </summary>
BindingList<Packet> PacketList { get; }
/// <summary>
/// Gets the start timestamp.
/// </summary>
DateTime StartTimestamp { get; }
}

View File

@@ -0,0 +1,172 @@
// <copyright file="LiveConnection.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.Buffers;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;
/// <summary>
/// A proxy which is a man-in-the-middle between a client and server connection.
/// It allows to capture the unencrypted network traffic.
/// </summary>
public class LiveConnection : INotifyPropertyChanged, ICapturedConnection
{
/// <summary>
/// The connection to the client.
/// </summary>
private readonly IConnection _clientConnection;
/// <summary>
/// The connection to the server.
/// </summary>
private readonly IConnection _serverConnection;
/// <summary>
/// The invoke action to run an action on the UI thread.
/// </summary>
private readonly Action<Delegate> _invokeAction;
/// <summary>
/// The logger for this proxied connection.
/// </summary>
private readonly ILogger _logger;
private readonly string _clientName;
private string _name = null!;
/// <summary>
/// Initializes a new instance of the <see cref="LiveConnection" /> class.
/// </summary>
/// <param name="clientConnection">The client connection.</param>
/// <param name="serverConnection">The server connection.</param>
/// <param name="invokeAction">The invoke action to run an action on the UI thread.</param>
/// <param name="loggerFactory">The logger factory.</param>
public LiveConnection(IConnection clientConnection, IConnection serverConnection, Action<Delegate> invokeAction, ILoggerFactory loggerFactory)
{
this._clientConnection = clientConnection;
this._serverConnection = serverConnection;
this._invokeAction = invokeAction;
this._logger = loggerFactory.CreateLogger("Proxy_" + this._clientConnection);
this._clientName = this._clientConnection.ToString()!;
this.Name = this._clientName;
this._clientConnection.PacketReceived += this.ClientPacketReceivedAsync;
this._serverConnection.PacketReceived += this.ServerPacketReceivedAsync;
this._clientConnection.Disconnected += this.ClientDisconnectedAsync;
this._serverConnection.Disconnected += this.ServerDisconnectedAsync;
this._logger.LogInformation("LiveConnection initialized.");
_ = this._clientConnection.BeginReceiveAsync();
_ = this._serverConnection.BeginReceiveAsync();
}
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// Gets the packet list of all captured packets.
/// </summary>
public BindingList<Packet> PacketList { get; } = new();
/// <summary>
/// Gets or sets the name of the proxied connection.
/// </summary>
public string Name
{
get => this._name;
set
{
if (this._name != value)
{
this._name = value;
this.OnPropertyChanged();
}
}
}
/// <inheritdoc />
public DateTime StartTimestamp { get; } = DateTime.UtcNow;
/// <summary>
/// Gets a value indicating whether this instance is connected to the client and server.
/// </summary>
/// <value>
/// <c>true</c> if this instance is connected; otherwise, <c>false</c>.
/// </value>
public bool IsConnected => this._clientConnection.Connected && this._serverConnection.Connected;
/// <summary>
/// Disconnects the connection to the server and therefore indirectly also to the client.
/// </summary>
public ValueTask DisconnectAsync()
{
return this._serverConnection.DisconnectAsync();
}
/// <summary>
/// Sends data to the server.
/// </summary>
/// <param name="data">The data.</param>
public async ValueTask SendToServerAsync(byte[] data)
{
var packet = new Packet(DateTime.UtcNow - this.StartTimestamp, data, true);
this._logger.LogInformation(packet.ToString());
this._serverConnection.Output.Write(data);
await this._serverConnection.Output.FlushAsync().ConfigureAwait(false);
this._invokeAction((Action)(() => this.PacketList.Add(packet)));
}
/// <summary>
/// Sends data to the client.
/// </summary>
/// <param name="data">The data.</param>
public async ValueTask SendToClientAsync(byte[] data)
{
this._clientConnection.Output.Write(data);
await this._clientConnection.Output.FlushAsync().ConfigureAwait(false);
var packet = new Packet(DateTime.UtcNow - this.StartTimestamp, data, false);
this._logger.LogInformation(packet.ToString());
this._invokeAction((Action)(() => this.PacketList.Add(packet)));
}
/// <summary>
/// Called when a property value changed.
/// </summary>
/// <param name="propertyName">Name of the property.</param>
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
this._invokeAction((Action)(() => this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName))));
}
private async ValueTask ServerDisconnectedAsync()
{
this._logger.LogInformation("The server connection closed.");
await this._clientConnection.DisconnectAsync().ConfigureAwait(false);
this.Name = this._clientName + " [Disconnected]";
}
private async ValueTask ClientDisconnectedAsync()
{
this._logger.LogInformation("The client connected closed");
await this._serverConnection.DisconnectAsync().ConfigureAwait(false);
this.Name = this._clientName + " [Disconnected]";
}
private async ValueTask ServerPacketReceivedAsync(ReadOnlySequence<byte> data)
{
var dataAsArray = data.ToArray();
await this.SendToClientAsync(dataAsArray).ConfigureAwait(false);
}
private async ValueTask ClientPacketReceivedAsync(ReadOnlySequence<byte> data)
{
var dataAsArray = data.ToArray();
await this.SendToServerAsync(dataAsArray).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,109 @@
// <copyright file="LiveConnectionListener.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.IO.Pipelines;
using System.Net.Sockets;
using Microsoft.Extensions.Logging;
using MUnique.OpenMU.Network.PlugIns;
using MUnique.OpenMU.PlugIns;
using Pipelines.Sockets.Unofficial;
/// <summary>
/// A listener which creates <see cref="LiveConnection"/> instances for each connected client.
/// </summary>
/// <seealso cref="MUnique.OpenMU.Network.Listener" />
public class LiveConnectionListener : Listener
{
private readonly PlugInManager _plugInManager;
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger<LiveConnectionListener> _logger;
private readonly Action<Delegate> _invokeAction;
/// <summary>
/// Initializes a new instance of the <see cref="LiveConnectionListener" /> class.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="targetHost">The target server host.</param>
/// <param name="targetPort">The target server port.</param>
/// <param name="plugInManager">The plug in manager.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="invokeAction">The invoke action to run an action on the UI thread.</param>
public LiveConnectionListener(int port, string targetHost, int targetPort, PlugInManager plugInManager, ILoggerFactory loggerFactory, Action<Delegate> invokeAction)
: base(port, null, null, loggerFactory)
{
this.TargetHost = targetHost;
this.TargetPort = targetPort;
this._plugInManager = plugInManager;
this._loggerFactory = loggerFactory;
this._logger = loggerFactory.CreateLogger<LiveConnectionListener>();
this._invokeAction = invokeAction;
this.ClientAccepted += this.OnClientAcceptedAsync;
}
/// <summary>
/// Occurs when a client connected and the <see cref="LiveConnection"/> object has been created.
/// </summary>
public event EventHandler<ClientConnectedEventArgs>? ClientConnected;
/// <summary>
/// Gets or sets the client version.
/// </summary>
public ClientVersion ClientVersion { get; set; }
/// <summary>
/// Gets or sets the target server host.
/// </summary>
public string TargetHost { get; set; }
/// <summary>
/// Gets or sets the target server port.
/// </summary>
public int TargetPort { get; set; }
private INetworkEncryptionFactoryPlugIn? NetworkEncryptionPlugIn =>
this._plugInManager.GetStrategy<ClientVersion, INetworkEncryptionFactoryPlugIn>(this.ClientVersion)
?? this._plugInManager.GetStrategy<ClientVersion, INetworkEncryptionFactoryPlugIn>(default);
/// <inheritdoc />
protected override IPipelinedDecryptor? CreateDecryptor(PipeReader reader)
{
return this.GetDecryptor(reader, DataDirection.ClientToServer);
}
/// <inheritdoc />
protected override IPipelinedEncryptor? CreateEncryptor(PipeWriter writer)
{
return this.GetEncryptor(writer, DataDirection.ServerToClient);
}
private IPipelinedEncryptor? GetEncryptor(PipeWriter pipeWriter, DataDirection direction) => this.NetworkEncryptionPlugIn?.CreateEncryptor(pipeWriter, direction);
private IPipelinedDecryptor? GetDecryptor(PipeReader pipeReader, DataDirection direction) => this.NetworkEncryptionPlugIn?.CreateDecryptor(pipeReader, direction);
private async ValueTask OnClientAcceptedAsync(ClientAcceptedEventArgs e)
{
var clientConnection = e.AcceptedConnection;
try
{
var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
await serverSocket.ConnectAsync(this.TargetHost, this.TargetPort).ConfigureAwait(false);
var socketConnection = SocketConnection.Create(serverSocket);
var decryptor = this.GetDecryptor(socketConnection.Input, DataDirection.ServerToClient);
var encryptor = this.GetEncryptor(socketConnection.Output, DataDirection.ClientToServer);
var serverConnection = new Connection(socketConnection, decryptor, encryptor, this._loggerFactory.CreateLogger<Connection>());
var proxy = new LiveConnection(clientConnection, serverConnection, this._invokeAction, this._loggerFactory);
this.ClientConnected?.Invoke(this, new ClientConnectedEventArgs(proxy));
}
catch (Exception exception)
{
this._logger.LogError(exception, "Error while connecting to the server. Disconnecting the client.");
await clientConnection.DisconnectAsync().ConfigureAwait(false);
}
}
}

View File

@@ -0,0 +1,52 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable;CS4014;VSTHRD110;VSTHRD100</WarningsAsErrors>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>MUnique.OpenMU.Network.Analyzer</RootNamespace>
<AssemblyName>MUnique.OpenMU.Network.Analyzer</AssemblyName>
<StartupObject>MUnique.OpenMU.Network.Analyzer.Program</StartupObject>
<ApplicationIcon>app.ico</ApplicationIcon>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>bin\Debug\MUnique.OpenMU.Network.Analyzer.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>bin\Release\MUnique.OpenMU.Network.Analyzer.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Content Include="..\Packets\ClientToServer\ClientToServerPackets.xml" Link="ClientToServerPackets.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\Packets\CommonEnums.xml" Link="CommonEnums.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\Packets\ServerToClient\ServerToClientPackets.xml" Link="ServerToClientPackets.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DG.AdvancedDataGridView" />
<PackageReference Include="System.Linq.Dynamic.Core" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MUnique.OpenMU.Network.csproj" />
<ProjectReference Include="..\Packets\MUnique.OpenMU.Network.Packets.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="MainForm.cs" />
<Compile Update="PacketSenderForm.cs" />
</ItemGroup>
<ItemGroup>
<None Update="Readme.md">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

519
src/Network/Analyzer/MainForm.Designer.cs generated Normal file
View File

@@ -0,0 +1,519 @@
namespace MUnique.OpenMU.Network.Analyzer
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (this.components != null))
{
this.components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
packetGridView = new Zuby.ADGV.AdvancedDataGridView();
packetBindingSource = new System.Windows.Forms.BindingSource(components);
rawDataTextBox = new System.Windows.Forms.TextBox();
packetInfoGroup = new System.Windows.Forms.GroupBox();
extractedInfoTextBox = new System.Windows.Forms.TextBox();
label3 = new System.Windows.Forms.Label();
label1 = new System.Windows.Forms.Label();
settingsGroup = new System.Windows.Forms.GroupBox();
targetPortNumericUpDown = new System.Windows.Forms.NumericUpDown();
label6 = new System.Windows.Forms.Label();
label7 = new System.Windows.Forms.Label();
label4 = new System.Windows.Forms.Label();
label8 = new System.Windows.Forms.Label();
targetHostTextBox = new System.Windows.Forms.TextBox();
listenerPortNumericUpDown = new System.Windows.Forms.NumericUpDown();
btnStartProxy = new System.Windows.Forms.Button();
clientVersionComboBox = new System.Windows.Forms.ComboBox();
connectedClientsGroup = new System.Windows.Forms.GroupBox();
connectedClientsListBox = new System.Windows.Forms.ListBox();
connectionContextMenu = new System.Windows.Forms.ContextMenuStrip(components);
disconnectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
loadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
openPacketSenderStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
clientBindingSource = new System.Windows.Forms.BindingSource(components);
trafficGroup = new System.Windows.Forms.GroupBox();
leftPanel = new System.Windows.Forms.Panel();
Timestamp = new System.Windows.Forms.DataGridViewTextBoxColumn();
PacketSize = new System.Windows.Forms.DataGridViewTextBoxColumn();
Type = new System.Windows.Forms.DataGridViewTextBoxColumn();
Code = new System.Windows.Forms.DataGridViewTextBoxColumn();
Direction = new System.Windows.Forms.DataGridViewTextBoxColumn();
Message = new System.Windows.Forms.DataGridViewTextBoxColumn();
PacketData = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)packetGridView).BeginInit();
((System.ComponentModel.ISupportInitialize)packetBindingSource).BeginInit();
packetInfoGroup.SuspendLayout();
settingsGroup.SuspendLayout();
((System.ComponentModel.ISupportInitialize)targetPortNumericUpDown).BeginInit();
((System.ComponentModel.ISupportInitialize)listenerPortNumericUpDown).BeginInit();
connectedClientsGroup.SuspendLayout();
connectionContextMenu.SuspendLayout();
((System.ComponentModel.ISupportInitialize)clientBindingSource).BeginInit();
trafficGroup.SuspendLayout();
leftPanel.SuspendLayout();
SuspendLayout();
//
// packetGridView
//
packetGridView.AllowUserToAddRows = false;
packetGridView.AllowUserToOrderColumns = true;
packetGridView.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
packetGridView.AutoGenerateColumns = false;
packetGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
packetGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { Timestamp, PacketSize, Type, Code, Direction, Message, PacketData });
packetGridView.DataSource = packetBindingSource;
packetGridView.FilterAndSortEnabled = true;
packetGridView.FilterStringChangedInvokeBeforeDatasourceUpdate = true;
packetGridView.Location = new System.Drawing.Point(4, 18);
packetGridView.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
packetGridView.MaxFilterButtonImageHeight = 23;
packetGridView.MultiSelect = false;
packetGridView.Name = "packetGridView";
packetGridView.ReadOnly = true;
packetGridView.RightToLeft = System.Windows.Forms.RightToLeft.No;
packetGridView.RowHeadersWidth = 20;
packetGridView.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
packetGridView.Size = new System.Drawing.Size(595, 689);
packetGridView.SortStringChangedInvokeBeforeDatasourceUpdate = true;
packetGridView.TabIndex = 27;
packetGridView.SelectionChanged += OnPacketSelected;
//
// packetBindingSource
//
packetBindingSource.AllowNew = false;
//
// rawDataTextBox
//
rawDataTextBox.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
rawDataTextBox.Location = new System.Drawing.Point(7, 320);
rawDataTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
rawDataTextBox.Multiline = true;
rawDataTextBox.Name = "rawDataTextBox";
rawDataTextBox.ReadOnly = true;
rawDataTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
rawDataTextBox.Size = new System.Drawing.Size(412, 363);
rawDataTextBox.TabIndex = 29;
//
// packetInfoGroup
//
packetInfoGroup.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
packetInfoGroup.Controls.Add(extractedInfoTextBox);
packetInfoGroup.Controls.Add(label3);
packetInfoGroup.Controls.Add(label1);
packetInfoGroup.Controls.Add(rawDataTextBox);
packetInfoGroup.Location = new System.Drawing.Point(605, 18);
packetInfoGroup.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
packetInfoGroup.Name = "packetInfoGroup";
packetInfoGroup.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
packetInfoGroup.Size = new System.Drawing.Size(427, 689);
packetInfoGroup.TabIndex = 30;
packetInfoGroup.TabStop = false;
packetInfoGroup.Text = "Packet Info";
//
// extractedInfoTextBox
//
extractedInfoTextBox.Location = new System.Drawing.Point(7, 37);
extractedInfoTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
extractedInfoTextBox.Multiline = true;
extractedInfoTextBox.Name = "extractedInfoTextBox";
extractedInfoTextBox.ReadOnly = true;
extractedInfoTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
extractedInfoTextBox.Size = new System.Drawing.Size(412, 230);
extractedInfoTextBox.TabIndex = 33;
//
// label3
//
label3.AutoSize = true;
label3.Location = new System.Drawing.Point(7, 18);
label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
label3.Name = "label3";
label3.Size = new System.Drawing.Size(125, 15);
label3.TabIndex = 32;
label3.Text = "Extracted Information:";
//
// label1
//
label1.AutoSize = true;
label1.Location = new System.Drawing.Point(4, 301);
label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
label1.Name = "label1";
label1.Size = new System.Drawing.Size(59, 15);
label1.TabIndex = 30;
label1.Text = "Raw Data:";
//
// settingsGroup
//
settingsGroup.Controls.Add(targetPortNumericUpDown);
settingsGroup.Controls.Add(label6);
settingsGroup.Controls.Add(label7);
settingsGroup.Controls.Add(label4);
settingsGroup.Controls.Add(label8);
settingsGroup.Controls.Add(targetHostTextBox);
settingsGroup.Controls.Add(listenerPortNumericUpDown);
settingsGroup.Controls.Add(btnStartProxy);
settingsGroup.Controls.Add(clientVersionComboBox);
settingsGroup.Dock = System.Windows.Forms.DockStyle.Top;
settingsGroup.Location = new System.Drawing.Point(0, 0);
settingsGroup.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
settingsGroup.Name = "settingsGroup";
settingsGroup.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
settingsGroup.Size = new System.Drawing.Size(233, 185);
settingsGroup.TabIndex = 32;
settingsGroup.TabStop = false;
settingsGroup.Text = "Settings";
//
// targetPortNumericUpDown
//
targetPortNumericUpDown.Location = new System.Drawing.Point(85, 52);
targetPortNumericUpDown.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
targetPortNumericUpDown.Maximum = new decimal(new int[] { 65536, 0, 0, 0 });
targetPortNumericUpDown.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
targetPortNumericUpDown.Name = "targetPortNumericUpDown";
targetPortNumericUpDown.Size = new System.Drawing.Size(92, 23);
targetPortNumericUpDown.TabIndex = 3;
targetPortNumericUpDown.Value = new decimal(new int[] { 55901, 0, 0, 0 });
//
// label6
//
label6.AutoSize = true;
label6.ForeColor = System.Drawing.SystemColors.ControlText;
label6.Location = new System.Drawing.Point(7, 25);
label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
label6.Name = "label6";
label6.Size = new System.Drawing.Size(55, 15);
label6.TabIndex = 0;
label6.Text = "Target IP:";
//
// label7
//
label7.AutoSize = true;
label7.ForeColor = System.Drawing.SystemColors.ControlText;
label7.Location = new System.Drawing.Point(7, 54);
label7.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
label7.Name = "label7";
label7.Size = new System.Drawing.Size(67, 15);
label7.TabIndex = 2;
label7.Text = "Target Port:";
//
// label4
//
label4.AutoSize = true;
label4.ForeColor = System.Drawing.SystemColors.ControlText;
label4.Location = new System.Drawing.Point(7, 84);
label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
label4.Name = "label4";
label4.Size = new System.Drawing.Size(63, 15);
label4.TabIndex = 2;
label4.Text = "Local Port:";
//
// label8
//
label8.AutoSize = true;
label8.ForeColor = System.Drawing.SystemColors.ControlText;
label8.Location = new System.Drawing.Point(7, 114);
label8.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
label8.Name = "label8";
label8.Size = new System.Drawing.Size(70, 15);
label8.TabIndex = 2;
label8.Text = "MU Version:";
//
// targetHostTextBox
//
targetHostTextBox.Location = new System.Drawing.Point(85, 22);
targetHostTextBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
targetHostTextBox.MaxLength = 15;
targetHostTextBox.Name = "targetHostTextBox";
targetHostTextBox.Size = new System.Drawing.Size(140, 23);
targetHostTextBox.TabIndex = 1;
targetHostTextBox.Text = "127.127.127.127";
//
// listenerPortNumericUpDown
//
listenerPortNumericUpDown.Location = new System.Drawing.Point(85, 82);
listenerPortNumericUpDown.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
listenerPortNumericUpDown.Maximum = new decimal(new int[] { 65536, 0, 0, 0 });
listenerPortNumericUpDown.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
listenerPortNumericUpDown.Name = "listenerPortNumericUpDown";
listenerPortNumericUpDown.Size = new System.Drawing.Size(92, 23);
listenerPortNumericUpDown.TabIndex = 3;
listenerPortNumericUpDown.Value = new decimal(new int[] { 55900, 0, 0, 0 });
//
// btnStartProxy
//
btnStartProxy.ForeColor = System.Drawing.SystemColors.ControlText;
btnStartProxy.Location = new System.Drawing.Point(85, 142);
btnStartProxy.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
btnStartProxy.Name = "btnStartProxy";
btnStartProxy.Size = new System.Drawing.Size(92, 27);
btnStartProxy.TabIndex = 5;
btnStartProxy.Text = "Start Proxy";
btnStartProxy.UseVisualStyleBackColor = true;
btnStartProxy.Click += StartProxy;
//
// clientVersionComboBox
//
clientVersionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
clientVersionComboBox.Location = new System.Drawing.Point(85, 112);
clientVersionComboBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
clientVersionComboBox.Name = "clientVersionComboBox";
clientVersionComboBox.Size = new System.Drawing.Size(140, 23);
clientVersionComboBox.TabIndex = 4;
//
// connectedClientsGroup
//
connectedClientsGroup.Controls.Add(connectedClientsListBox);
connectedClientsGroup.Dock = System.Windows.Forms.DockStyle.Fill;
connectedClientsGroup.Location = new System.Drawing.Point(0, 185);
connectedClientsGroup.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
connectedClientsGroup.Name = "connectedClientsGroup";
connectedClientsGroup.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
connectedClientsGroup.Size = new System.Drawing.Size(233, 529);
connectedClientsGroup.TabIndex = 33;
connectedClientsGroup.TabStop = false;
connectedClientsGroup.Text = "Connected Clients";
//
// connectedClientsListBox
//
connectedClientsListBox.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
connectedClientsListBox.ContextMenuStrip = connectionContextMenu;
connectedClientsListBox.DataSource = clientBindingSource;
connectedClientsListBox.FormattingEnabled = true;
connectedClientsListBox.ItemHeight = 15;
connectedClientsListBox.Location = new System.Drawing.Point(4, 18);
connectedClientsListBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
connectedClientsListBox.Name = "connectedClientsListBox";
connectedClientsListBox.Size = new System.Drawing.Size(229, 499);
connectedClientsListBox.TabIndex = 0;
connectedClientsListBox.SelectedIndexChanged += OnConnectionSelected;
//
// connectionContextMenu
//
connectionContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { disconnectToolStripMenuItem, loadToolStripMenuItem, saveToolStripMenuItem, openPacketSenderStripMenuItem });
connectionContextMenu.Name = "connectionContextMenu";
connectionContextMenu.Size = new System.Drawing.Size(149, 92);
connectionContextMenu.Opening += OnBeforeContextMenuOpens;
//
// disconnectToolStripMenuItem
//
disconnectToolStripMenuItem.Name = "disconnectToolStripMenuItem";
disconnectToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
disconnectToolStripMenuItem.Text = "Disconnect";
disconnectToolStripMenuItem.Click += OnDisconnectClientClick;
//
// loadToolStripMenuItem
//
loadToolStripMenuItem.Name = "loadToolStripMenuItem";
loadToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
loadToolStripMenuItem.Text = "Load from file";
loadToolStripMenuItem.Click += OnLoadFromFileClick;
//
// saveToolStripMenuItem
//
saveToolStripMenuItem.Name = "saveToolStripMenuItem";
saveToolStripMenuItem.Size = new System.Drawing.Size(148, 22);
saveToolStripMenuItem.Text = "Save to file";
saveToolStripMenuItem.Click += OnSaveToFileClick;
//
// openPacketSenderStripMenuItem
//
openPacketSenderStripMenuItem.Name = "openPacketSenderStripMenuItem";
openPacketSenderStripMenuItem.Size = new System.Drawing.Size(148, 22);
openPacketSenderStripMenuItem.Text = "Packet Sender";
openPacketSenderStripMenuItem.Click += OnSendPacketClick;
//
// trafficGroup
//
trafficGroup.Controls.Add(packetInfoGroup);
trafficGroup.Controls.Add(packetGridView);
trafficGroup.Dock = System.Windows.Forms.DockStyle.Fill;
trafficGroup.Enabled = false;
trafficGroup.Location = new System.Drawing.Point(233, 0);
trafficGroup.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
trafficGroup.Name = "trafficGroup";
trafficGroup.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
trafficGroup.Size = new System.Drawing.Size(1039, 714);
trafficGroup.TabIndex = 34;
trafficGroup.TabStop = false;
trafficGroup.Text = "Traffic";
//
// leftPanel
//
leftPanel.Controls.Add(connectedClientsGroup);
leftPanel.Controls.Add(settingsGroup);
leftPanel.Dock = System.Windows.Forms.DockStyle.Left;
leftPanel.Location = new System.Drawing.Point(0, 0);
leftPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
leftPanel.Name = "leftPanel";
leftPanel.Size = new System.Drawing.Size(233, 714);
leftPanel.TabIndex = 35;
//
// Timestamp
//
Timestamp.DataPropertyName = "Timestamp";
dataGridViewCellStyle1.Format = "g";
Timestamp.DefaultCellStyle = dataGridViewCellStyle1;
Timestamp.HeaderText = "Timestamp";
Timestamp.MinimumWidth = 24;
Timestamp.Name = "Timestamp";
Timestamp.ReadOnly = true;
Timestamp.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic;
//
// PacketSize
//
PacketSize.DataPropertyName = "Size";
PacketSize.HeaderText = "Size";
PacketSize.MinimumWidth = 24;
PacketSize.Name = "PacketSize";
PacketSize.ReadOnly = true;
PacketSize.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic;
PacketSize.Width = 55;
//
// Type
//
Type.DataPropertyName = "Type";
dataGridViewCellStyle2.Format = "X2";
Type.DefaultCellStyle = dataGridViewCellStyle2;
Type.HeaderText = "Type";
Type.MinimumWidth = 24;
Type.Name = "Type";
Type.ReadOnly = true;
Type.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic;
Type.Width = 55;
//
// Code
//
Code.DataPropertyName = "DisplayCode";
dataGridViewCellStyle3.Format = "X2";
dataGridViewCellStyle3.NullValue = null;
Code.DefaultCellStyle = dataGridViewCellStyle3;
Code.HeaderText = "Code";
Code.MinimumWidth = 24;
Code.Name = "Code";
Code.ReadOnly = true;
Code.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic;
Code.Width = 55;
//
// Direction
//
Direction.DataPropertyName = "Direction";
Direction.HeaderText = "Direction";
Direction.MinimumWidth = 24;
Direction.Name = "Direction";
Direction.ReadOnly = true;
Direction.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic;
Direction.Width = 75;
//
// Message
//
Message.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
Message.DataPropertyName = "Message";
Message.HeaderText = "Message";
Message.MinimumWidth = 24;
Message.Name = "Message";
Message.ReadOnly = true;
Message.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic;
//
// PacketData
//
PacketData.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
PacketData.DataPropertyName = "PacketData";
PacketData.HeaderText = "Data";
PacketData.MinimumWidth = 24;
PacketData.Name = "PacketData";
PacketData.ReadOnly = true;
PacketData.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Programmatic;
PacketData.Visible = false;
//
// MainForm
//
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(1272, 714);
Controls.Add(trafficGroup);
Controls.Add(leftPanel);
Icon = (System.Drawing.Icon)resources.GetObject("$this.Icon");
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
Name = "MainForm";
Text = "MUnique OpenMU Network Analyzer";
((System.ComponentModel.ISupportInitialize)packetGridView).EndInit();
((System.ComponentModel.ISupportInitialize)packetBindingSource).EndInit();
packetInfoGroup.ResumeLayout(false);
packetInfoGroup.PerformLayout();
settingsGroup.ResumeLayout(false);
settingsGroup.PerformLayout();
((System.ComponentModel.ISupportInitialize)targetPortNumericUpDown).EndInit();
((System.ComponentModel.ISupportInitialize)listenerPortNumericUpDown).EndInit();
connectedClientsGroup.ResumeLayout(false);
connectionContextMenu.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)clientBindingSource).EndInit();
trafficGroup.ResumeLayout(false);
leftPanel.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private Zuby.ADGV.AdvancedDataGridView packetGridView;
private System.Windows.Forms.TextBox rawDataTextBox;
private System.Windows.Forms.GroupBox packetInfoGroup;
private System.Windows.Forms.TextBox extractedInfoTextBox;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.GroupBox settingsGroup;
private System.Windows.Forms.TextBox targetHostTextBox;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.NumericUpDown targetPortNumericUpDown;
private System.Windows.Forms.NumericUpDown listenerPortNumericUpDown;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.Button btnStartProxy;
private System.Windows.Forms.GroupBox connectedClientsGroup;
private System.Windows.Forms.ListBox connectedClientsListBox;
private System.Windows.Forms.GroupBox trafficGroup;
private System.Windows.Forms.BindingSource clientBindingSource;
private System.Windows.Forms.BindingSource packetBindingSource;
private System.Windows.Forms.Panel leftPanel;
private System.Windows.Forms.ContextMenuStrip connectionContextMenu;
private System.Windows.Forms.ToolStripMenuItem disconnectToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem loadToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem openPacketSenderStripMenuItem;
private System.Windows.Forms.ComboBox clientVersionComboBox;
private System.Windows.Forms.DataGridViewTextBoxColumn Timestamp;
private System.Windows.Forms.DataGridViewTextBoxColumn PacketSize;
private System.Windows.Forms.DataGridViewTextBoxColumn Type;
private System.Windows.Forms.DataGridViewTextBoxColumn Code;
private System.Windows.Forms.DataGridViewTextBoxColumn Direction;
private System.Windows.Forms.DataGridViewTextBoxColumn Message;
private System.Windows.Forms.DataGridViewTextBoxColumn PacketData;
}
}

View File

@@ -0,0 +1,480 @@
// <copyright file="MainForm.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Runtime.Versioning;
using System.Windows.Forms;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using MUnique.OpenMU.Network.PlugIns;
using MUnique.OpenMU.PlugIns;
using Zuby.ADGV;
/// <summary>
/// The main form of the analyzer.
/// </summary>
[SupportedOSPlatform("windows")]
public partial class MainForm : Form
{
private readonly BindingList<ICapturedConnection> _proxiedConnections = new();
private readonly Dictionary<ClientVersion, string> _clientVersions = new()
{
{ new ClientVersion(106, 3, ClientLanguage.English), "Extended S6E3 (2.04d)" },
{ new ClientVersion(6, 3, ClientLanguage.English), "S6E3 (1.04d)" },
{ new ClientVersion(1, 0, ClientLanguage.Invariant), "Season 1 - 6" },
{ new ClientVersion(0, 97, ClientLanguage.Invariant), "0.97" },
{ new ClientVersion(0, 95, ClientLanguage.English), "0.95d" },
{ new ClientVersion(0, 75, ClientLanguage.Invariant), "0.75" },
};
private readonly PacketAnalyzer _analyzer;
private readonly PlugInManager _plugInManager;
private LiveConnectionListener? _clientListener;
private BindingList<Packet>? _unfilteredList;
private Delegate? _filterMethod;
private LambdaExpression? _filterExpression;
/// <summary>
/// Initializes a new instance of the <see cref="MainForm"/> class.
/// </summary>
public MainForm()
{
this.InitializeComponent();
var serviceContainer = new ServiceContainer();
serviceContainer.AddService(typeof(ILoggerFactory), new NullLoggerFactory());
this._plugInManager = new PlugInManager(null, new NullLoggerFactory(), serviceContainer, null);
this._plugInManager.DiscoverAndRegisterPlugIns();
this.clientBindingSource.DataSource = this._proxiedConnections;
this.connectedClientsListBox.DisplayMember = nameof(ICapturedConnection.Name);
this.connectedClientsListBox.Update();
this._analyzer = new PacketAnalyzer();
this.Disposed += (_, _) => this._analyzer.Dispose();
this.clientVersionComboBox.SelectedIndexChanged += this.OnSelectedClientVersionChanged;
this.clientVersionComboBox.DataSource = new BindingSource(this._clientVersions, string.Empty);
this.clientVersionComboBox.DisplayMember = "Value";
this.clientVersionComboBox.ValueMember = "Key";
this.targetHostTextBox.TextChanged += (_, _) =>
{
var listener = this._clientListener;
if (listener != null)
{
listener.TargetHost = this.targetHostTextBox.Text;
}
};
this.targetPortNumericUpDown.ValueChanged += (_, _) =>
{
var listener = this._clientListener;
if (listener != null)
{
listener.TargetPort = (int)this.targetPortNumericUpDown.Value;
}
};
this.packetGridView.FilterStringChanged += this.OnPacketFilterStringChanged;
foreach (DataGridViewColumn column in this.packetGridView.Columns)
{
this.packetGridView.SetSortEnabled(column, false);
}
}
private ClientVersion SelectedClientVersion
{
get
{
if (this.clientVersionComboBox.SelectedItem is KeyValuePair<ClientVersion, string> selectedItem)
{
return selectedItem.Key;
}
return default;
}
}
private ICapturedConnection? SelectedConnection
{
get
{
var index = this.connectedClientsListBox.SelectedIndex;
if (index < 0)
{
return null;
}
return this._proxiedConnections[index];
}
}
/// <inheritdoc />
protected override void OnFormClosed(FormClosedEventArgs e)
{
if (this._clientListener != null)
{
this._clientListener.Stop();
this._clientListener = null;
}
base.OnFormClosed(e);
}
private static string ConvertFilterStringToExpressionString(string filter)
{
var result = new StringBuilder();
filter = filter
.Replace("(", string.Empty, StringComparison.InvariantCulture)
.Replace(")", string.Empty, StringComparison.InvariantCulture);
var andOperator = string.Empty;
foreach (var columnFilter in filter.Split("AND"))
{
// Example: [Type] IN 'C1', 'C2'
result.Append(andOperator);
var temp1 = columnFilter.Trim().Split("IN");
var columnName = temp1[0].Split('[', ']')[1].Trim();
// prepare beginning of linq statement
result.Append("(")
.Append(columnName)
.Append(" != null && (");
string orOperator = string.Empty;
var filterValues = temp1[1].Split(',').Select(v => v.Replace("\'", string.Empty).Trim());
foreach (var filterValue in filterValues)
{
result.Append(orOperator).Append(columnName);
if (double.TryParse(filterValue, out _))
{
result.Append(" = ").Append(filterValue);
}
else
{
result.Append(".Contains(\"").Append(filterValue).Append("\")");
}
orOperator = " OR ";
}
result.Append("))");
andOperator = " AND ";
}
// replace all single quotes with double quotes
return result.ToString();
}
private void UpdateFilterExpression()
{
var filterString = this.packetGridView.FilterString;
if (string.IsNullOrEmpty(filterString))
{
this._filterExpression = null;
this._filterMethod = null;
}
else
{
var filterExpressionString = ConvertFilterStringToExpressionString(filterString);
this._filterExpression = DynamicExpressionParser.ParseLambda(ParsingConfig.Default, true, typeof(Packet), typeof(bool), filterExpressionString);
this._filterMethod = this._filterExpression.Compile(false);
}
}
private void SetPacketDataSource()
{
if (this._unfilteredList is { } oldList)
{
oldList.ListChanged -= this.OnUnfilteredListChanged;
foreach (var packet in oldList)
{
packet.AnalyzingRequested -= this.OnPacketAnalyzingRequested;
}
}
this._unfilteredList = this.SelectedConnection?.PacketList;
if (this._unfilteredList is null)
{
return;
}
foreach (var packet in this._unfilteredList)
{
packet.AnalyzingRequested += this.OnPacketAnalyzingRequested;
if (packet.AnalyzedByVersion != this.SelectedClientVersion)
{
packet.ClearMessage();
}
}
this._unfilteredList.ListChanged += this.OnUnfilteredListChanged;
if (this._filterExpression is null)
{
this.packetBindingSource.DataSource = this.SelectedConnection?.PacketList;
}
else
{
this.packetBindingSource.DataSource = this._unfilteredList.AsQueryable().Where(this._filterExpression).ToList();
}
}
private void OnPacketAnalyzingRequested(object? sender, Packet.AnalyzingRequestedEventArgs e)
{
e.ClientVersion = this._analyzer.ClientVersion;
(e.Message, e.Definition) = this._analyzer.ExtractShortInformation(e.Packet);
}
private void OnUnfilteredListChanged(object? sender, ListChangedEventArgs e)
{
if (e.ListChangedType != ListChangedType.ItemAdded
|| this._unfilteredList is not { } sourceList
|| this._unfilteredList?.Count < e.NewIndex
|| e.NewIndex < 0)
{
return;
}
var newPacket = sourceList[e.NewIndex];
newPacket.AnalyzingRequested += this.OnPacketAnalyzingRequested;
if (this._filterMethod is { } filter
&& filter.DynamicInvoke(newPacket) is true)
{
this.packetBindingSource.Add(newPacket);
}
}
private void OnSelectedClientVersionChanged(object? o, EventArgs eventArgs)
{
if (this._clientListener is { } listener)
{
listener.ClientVersion = this.SelectedClientVersion;
}
this._analyzer.ClientVersion = this.SelectedClientVersion;
if (this._unfilteredList is { } unfilteredList)
{
foreach (var packet in unfilteredList)
{
packet.ClearMessage();
}
}
}
private void OnPacketFilterStringChanged(object? sender, AdvancedDataGridView.FilterEventArgs e)
{
try
{
this.UpdateFilterExpression();
this.SetPacketDataSource();
}
catch (Exception ex)
{
Debug.Fail(ex.Message, ex.StackTrace);
}
}
private void StartProxy(object sender, System.EventArgs e)
{
if (this._clientListener != null)
{
this._clientListener.Stop();
this._clientListener = null;
this.btnStartProxy.Text = "Start Proxy";
this.listenerPortNumericUpDown.Enabled = true;
this.targetPortNumericUpDown.Enabled = true;
this.targetHostTextBox.Enabled = true;
this.clientVersionComboBox.Enabled = true;
return;
}
this._clientListener = new LiveConnectionListener(
(int)this.listenerPortNumericUpDown.Value,
this.targetHostTextBox.Text,
(int)this.targetPortNumericUpDown.Value,
this._plugInManager,
new NullLoggerFactory(),
this.InvokeByProxy)
{
ClientVersion = this.SelectedClientVersion,
};
this._analyzer.ClientVersion = this.SelectedClientVersion;
this._clientListener.ClientConnected += this.ClientListenerOnClientConnected;
this._clientListener.Start();
this.btnStartProxy.Text = "Stop Proxy";
this.listenerPortNumericUpDown.Enabled = false;
this.targetPortNumericUpDown.Enabled = false;
this.targetHostTextBox.Enabled = false;
this.clientVersionComboBox.Enabled = false;
}
private void ClientListenerOnClientConnected(object? sender, ClientConnectedEventArgs e)
{
this.InvokeByProxy(new Action(() =>
{
this._proxiedConnections.Add(e.Connection);
if (this._proxiedConnections.Count == 1)
{
this.connectedClientsListBox.SelectedItem = e.Connection;
this.OnConnectionSelected(this, EventArgs.Empty);
}
}));
}
private void InvokeByProxy(Delegate action)
{
if (this.Disposing || this.IsDisposed)
{
return;
}
try
{
this.Invoke(action);
}
catch (ObjectDisposedException)
{
// the application is probably just closing down... so swallow this error.
}
}
private void OnPacketSelected(object sender, EventArgs e)
{
this.SuspendLayout();
try
{
var rows = this.packetGridView.SelectedRows;
if (rows.Count > 0 && this.packetGridView.SelectedRows[0].DataBoundItem is Packet packet)
{
this.rawDataTextBox.Text = packet.PacketData;
this.extractedInfoTextBox.Text = this._analyzer.ExtractInformation(packet);
this.packetInfoGroup.Enabled = true;
}
else
{
this.packetInfoGroup.Enabled = false;
this.rawDataTextBox.Text = string.Empty;
this.extractedInfoTextBox.Text = string.Empty;
}
}
finally
{
this.ResumeLayout();
}
}
private void OnConnectionSelected(object sender, EventArgs e)
{
this.SetPacketDataSource();
if (this.SelectedConnection is { } connection)
{
this.trafficGroup.Enabled = true;
this.trafficGroup.Text = $"Traffic ({connection.Name})";
}
else
{
this.trafficGroup.Enabled = false;
this.trafficGroup.Text = "Traffic";
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "Catching all Exceptions.")]
private async void OnDisconnectClientClick(object sender, EventArgs e)
{
try
{
var index = this.connectedClientsListBox.SelectedIndex;
if (index < 0)
{
return;
}
if (this._proxiedConnections[index] is LiveConnection proxy)
{
await proxy.DisconnectAsync().ConfigureAwait(false);
}
}
catch
{
// Must be catched because the method is async void.
}
}
private void OnLoadFromFileClick(object sender, EventArgs e)
{
using var loadFileDialog = new OpenFileDialog { Filter = "Analyzer files (*.mucap)|*.mucap" };
if (loadFileDialog.ShowDialog(this) == DialogResult.OK)
{
var loadedConnection = new SavedConnection(loadFileDialog.FileName);
if (loadedConnection.PacketList.Count == 0)
{
MessageBox.Show("The file couldn't be loaded. It was either empty or in a wrong format.", this.loadToolStripMenuItem.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
this._proxiedConnections.Add(loadedConnection);
this.connectedClientsListBox.SelectedItem = loadedConnection;
this.OnConnectionSelected(this, EventArgs.Empty);
}
}
}
private void OnSaveToFileClick(object sender, EventArgs e)
{
var index = this.connectedClientsListBox.SelectedIndex;
if (index < 0 || this._proxiedConnections[index] is not { } capturedConnection)
{
return;
}
using var saveFileDialog = new SaveFileDialog
{
DefaultExt = "mucap",
Filter = "Analyzer files (*.mucap)|*.mucap",
AddExtension = true,
};
if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
{
capturedConnection.SaveToFile(saveFileDialog.FileName);
}
}
private void OnSendPacketClick(object sender, EventArgs e)
{
var index = this.connectedClientsListBox.SelectedIndex;
if (index < 0
|| this._proxiedConnections[index] is not LiveConnection { IsConnected: true } liveConnection)
{
return;
}
var packetSender = new PacketSenderForm(liveConnection);
packetSender.Show(this);
}
private void OnBeforeContextMenuOpens(object sender, CancelEventArgs e)
{
var index = this.connectedClientsListBox.SelectedIndex;
var selectedConnection = index < 0 ? null : this._proxiedConnections[index];
this.disconnectToolStripMenuItem.Enabled = selectedConnection is LiveConnection;
this.saveToolStripMenuItem.Enabled = selectedConnection != null;
this.openPacketSenderStripMenuItem.Enabled = selectedConnection is LiveConnection { IsConnected: true };
}
}

View File

@@ -0,0 +1,609 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="Timestamp.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="PacketSize.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Type.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Code.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Direction.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Message.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="PacketData.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="packetBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="connectionContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>183, 17</value>
</metadata>
<metadata name="clientBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>369, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>63</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAQAEBAAAAAAIABoBAAARgAAACAgAAAAACAAqBAAAK4EAAAwMAAAAAAgAKglAABWFQAADQ0AAAAA
AA2kLgAA/joAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPr6
+gD5+fkF/v7+I////zT+/v4f+Pj4A/n5+QD5+fkA9/f3Av7+/h3///80/v7+Jfr6+gb7+/sA////APf3
9wD4+PgY9/f3k9/f3+PNzc3x4+Pj3vj4+IP39/cP9/f3DPn5+X3k5OTczc3N8d7e3uT39/ea+Pj4Hff3
9wD4+PgF9/f3lr29vf9ramv/aWlp/29ub//IyMj9+fn5fvn5+XfNzc37cXFx/2lpaf9paWn/t7e3//b2
9qH5+fkJ/f39LeTk5OJubm7/srCx/+Xj5P+ko6T/dnZ2/+7u7uLy8vLffHx8/52cnf/k4uP/uLe3/2tr
a//f39/p/f39N/v7+5a/v7/9ZGRk/+Ph4v/39fb/2NbX/15eXv+0tLT+u7u7/l1dXf/R0NH/9/X2/+jm
5/9nZ2f/t7e3/vv7+6Ln5+f4cHBw/0VFRf+enZ7/0tDR/5GQkP9CQkL/RUVF/0dHR/9BQUH/i4qK/9HP
0P+ko6P/R0dH/2lpaf/j4+P61tbW/2VlZf9DQ0P/R0dH/2ZmZv9eXl7/XV1d/4aGhv+Kior/Xl5e/15e
Xv9mZmb/SEhI/0NDQ/9hYWH/zs7O//Ly8uTj4+P6kZGR/0dHR/+goKD/5ubm/+bm5v/z8/P/9PT0/+bm
5v/m5ub/paWl/0dHR/+MjIz/4eHh+/Hx8eX4+Pgj+fn5ke/v7/uQkJD/Wlpa/9HR0f/5+fn/9vb2//b2
9v/5+fn/1tbW/11dXf+Li4v/7e3t/Pn5+Zf4+Pgl9vb2APb29g34+PiR7u7u+46Ojv9ycnL/5ubm//f3
9//39/f/6enp/3d3d/+JiYn/7e3t/Pj4+Jj29vYP9vb2AAAAAAD29vYA9vb2Dfj4+JHu7u77j4+P/5OT
k//y8vL/9PT0/5qamv+Kior/7Ozs/Pj4+Jn29vYQ9vb2AAAAAAAAAAAAAAAAAPb29gD29vYN+Pj4kOzs
7PulpaX/5OTk/+np6f+lpaX/6enp/Pj4+Jn29vYQ9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAA9vb2APb2
9g339/eQ8/Pz+/T09P/09PT/8/Pz/Pf395n29vYQ9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAD29vYA9vb2DPf394329vbq9vb26/f395b29vYQ9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAPb29gD29vYM9vb2Mfb29jL29vYO9vb2AAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAMGD
AACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIABAADAAwAA4AcAAPAPAAD4HwAA/D8AACgA
AAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA9/f3APf39wL39/cY9vb2Pff391P29vZQ9vb2Nff39xD8/PwA+Pj4AAAA
AAAAAAAAAAAAAAAAAAD5+fkA8fHxAPf39w329vYx9vb2Tvf391P29vZA9/f3HPf39wL39/cAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA+fn5APX19QD39/ce9vb2g/f399X4+Pj0+fn5/Pn5+fv4+Pjw9vb2xvb2
9mj39/cP9vb2APv7+wAAAAAA9/f3APf39wv29vZf9vb2wPj4+O35+fn7+fn5/Pj4+PX39/fa9vb2jvb2
9if09PQA+Pj4AAAAAAAAAAAAAAAAAPj4+AD29vYA9vb2N/b29sn4+Pj/8PDw/9LS0v+6urr/vr6+/9ra
2v/09PT/9/f3+/b29qn29vYc9vb2APf39wD39/cV9vb2nPf39/n19fX/3d3d/8DAwP+5ubn/z8/P/+7u
7v/4+Pj/9vb21fb29kbz8/MA9/f3AAAAAAAAAAAA9vb2APb29iT29vbO9/f3/9bW1v99fX3/TU1N/0FB
Qf9CQkL/VFRU/5CQkP/l5eX/9/f3//b29qX39/cM9/f3B/b29pb39/f+6urq/5qamv9XV1f/Q0ND/0FB
Qf9LS0v/dXV1/83Nzf/39/f/9vb23Pb29jT29vYA+Pj4APf39wD6+voB9vb2j/j4+P/Y2Nj/Y2Nj/z4+
Pv9SUlL/cG9v/2tqa/9KSkr/Pz8//3p6ev/o6Oj/9/f3+fb29ln29vZI9/f38+7u7v+IiIj/QEBA/0hI
SP9oaGj/cXBx/1VVVf8+Pj7/WVlZ/8zMzP/4+Pj/9vb2p/f39wf39/cA9/f3APf39xz29vbZ8/Pz/4WF
hf8+Pj7/cHBw/8/Oz//s6uv/6efo/769vv9cXFz/QEBA/6Wlpf/4+Pj/9vb2svb29qP4+Pj/tra2/0RE
RP9UVFT/tbS1/+jm5//s6uv/1dTU/3x7e/8+Pj7/dXV1/+7u7v/39/fp9vb2Lfb29gD29vYA9vb2Qfj4
+PTc3Nz/VFRU/1FRUf/Ozc7/9PLz//Hv8P/y8PH/9fP0/7Oxsv9DQ0P/bGxs/+7u7v/39/fp9vb25PPz
8/99fX3/Pz8//6Oio//08vP/8vDx//Hv8P/08vP/2tjZ/1xbW/9KSkr/zs7O//j4+Pz29vZY9vb2APf3
9w329vam+fn5/8TExP9FRUX/bWxt/+vp6v/x7/D/8e/w//Hv8P/z8fL/2tjZ/1NTU/9UVFT/29vb//r6
+v/6+vr+5ubm/2FhYf9JSUn/zMvM//Px8v/x7/D/8e/w//Hv8P/w7u//fX19/0BAQP+zs7P/+fn5//b2
9rn39/cW9vb2dff39/fw8PD/gICA/z4+Pv9lZWX/5uTl//Lw8f/x7/D/8e/w//Px8v/Qzs//T09P/0JC
Qv91dXX/v7+//8fHx/+AgID/RERE/0hISP/DwsL/9PLz//Hv8P/x7/D/8e/w/+zq6/9xcXH/Pj4+/3Nz
c//q6ur/9/f3+/b29o329vbt+Pj4/7Kysv9GRkb/QUFB/0dHR/+ura3/8/Hy//Tx8//08vP/7+3u/5CP
kP9BQUH/QkJC/0BAQP9GRkb/SUlJ/0BAQP9CQkL/QEBA/4KBgf/q6On/9PLz//Px8v/08vP/u7q6/0xM
TP9BQUH/Q0ND/6Kiov/39/f/9vb29vj4+P/f39//X19f/0BAQP9CQkL/QUFB/1FRUf+dnJ3/y8nK/8bF
xv+Mi4z/SEhI/0FBQf9CQkL/QkJC/0BAQP9AQED/QkJC/0JCQv9CQkL/RUVF/4KBgv/CwcH/zMvM/6Wk
pf9XV1f/QUFB/0JCQv9BQUH/VVVV/9PT0//4+Pj/+fn5/8XFxf9ERET/QEBA/0JCQv9CQkL/QUFB/0FB
Qf9JSUn/R0dH/z8/P/8/Pz//QEBA/0BAQP9CQkL/VlZW/1lZWf9ERET/QEBA/0BAQP9AQED/Pj4+/0ZG
Rv9KSkr/QkJC/0FBQf9CQkL/QkJC/0BAQP9AQED/srKy//r6+v/5+fn/zs7O/2ZmZv9cXFz/RERE/0JC
Qv9CQkL/RkZG/15eXv9iYmL/YmJi/2JiYv9iYmL/Y2Nj/5mZmf/c3Nz/4eHh/6SkpP9lZWX/YmJi/2Ji
Yv9iYmL/YmJi/19fX/9ISEj/QkJC/0JCQv9DQ0P/W1tb/2JiYv+/v7//+fn5//b29v/y8vL/6enp/+Li
4v+IiIj/QkJC/0FBQf9HR0f/qamp/+rq6v/o6Oj/6Ojo/+jo6P/p6en/9fX1//j4+P/4+Pj/9vb2/+rq
6v/o6Oj/6Ojo/+jo6P/q6ur/srKy/0pKSv9BQUH/QUFB/4CAgP/f39//6enp//Hx8f/29vb/9vb24Pb2
9uX39/f8+Pj4/+vr6/+Hh4f/QkJC/0BAQP9bW1v/1dXV//n5+f/39/f/9/f3//f39//29vb/9vb2//b2
9v/29vb/9/f3//f39//39/f/+fn5/9zc3P9iYmL/QEBA/0FBQf9+fn7/5ubm//j4+P/39/f99vb25/b2
9uD29vYe9vb2J/b29qP29vb99/f3/+rq6v+Hh4f/QkJC/z8/P/90dHT/6Ojo//f39//29vb/9vb2//b2
9v/29vb/9vb2//b29v/29vb/9vb2//f39//t7e3/f39//0BAQP9BQUH/fX19/+bm5v/4+Pj/9vb2//b2
9q729vYr9vb2Hv///wD29vYA9vb2E/b29qH29vb99/f3/+rq6v+Hh4f/QkJC/0FBQf+Wlpb/9PT0//b2
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2/6Kiov9ERET/QUFB/3x8fP/l5eX/+Pj4//b2
9v/29vat9/f3Gvb29gD5+fkAAAAAAAAAAAD29vYA9vb2E/b29qL29vb99/f3/+rq6v+Ghob/QUFB/0pK
Sv+4uLj/+Pj4//b29v/29vb/9vb2//b29v/29vb/9vb2//j4+P/ExMT/T09P/0BAQP97e3v/5eXl//j4
+P/29vb/9vb2r/b29hr29vYA+Pj4AAAAAAAAAAAAAAAAAP///wD29vYA9vb2E/b29qH29vb+9/f3/+rq
6v+EhIT/QEBA/1tbW//V1dX/+Pj4//b29v/29vb/9vb2//b29v/4+Pj/3t7e/2VlZf8+Pj7/eXl5/+Tk
5P/4+Pj/9vb2//b29q/39/ca9vb2APj4+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2E/b2
9qP29vb++Pj4/+np6f+EhIT/Pz8//3V1df/p6en/9/f3//b29v/29vb/9/f3/+/v7/+Dg4P/Pz8//3l5
ef/k5OT/+Pj4//b29v/29vax9vb2G/b29gD4+PgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//
/wD29vYA9/f3FPb29qL29vb9+Pj4/+np6f+Dg4P/QkJC/5eXl//09PT/9vb2//b29v/29vb/p6en/0RE
RP93d3f/4+Pj//j4+P/29vb/9vb2sfb29hz29vYA9/f3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAP///wD29vYA9vb2E/b29qD29vb9+Pj4/+np6f+CgoL/WVlZ/+Hh4f/39/f/9/f3/+vr
6/9lZWX/dXV1/+Pj4//4+Pj/9vb2//b29q/29vYb9vb2APb29gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2E/b29qL29vb9+Pj4/+fn5/+Xl5f/4ODg//f3
9//39/f/6urq/5iYmP/f39//+Pj4//b29v/29vay9vb2HPb29gD5+fkAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD29vYA9vb2E/b29qD29vb99/f3//Dw
8P/y8vL/9vb2//b29v/09PT/7+/v//f39//29vb/9vb2sfb29hz29vYA9/f3AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2E/b2
9p/29vb99vb2//b29v/29vb/9vb2//b29v/39/f/9vb2//b29rD29vYb9vb2APb29gAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAD29vYA9vb2Evb29qD29vb99vb2//b29v/29vb/9vb2//b29v/29vay9vb2G/b29gD39/cAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAD29vYA9vb2Evb29p729vb19vb29fb29vX29vb29vb2sPb29hz29vYA9/f3AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29vYA9vb2EPf39zz39/c/9/f3P/f39z729vYW9/f3APb2
9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////
////////+A/wH/ADwA/gAYAHwAAAA4AAAAGAAAABgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAMAAAAPgAAAH8AAAD/gAAB/8AAA//gAAf/8AAP//gAH//8AD///gB///8A////gf////
//8oAAAAMAAAAGAAAAABACAAAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAPn5+QD9/f0A9/f3Dvf39zL29vZa9/f3cPf393f29vZr9vb2Tff39yT4+PgG9/f3AP//
/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD39/cA+Pj4BPf39x739/dH9vb2aPf3
93b39/dy9vb2X/f39zj39/cS+fn5Afj4+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAD4+PgA9vb2APf39xj29vZr9vb2wvb29u329vb99vb2//b29v/29vb/9vb2+fb2
9uL29van9/f3SPf39wj39/cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9/f3APj4+AX39/c89vb2m/b2
9t329vb39vb2//b29v/29vb/9vb2/vb29vH29vbL9vb2e/f39yL+/v4A+Pj4AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPf39wD4+PgC9/f3Rvb29sf29vb89vb2//f39//5+fn/+fn5//j4
+P/5+fn/+Pj4//f39//29vb/9vb28/b29pv39/cf9vb2APf39wAAAAAAAAAAAPn5+QD39/cA9/f3Fvb2
9or29vbt9vb2//b29v/4+Pj/+fn5//j4+P/5+fn/+fn5//f39//29vb/9vb2/vb29tf29vZb+Pj4Bvf3
9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9/f3APj4+AL29vZi9vb26vb29v/39/f/9/f3/+Pj
4//BwcH/pKSk/5ycnP+tra3/zc3N/+zs7P/4+Pj/9vb2//b29v/29vbE9vb2LPb29gD4+PgAAAAAAPf3
9wD39/ce9vb2svb29v729vb/+Pj4//Dw8P/S0tL/sbGx/52dnf+ioqL/vLy8/97e3v/19fX/9/f3//b2
9v/29vbz9vb2fvf39wj39/cAAAAAAAAAAAAAAAAAAAAAAAAAAAD4+PgA9fX1APf391L29vbt9vb2//j4
+P/r6+v/o6Oj/19fX/9GRkb/QEBA/0BAQP9CQkL/TExM/3Fxcf/BwcH/9PT0//f39//29vb/9vb2wPf3
9x339/cA9/f3APf39xH29vas9vb2//b29v/39/f/zc3N/3t7e/9PT0//QkJC/0BAQP9AQED/RUVF/1lZ
Wf+Wlpb/4+Pj//j4+P/29vb/9vb29/b29nD6+voB9/f3AAAAAAAAAAAAAAAAAAAAAAD39/cA9/f3Ivb2
9tL29vb/9/f3/+Li4v99fX3/Q0ND/0BAQP9AQED/Pz8//z8/P/8/Pz//QUFB/z8/P/9NTU3/oqKi//Ly
8v/39/f/9vb2//b29pH5+fkE8fHxAPb29nf29vb99vb2//b29v+1tbX/VFRU/z8/P/9BQUH/QEBA/z8/
P/8/Pz//QEBA/0BAQP9BQUH/bW1t/9bW1v/4+Pj/9vb2//b29uf39/c79vb2APn5+QAAAAAAAAAAAPj4
+ADz8/MA9vb2f/b29v/39/f/7e3t/39/f/9AQED/QUFB/0JCQv9aWVr/fHx8/4WFhf9ycXL/Tk5O/0BA
QP9BQUH/R0dH/6ysrP/39/f/9vb2//b29ur39/c19/f3IPb29tv29vb/+Pj4/8HBwf9QUFD/QEBA/0BA
QP9KSkr/bWxs/4WEhP+Af3//X19f/0NDQ/9BQUH/Pz8//2xsbP/i4uL/9/f3//b29v/29vaj+Pj4Bff3
9wAAAAAAAAAAAPf39wD39/cT9vb2zPb29v/4+Pj/rq6u/0RERP9BQUH/R0dH/5CPj//a2Nn/7+3u//Hw
8f/r6er/x8bG/25ubv9BQUH/QEBA/1hYWP/X19f/+Pj4//b29v/29vaD9/f3Zfb29v739/f/5+fn/2lp
af8/Pz//QEBA/2FhYf+8u7z/6efo//Hv8P/w7u//4N7f/5+en/9NTU3/QUFB/0BAQP+VlZX/9vb2//b2
9v/29vbm9/f3Kvf39wAAAAAAAAAAAPb29gD39/c19vb27/f39//s7Oz/bGxs/z8/P/9CQkL/jo2O/+3r
7P/z8fL/8e/w//Hv8P/x7/D/9PLz/9rY2f9mZWX/QEBA/0BAQP+bm5v/9/f3//b29v/29vbA9vb2qfb2
9v/5+fn/tra2/0RERP9AQED/V1dX/8vKyv/08vP/8vDx//Hv8P/x7/D/8vDx//Lw8f+ko6T/RkZG/0BA
QP9ZWVn/3t7e//j4+P/29vb99vb2Wfb29gAAAAAA+Pj4APb29gD39/de9vb2/Pj4+P/R0dH/Tk5O/0BA
QP9ZWFj/2dfY//Px8v/x7/D/8e/w//Hv8P/x7/D/8e/w//Ty8/+xsLD/RUVF/z8/P/9ubm7/7u7u//f3
9//29vbr9vb24/b29v/29vb/iIiI/z8/P/9BQUH/mJeY//Px8v/x7/D/8e/w//Hv8P/x7/D/8e/w//Lw
8f/n5eb/bGtr/0BAQP9ERET/ubm5//n5+f/29vb/9vb2g/Pz8wD39/cA9/f3APf39xv29vbH9vb2//n5
+f+9vb3/RUVF/z8/P/94d3j/7uzt//Hv8P/x7/D/8e/w//Hv8P/x7/D/8e/w//Px8v/X1db/U1NT/z8/
P/9bW1v/5OTk//j4+P/29vb/9vb2//f39//x8fH/cXFx/z8/P/9HR0f/wb/A//Ty8//x7/D/8e/w//Hv
8P/x7/D/8e/w//Hv8P/z8fL/k5KT/z9AP/9AQED/oaGh//n5+f/29vb/9vb23Pf39y729vYA+Pj4BPb2
9or29vb/9vb2//T09P+QkJD/QUFB/z8/P/+Af4D/8O7v//Hv8P/x7/D/8e/w//Hv8P/x7/D/8e/w//Lw
8f/a2Nn/VVVV/0BAQP9ISEj/qqqq//Ly8v/5+fn/+fn5//b29v+9vb3/UlJS/0FBQf9ISEj/x8XG//Ty
8//x7/D/8e/w//Hv8P/x7/D/8e/w//Hv8P/z8fL/mJeY/0BAQP9AQED/enp6/+/v7//39/f/9vb2//b2
9qj39/cO9vb2Vvb29u329vb/+Pj4/8PDw/9NTU3/QUFB/0BAQP9nZmb/5uTl//Lw8f/x7/D/8e/w//Hv
8P/x7/D/8e/w//Ty8//CwcH/SUlJ/0JCQv9BQUH/SUlJ/39/f/+4uLj/xMTE/5KSkv9PT0//QUFB/0JC
Qv9DQ0P/rayt//Ty8//x7/D/8e/w//Hv8P/x7/D/8e/w//Hv8P/u7O3/eXl5/z8/P/9CQkL/RkZG/6+v
r//4+Pj/9vb2//b29vf29vZ69vb23fb29v/39/f/5ubm/2xsbP9AQED/QkJC/0JCQv9HR0f/srGx//Ty
8//x7/D/8e/w//Hv8P/x7/D/8vDx/+3r7P+DgoL/QEBA/0JCQv9CQkL/QUFB/0BAQP9ERET/R0dH/0FB
Qf9BQUH/QkJC/0JCQv9AQED/bm5u/+Tj5P/z8fL/8e/w//Hv8P/x7/D/8e/w//Ty8//FxMX/T09P/0FB
Qf9CQkL/QEBA/1tbW//Y2Nj/+Pj4//b29v/29vbw9vb2//b29v/29vb/nJyc/0JCQv9CQkL/QkJC/0JC
Qv9BQUH/WVlZ/8LBwf/y8PH/9PLz//Ty8//08vP/6+rq/6Cfn/9ISEj/QUJB/0JCQv9CQkL/QkJC/0JC
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/Q0ND/4uKiv/l4+T/9PLz//Ty8//08vP/8/Hy/9HP
0P9nZmf/QEBA/0JCQv9CQkL/QkJC/0BAQP+EhIT/8PDw//b29v/29vb/9vb2//j4+P/Q0ND/UlJS/0FB
Qf9CQkL/QkJC/0JCQv9CQkL/QEFB/1JSUv+Qj4//vby8/8fFxv+0s7P/e3p6/0dHR/9BQUH/QkJC/0JC
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0NDQ/9vbm//q6qq/8bE
xf/BwMH/mpmZ/1taW/9BQUH/QkJC/0JCQv9CQkL/QkJC/0FBQf9ISEj/ubm5//j4+P/29vb/9vb2//n5
+f+zs7P/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QkJC/0FBQf9AQED/RkZG/0lJSf9ERET/QEBA/0JC
Qv9CQkL/QkJC/0JCQv9CQkL/QkJC/0BAQP9BQUH/QUFB/0BAQP9BQUH/QkJC/0JCQv9CQkL/QkJC/0JC
Qv9AQED/QkJC/0hISP9HR0f/QUFB/0FBQf9CQkL/QkJC/0JCQv9CQkL/QkJC/0JCQv8/Pz//lpaW//j4
+P/29vb/9vb2//n5+f+zs7P/QEBA/0BAQP9AQED/QkJC/0JCQv9CQkL/QkJC/0JCQv9CQkL/QEBA/z8/
P/9AQED/QEBA/0BAQP9AQED/QEBA/0BAQP8/Pz//RERE/29vb/+jo6P/qamp/3t7e/9JSUn/Pz8//0BA
QP9AQED/QEBA/0BAQP9AQED/QEBA/z8/P/9AQED/QUFB/0JCQv9CQkL/QkJC/0JCQv9CQkL/QEBA/0BA
QP89PT3/lZWV//j4+P/29vb/9vb2//j4+P/BwcH/aGho/2hoaP9eXl7/Q0ND/0JCQv9CQkL/QkJC/0JC
Qv9ISEj/ZWVl/2hoaP9oaGj/aGho/2hoaP9oaGj/aGho/2dnZ/9oaGj/oqKi/+vr6//5+fn/+fn5//Hx
8f+0tLT/bGxs/2dnZ/9oaGj/aGho/2hoaP9oaGj/aGho/2hoaP9nZ2f/S0tL/0FBQf9CQkL/QkJC/0JC
Qv9CQkL/W1tb/2hoaP9lZWX/qqqq//j4+P/29vb/9vb2//b29v/y8vL/6+vr/+zs7P/h4eH/gICA/0FB
Qf9CQkL/QkJC/0FBQf9JSUn/sLCw/+3t7f/r6+v/6+vr/+vr6//r6+v/6+vr/+vr6//s7Oz/9fX1//f3
9//29vb/9vb2//f39//39/f/7e3t/+vr6//r6+v/6+vr/+vr6//r6+v/6+vr/+7u7v+9vb3/T09P/0FB
Qf9CQkL/QkJC/0BAQP90dHT/29vb/+zs7P/r6+v/8PDw//b29v/29vb/9vb2//b29v/29vb/9/f3//f3
9//4+Pj/5ubm/319ff9BQUH/QkJC/0JCQv9AQED/Xl5e/9fX1//5+fn/9/f3//f39//39/f/9/f3//f3
9//39/f/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//f39//39/f/9/f3//f39//39/f/+Pj4/+Li
4v9paWn/QEBA/0JCQv9CQkL/QEBA/3BwcP/e3t7/+Pj4//f39//39/f/9vb2//b29v/29vb/9vb24fb2
9uD29vbo9vb2/fb29v/29vb/+Pj4/+Xl5f99fX3/QUFB/0JCQv9CQkL/QEBA/3l5ef/r6+v/9/f3//b2
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
9v/39/f/8fHx/4mJif9BQUH/QkJC/0JCQv9AQED/cHBw/93d3f/4+Pj/9vb2//b29v/29vb+9vb26vb2
9uD29vbh9vb2Hvb29h329vYt9vb2s/b29v/29vb/9vb2//j4+P/l5eX/fX19/0FBQf9CQkL/QkJC/0ND
Q/+ampr/9PT0//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
9v/29vb/9vb2//b29v/39/f/q6ur/0ZGRv9BQUH/QkJC/0BAQP9wcHD/3d3d//j4+P/29vb/9vb2//b2
9v/29vbD9vb2Nvb29h329vYeAAAAAPn5+QD29vYA9/f3HPb29rH29vb/9vb2//b29v/4+Pj/5ubm/3x8
fP9BQUH/QkJC/0FBQf9MTEz/vLy8//j4+P/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
9v/29vb/9vb2//b29v/29vb/9vb2//j4+P/MzMz/VFRU/0FBQf9CQkL/QEBA/25ubv/d3d3/+Pj4//b2
9v/29vb/9vb2//b29sL39/co9vb2APn5+QAAAAAAAAAAAAAAAAD5+fkA9vb2APf39xv29vaw9vb2//b2
9v/29vb/+Pj4/+Xl5f99fX3/QUFB/0JCQv9AQED/Xl5e/9jY2P/4+Pj/9vb2//b29v/29vb/9vb2//b2
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3/+Tk5P9sbGz/QEBA/0JCQv9AQED/b29v/9zc
3P/4+Pj/9vb2//b29v/29vb/9vb2wvf39yf29vYA+Pj4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPb2
9gD39/cc9vb2svb29v/29vb/9vb2//j4+P/l5eX/e3t7/0FBQf9CQkL/QEBA/3t7e//r6+v/9/f3//b2
9v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/39/f/8vLy/46Ojv9BQUH/QkJC/0BA
QP9tbW3/3Nzc//j4+P/29vb/9vb2//b29v/29vbE9/f3Kfb29gD4+PgAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAPj4+AD29vYA9/f3HPb29rD29vb/9vb2//b29v/4+Pj/5OTk/3t7e/9BQUH/QUFB/0ND
Q/+cnJz/9fX1//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/39/f/sLCw/0hI
SP9BQUH/QEBA/2xsbP/a2tr/+Pj4//b29v/29vb/9vb2//b29sP39/cp9vb2APj4+AAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD6+voA9vb2APf39xv29vax9vb2//b29v/29vb/+Pj4/+Pj
4/95eXn/QUFB/0FBQf9NTU3/vb29//j4+P/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//j4
+P/Pz8//V1dX/0BAQP9AQED/ampq/9nZ2f/4+Pj/9vb2//b29v/29vb/9vb2xPf39yj29vYA+fn5AAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////APb29gD39/cc9vb2s/b2
9v/29vb/9vb2//j4+P/k5OT/eXl5/0FBQf9AQED/X19f/9nZ2f/4+Pj/9vb2//b29v/29vb/9vb2//b2
9v/29vb/9/f3/+bm5v9wcHD/QEBA/0BAQP9qamr/2dnZ//j4+P/29vb/9vb2//b29v/29vbH9vb2Kvb2
9gD4+PgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPj4
+AD29vYA9/f3Hfb29rP29vb/9vb2//b29v/4+Pj/4+Pj/3h4eP9BQUH/QEBA/3x8fP/s7Oz/9/f3//b2
9v/29vb/9vb2//b29v/29vb/8/Pz/5GRkf9BQUH/QEBA/2hoaP/Y2Nj/+Pj4//b29v/29vb/9vb2//b2
9sf29vYs9vb2APf39wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAD6+voA9vb2APf39xz29vax9vb2//b29v/29vb/+Pj4/+Li4v93d3f/QEBA/0ND
Q/+enp7/9PT0//b29v/29vb/9vb2//b29v/39/f/tbW1/0lJSf8/Pz//Z2dn/9bW1v/4+Pj/9vb2//b2
9v/29vb/9vb2xvb29iv29vYA9/f3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////APb29gD29vYb9vb2rvb29v/29vb/9vb2//j4
+P/j4+P/enp6/z8/P/9aWlr/4uLi//f39//29vb/9vb2//b29v/w8PD/cHBw/z09Pf9paWn/19fX//j4
+P/29vb/9vb2//b29v/29vbE9/f3Kff39wD29vYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPf39wD29vYA9vb2Gvb2
9rD29vb/9vb2//b29v/4+Pj/4uLi/3V1df9VVVX/39/f//f39//29vb/9vb2//b29v/u7u7/aWlp/2Nj
Y//V1dX/+Pj4//b29v/29vb/9vb2//b29sb39/cp9vb2APn5+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAD6+voA9vb2APf39xz29vay9vb2//b29v/29vb/+Pj4/+Hh4f+MjIz/39/f//f39//29vb/9vb2//b2
9v/t7e3/j4+P/9LS0v/4+Pj/9vb2//b29v/29vb/9vb2yPb29iz29vYA9/f3AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA////APb29gD39/cb9vb2sPb29v/29vb/9vb2//f39//r6+v/8PDw//b2
9v/29vb/9vb2//b29v/z8/P/6enp//f39//29vb/9vb2//b29v/29vbG9vb2K/b29gD39/cAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPj4+AD29vYA9vb2G/b29q/29vb/9vb2//b2
9v/39/f/9vb2//b29v/29vb/9vb2//b29v/29vb/9/f3//b29v/29vb/9vb2//b29sb29vYr9vb2APf3
9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5+fkA9vb2APb2
9hr29vat9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2xfb2
9ir29vYA9/f3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAPb29gD29vYa9vb2sPb29v/29vb/9vb2//b29v/29vb/9vb2//b29v/29vb/9vb2//b2
9v/29vbH9vb2K/b29gD4+PgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPj4+AD29vYA9vb2Gvb29q/29vb/9vb2//b29v/29vb/9vb2//b2
9v/29vb/9vb2//b29sf29vYs9vb2APf39wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD5+fkA9vb2APb29hn29vas9vb2/Pb2
9vv29vb79vb2+/b29vv29vb99vb2xvb29iv29vYA9/f3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPf3
9wD39/cY9/f3T/f391P39/dT9/f3U/f391P39/dS9/f3JPf39wD39/cAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA////////AAD///////8AAP///////wAA////////AAD///////8AAP+A
P/wA/wAA/gAP8AB/AAD4AAfgAB8AAPAAA8AADwAA8AABgAAHAADgAACAAAcAAOAAAAAAAwAAwAAAAAAD
AADAAAAAAAMAAMAAAAAAAwAAgAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AADgAAAAAAcAAPAAAAAADwAA+AAAAAAfAAD8AAAAAD8AAP4AAAAAfwAA/wAAAAD/AAD/gAAAAf8AAP/A
AAAD/wAA/+AAAAf/AAD/8AAAD/8AAP/4AAAf/wAA//wAAD//AAD//gAAf/8AAP//AAD//wAA//+AAf//
AAD//8AD//8AAP//4Af//wAA///wD///AAD///////8AAP///////wAAiVBORw0KGgoAAAANSUhEUgAA
AQAAAAEACAYAAABccqhmAAAua0lEQVR42u2deXwURfr/P909V4fcieGIBEg4haxR4sqhIggKX2FFDCC6
igIiCAJCSDKTA5C47Bf8yuKByOL1Xfa3i4uLX3ZFZQXcVRQ55HKBBALhCkGCSYCkZyaZ7t8fzLghJpBM
V3f1zNT7H18g89RTNVOfrq566nk4RVHAYDBCE562AwwGgx5MABiMEIYJAIMRwjABYDBCGCYADEYIwwSA
wQhhmAAwGCEMEwAGI4RhAsBghDBMABiMEIYJAIMRwjABYDBCGCYADEYIY6LtAEMV0W63eyFtJywWywIA
1bT9YLQejl0HDljiJEmqoO2ED1EUo8FEIOBgrwCBiU2SpEO0nWiIJEkHAFhp+8FoHUwAAg/RO/kTaDvS
iCRJkvYDsNB2hNFy2CtAYBEuSVIRgA60HbkOR0VRTAXgou0I48awFUDgIEqSdBTGnvwA0E2SpL1gK4GA
gAlAYCBKknQEQDvajrSQXpIk7QFgpu0I4/owATA+4ZIkFQNIou1IK+kjSdJ3YBuDhobtARibSEmSTgCI
pe2ICk6IotgbgETbEcbPYQJgXOIlSbpA2wlCnBFFsSeAGtqOMK6FvQIYkxjvkz9YuNl7dCnSdoRxLUwA
jEeMJEnHAYTTdoQwSd6NTCYCBoIJgLGI9U7+aNqOaESSJEmHAYTRdoRxFbYHYBxiJUk6jdCYHKe8ewJs
Y5AybAVgDBJCaPID7HXAMLAVAGUURUlwOp3naftBCXY6QBm2AqBLrNPpLKHtBEV8pwMsbJgSTADoES5J
UgmCb7e/tSRJkrQPLGyYCkwA6BDmvdgTTdsRg9DL6XTuBCDQdiTUYAKgP2HeZW+gXOzRBUVR0lwu11Yw
EdAVtgmoL228u98303bEqHAct9tms/UD4KHtSyjAVgD6ESFJ0jGwyX9dFEVJdzqdO8AS1uoCWwHoQ7R3
wy+Qb/XpzfeiKPYF4KbtSDDDBEB7oiVJOgkgkrYjAchhURTTwERAM9grgLawya+OXt4jQhYnoBFMALQj
lk1+IjAR0BAmANrgu9jDJj8ZfCJgo+1IsMH2AMgT703mEeoRflpQIoriLWB7AsRgKwCysMmvLSnsdYAs
TADIwSa/PrA9AYIwASADm/z6wkSAEGwPQD03SZL0A20nQpR/e4OFWBkyP2ErAHUkSJJUSqvxoqIi1NbW
Uh2A2tpaHD16lFbzvb0FSVnxET9hAuAniqK0957zU0njVVxcjPz8fMiyTHUcZFlGQUEBjh8/TsuFHt5E
oyy9mB8wAfADRVGSnE5nKSidSx84cAB2u53609/H5cuXkZWVhaKiIloudPGWT2tDeywCDSYArURRlG5O
p/MkKG1AHTx4EAsXLoTLZazXXqfTidzcXBQXF9Ny4eYgraegKUwAWoF38h+h1X5RUREWLVoEt9uYcTBO
pxP5+fk4deoULRcSvJmWmAi0ECYALURRlM7eyU9lzEpLS5Gfnw+n00l7KK5LTU0NcnNzcf48tUTH7ZgI
tBwmAC3AO/mPgtJ4FRcXIzs7u8l3fiNsAjamsrISmZmZOH36NC23fCLANgZvABOAG9Bg8lPJULN3717Y
7XbU1DSdOp/n6X6FzbXvEwGKewLtWPGRG8ME4DooitKR5uTfvXs38vPzr7vhRzuQ63rt19TUwOFw0Dwd
8FUgYrcIm4EJQDMoitLe6XQeA6XJv2fPHhQWFrbETxrutbh93+nAsWPHaLmYJEnS92B1B5qECUDTxDqd
zuOgdNS3f/9+LFiwAPX19Tf8t0Z9BWiI0+mEw+FAaWkpLTdTvHUHWKLRRjAB+DlR3gSeVJaNx44dw+LF
i2mPAXFqa2uRl5dH7XTAW3fgK7C6A9fABOBawr2pu6NpNH727NlWH/UZ8RSgOaqqqpCbm4vKykpavt7p
crk+A/vd/wQbiP8Q4T06iqfR+Llz5+BwOHD58uVWfS4QXgEaUl5ejvz8/Fb3kxSyLN/ncrm2gP32AbBB
8BHtvdVHpVzXuXPnkJOTg4sXL9IeB10oLS31S+xIIcvyvUwErhLyA4D/pO6mUrRD7eQ3+ilAc5w4cQJ2
u522CPwLIT4HQrrzoJy6++zZs6qf/BzH0XCdSPulpaXIycnBpUuXqPguy/JArwiE7MZgyAqAoihtJUm6
CEqT//jx48jMzFQ1+fv27YvwcLoh7+Hh4UhLS/P78ydPnlQ9DmqQZXlgKNciDFUBSPDe56fC4cOHkZWV
pWr527lzZ9jtdlpduAaHw4HExES/P19WVoZ58+ahrKyMiv+KoqRLkrQXISgCIScADTL5UDnn//7775GX
l6fqVp/VaoXdbofNZowI17CwMGRlZamyUVFRgaysLGoiAKCPVwRCKtFoSAkA7Uw+R44cwYIFC1Qn85g+
fbqqJ64WpKSkYNKkSapsVFVVITs7G+Xl5bS60UeSpAMIIREIGQFQFCWZZiaf4uJi5OXlqZ78gwcPxtCh
Q2l04YaMGTMGffv2VWWjsrISubm5+PHHH2l1o4c35XhIJBoNCQHwTn5qqWtLS0tVL/sBIDExETNmzKDV
jRYxb948xMTEqLJx/vx5ZGdnU4sYxNW6A/9GCNwiDHoBaDD5qfT1+PHjzSbzaA1msxm5ubmGee9vjsjI
SOTk5Kg+njx37hyysrJoikCK9xahsQdcJUEtAIqi9DTC5G8umUdreO6555CUlESjG62md+/emDBhgmo7
BhKBoE0qErQC4J38h2n10Tf5JUlSbeuuu+7CsGHDaHTDbyZMmIDevXurtmMQEQjazEJBKQCyLKd6Jz8V
jh07hpycHCKTv3379pgzZw6trvgNx3HIyspCWJj6uim+cOnq6mpa3fFlFqJSBEZLgk4AZFnu7XK5DtBq
/8SJE8jNzSVWtMNI5/2tJS4uDvPnzydi6+zZs8jOzqZ2dwBXRSDoKhAFlQB4J//3tNo/ffr0dRN4tpZJ
kyYhOTmZVneIcMcdd2DEiBFEbJ05c4bqBSIEYY7BoBEA2pPfd7HnypUrROylpaVhzJgxtLpDlClTpqBD
hw5EbPmOVCmWRUsKptOBoBAAWZb70Jz8ZWVlyM7OJvaOGhsbi+zsbFrdIY7VakVeXh6sVjKxNSUlJbDb
7UT2WPwkaI4IA14AFEXp5nK5DtJqv6ysDFlZWaiqqiJij+d5FBQUICIiglaXNCEpKYnoZmZJSQlyc3ON
IAIBHTYc0ALQoFwXFc6ePUt08gNX3/u7du1Kq0uacvfdd+P+++8nZs8XXk1ZBPYhgFOOB6wAKIqSSDPI
x7crTXLyp6enY/To0TS6oxvPPvss0YtMRUVFtFcCvQI55XhACoCiKO28efupDPqZM2eIT/7o6GhkZmbS
6I6uWK1WOBwOmM3kHprFxcXIzc0ldvrSWgI55XjACYB38p8DpXevM2fOEF/28zyPvLw86tl99KJTp06Y
Nm0aUZvFxcVwOBzURMCbcnwzAmxOBZSz3sl/glb7J0+eRFZWFvEcdpMmTULPnj1pdYsKDzzwAO69916i
NktKSmiLwJBAE4GAcRRAvHfyUzl6KS0txfz584lP/v79+wf9e39zZGZmolOnTkRtlpSUICcnh6YI3BdI
IhAQTgKIlySJ2uT3BfmQDj6Ji4vDCy+8QKNLhoH0fgBwNRzb4XBQ2xgMJBEwvIMAEiRJugCAygtyeXk5
0Qg/HzzPIzc3l8hlmUAmMTERU6dOJW63pKQEeXl5cLvdVPrlFYGPYfA5ZmjncHXyU3vnv3DhAnJycjS5
ivrkk0+ie/futLpmKEaMGIH+/fsTt1tUVES10Kosy8ONvhIwrGO4OvlPgtIVzIsXL8Jut6OiooK47bS0
NGRkZNDolmGZO3cuEhISiNvdu3cvXnzxRWr9MvrrgCGdop26++LFi8jMzNQkO210dLTqFNrBiCiKyMnJ
0aTY6c6dO7Fw4ULU19dT6ZuRRcBwDimKcrPT6SwDpcl//vx5zJ07FxcuXNDEvt1uR2QklWJEhqd79+6q
U4s3x+7du7Fo0SLaewL/gMHmnKGc8ebtL6HVfnl5OebPn69ZmaqJEycSSZMVzIwePRq33367Jrb37t2L
BQsWoK6ujkrfvHEChqpFaBgB8GbvPQFKEX5lZWXIzMzULB99eno6xo4dS6NrAUd2drYm+wEAcPDgQRQU
FFDrW4NahIYQAUMIAO3svRUVFXA4HETDextCMjVWKNCmTRvk5eVpZv/gwYNYtGgRtf4pipJulIKk1AVA
luVeNLP3VldXIzs7W5PdfgAQBAH5+flo06YNje4FLMnJyXj22Wc1s79r1y785je/gSzLVPrnLUi6B5RF
gKoAKIrSkWYmn8uXLyM7Oxvnz5/XrI2pU6cG7f1+rRk1ahTuvPNOzex//fXXWLFiBRRFodXFX9C+RUhN
ABRFae90Oo/R8qGmpgZ5eXk4c+aMZm0MGjQIDz74II3uBQ2ZmZlo3769Zva3bNmCVatWUeuf9xbhVgDq
Sin5CS0BuMl7n5/Khl9NTQ0cDgdKSrQ7cIiPjzd8Hb9AQBRFZGdnaxIf4OPjjz/GG2+8Qa2Psizf43K5
NoKCCNAQgFhJkkpB6Zxfj8nPcRzsdnvIx/mTomvXrnjsscc0beOTTz6hLQIjXS7XeugsAnoLQIIkSadB
KbxXj8kPAOPGjUOPHj1odDFoGTdunOY5EwwgAmP0FgE9BYBqbP+lS5eQnZ2t+eTv2bOn5k+rUITnedjt
ds1PUz755BO89tpr1DYG9RYBXQTAG9t/HpSW/VVVVcjMzERpaamm7URERCA3NxeCYIgYj6AjLi5Ol3sU
n332GZYvX05bBDZABxHQXAAaJPCkwg8//IB58+ahrKxM87YcDgdiYmJodTUk6Nu3ry4Vk7Zu3YqlS5fC
4/FQ6acsyw/psRLQVAAa5PCj8uQvLy/HvHnzND3n9zF+/HikpqbS6GbIMWnSJF1yKXz55ZdYsmQJtX7q
8TqgmQAoitLBm72XyuSvrq5Gbm6uLnXle/Xqhccff5xGN0MWh8OhS3Tljh07sHTpUtqvA3+CRiKgiQB4
K/ac1HRkroMeEX4+IiIi4HA4ND2nZvyc+Ph43eoo/Otf/8LKlSup9VWW5fEul2sTNJivxA0qitLLu+yn
EuMsSRLsdrumEX4Nyc7OZu/9lLjjjjswcuRIXdr65JNP8Ic//IFaX73pxf4BwmHDRAVAUZRuTqfzkK4j
0wCn04mCggLNd/t9jBkzBmlpabS6ywAwbdo0JCUl6dLWunXr8Oc//5laX735BLaC4LwlZsg7+akV6rxy
5Qqys7Nx+PBhXdrr0qULJk6cSKu7jAbk5uYSTy3eHGvXrsXbb79Nra/esOFPQWjuEjHivc9/hJS91nLp
0iXMnz9f8yAfH2FhYcjPz2fn/QYhMTERs2bN0q29DRs24M0336TWX1mWh7lcri0gMN9UG5BlOZXmff7K
ykrMnz8fp0+f1q1NLTPWMPxj8ODBREuP34iPP/4Yr732GrX+yrJ8L4kcg6o+LMvyAJfLdYDWIFRVVSEn
Jwdnz57Vrc3x48ejb9++tLrMuA7Tpk1D586ddWvvs88+o32VeIg3n4DfG+5+C4Asy6kul2s7rc5XV1fr
PvnZeb+xsVgssNvtsFqturX597//nfbrQH+vCPgVJ8DV1tZSS4fiL75z/lOnTunWZkREBFauXMmO/AKA
rVu34pVXXtG1zYcffhiTJ0+m3fVWE3DRK5cvX0ZOTo6ukx+4mpmGTf7AYMiQIbjnnnt0bXPDhg149913
aXe91QSUAPgm/8mT+gYZjhs3jr33BxizZs1Cx44ddW3zww8/xHvvvUe7660iYASA1uRPTU3Fk08+Sbv7
jFZis9mQl5cHm03fqyjr16/H+++/T7v7LSYgBMAX5KP35I+MjEROTg7t7jP8JDExEdOmTdO93b/85S8B
sxIwvABUV1cjKytL93d+AMjKykJUVBTtIWCoYOjQoRg4cKDu7a5fvz4gRMDQAuA76qMx+UeNGsXi/IOE
2bNnIz4+Xvd2A0EEDCsAvqM+PSP8fHTp0iUgj3QYTRMWFga73Q6O0z/1vtFFwJAC4Nvw0+tKb0NsNhvs
djtMJupl2xgE6dGjB379619TaXv9+vVUbxFeD8MJQE1NDZXdfh+zZ89Ghw4daA8DQwPGjRuHW265hUrb
a9euxV//+lfaQ/AzDCUAtbW1cDgc1Cb/Aw88gLvvvpv2MDA0wlewJTIykkr777zzDjZu3Eh7GK7BMALg
S+ah15XexiQlJWlajZZhDGJiYnRJLd4cq1evxubNm2kPw08YRgAKCwtx5AidfCIWiwW5ubmwWKiUKmTo
TFpaGjIyMqi1/+qrr2LHjh20hwGAQQSgsLAQ+/bto9b+7NmzkZiYSHsYGDry1FNPaV5q7HoUFhbiu+++
oz0M9AXgpZdeoqqGY8aMwaBBg2gPA4MCubm5iIuLo9b+4sWLsX//fqpjQE0AnE4n7HY7vvnmG2qdT01N
xaRJk6i1z6BLTEwM7HY7tfbr6uqQm5uL7duppdXwPx9AUVER3G633w1v2LABO3fupNZxAJg/fz5iY2Op
+qCW5ORkXQpkNEdtbS21jVtSfPzxx/jqq6+o+jBjxgzcfPPNfn/eYrH4VZHabwGYMmUKysvL9RshRpN0
6NABS5cuRXR0tO5tX7hwAQUFBVSiNRnX0q5dO6xZs6bVn6O+B8BQR1lZGWbPno3i4mJd2z1y5AhmzZrF
Jn+AwwQgCLh48SLmzp2LDRs26NLexo0bkZmZicuXL9PuOkMlLOA9iHj77bexZ88ezJ07V5O9jcrKSrzy
yivYu3cv7a4yCMFWAEHGvn37MHXqVHz00UdE7X7yySeYPn06m/xBBlsBBCFOpxNr1qzBpk2bMG7cOAwd
OtRvWzt37sTbb7+ta/p1hn4wAQhiysrK8Lvf/Q7vvvsuhg8fjrvvvrtFhTPKy8vx9ddfY9OmTeykJ8hh
AhACVFdXY926dVi3bh06dOiAO++8EzfddBOioqIQFRUFQRBQU1ODHTt2YM+ePaisrKTtMkMnmACEGGVl
ZbqdFjCMD9sEZDBCGCYADEYIwwSAwQhhmAAwGCEMEwAGI4RhAsBghDBMABiMEMbvOIB77rkHH3zwAW3/
ifDo+Edx2+23IyoqCm3CwmC12iAIAjiOg8dTD7e7DpJUi0uXL+PM6dP4fMvnOHDgAG23GY3o0KEDxo0b
h6SkToiMiIAohsFqtYDnBSiKAo/HA5fLiZraWlRVVWH37l1Yv349bbeJMHjwYL8+53dCEAB45plncO7c
Odp9bzXh4eHIyBiLAf0HIC4uzq+SUR6PB4cPH8J7772H4yeO0+5SyJKcnIzx4x9Fn959IIpiqz+vKAou
VFzAV19+ibV/XEu7O37RuXNnvP766359VpUAHDp0iGqO9dbSqVMnzJwxE8nJKUTrxFVUVOCdd97Gjm+N
keo5FBg0aBAmPjkR0dExxGwqioLDRw5jxYrf4cKFC7S72GJWrFiBlJQUvz6rSgCAq4UOjFbtpDEmkwkL
Chagd+8+mrZzoeICFi9+kUpNw1ChR48eyMrKRgzBid8YRVHw7c5vsWzZUiiKqumhOY8//jgmTJjg9+dV
C4DT6cSzzz6Lixcv0h6LJunfrz/mzp0HQRB0alHBhg0b8Ie1f6Dd9aBjzpwXcM/d9+jWntvtxsKFC3Ck
iE7BmhuRmJiIt956S5UN1QIAAF9//TV+85vf0B6PnzFp0iQ8+F8jqZSFLiougt2eQ3sIgoY3Xn8D7dvT
KNqq4L3338fGjf9Hewh+xm9/+1v06aNuVUvkGHDAgAHo168f7fG4hunTn8PIB0dRmfwA0KN7D/x+9RqY
zWbaQxHQWCwWvPfue5QmPwBweGriU8jIGEt7KK5h5MiRqic/QDAOYPbs2VRSUzfF88/PwrChw2i7gbi4
OKx+6/es5qAK3lq1GpGRUbTdwGMTHsO4ceNouwHg6nEnqYI2xAQgIiIC06ZNozYoPiZOnIjB9/p3JqoF
UVFR+N3yFeB5FnPVWla/tRpRUfQnv49Hxz+KwYOH0HYDmZmZxB4qRH+Vd911F375y19SGRQAGPngSDz0
q9HU2m+Odu3aIS83j7YbAcWypcsQH38TbTcaweH5mTOJLL39ZeTIkejevTsxe8QfSzNnzoTVatV1UACg
W7duePpp49b5S0u7Dffffz9tNwKCp596GikpXWm70QwcCvIXUFmZREdH48knnyRqk7gAxMbGqjqX9JcF
BQupbfi1lKnPTIVoa320WiiRmJiIkSNH0XbjuphMJixYsFD3dqdOnYqwsDCiNnmLxfIgaUczMjJUFTps
LWPHjiU+MFrA8wLVarSBgMPuMLyQA0DnTp3Rq9cturV366234p57yMdA8IIgbOJ5/l+kDWdmZuoyMACQ
8YixjmiuR58+qWjfvj1tNwzJHXfcQfG4r/W8MOcFXdqxWq2YM2cOcbs8z3/Aexsgvubq2rUrMjIyNB+c
6dOmB9xZ++xZs2m7YEimT3+OtgutIj4+HgP6D9C8nenTp+Omm8hviFqt1qd9ewCXLBbLA6QbeOqpp9Ch
g7aKPmTIfZra14Ju3bqz2IBG3HnnnYiOiqbtRqvReuM5LS1NVWWn5rBYLEMB1P6UD0AQhM08z/9RluXH
STY0Z84czW4MDh8+XMcYf3Jw3NXostW/X6172507d0a/fv3QsWNHJCUloUuXLqitrUVlZSWqq6tx8OBB
bN26VfdSYOPHjdd9LEgQFxeHmJgYTYqp2Gw2zJo1i7hdQRD+VxCELQDANbrtZJMkSSLdoFY3Bl9d8Zqu
m40kuXTpEp56eqIubUVERGDo0KF44IEHWjxeJSUl+OCDD7B9+3ZdfPxw/V8DYvOvKbZu24rXX3+NuN2Z
M2di+PDhpM1WiKLYHkA98POMQE6LxTLU7XZ/TrLFiRMnYufOncTrzAXyZlpERARMJhPq6+s1ayMhIQFP
PPGEX9liUlJSYLfbcfjwYaxatQolJSWa+Tmg/4CAnfwAkJqaStzm7bffrsXkh81m6wfv5AeaiAMQBGEL
z/ObSDaqxS5mcnJyQC7/fXAch2HDtAkMCgsLwzPPPIN33nnH71RRPnr16oUVK1ZgxowZmh21anG8pSdx
sXFE7VmtVk2W/mazeT7HcdcoeZOBQFarNQOAm2Tjffr0Uf1jbMhdd91NfID0Rosnx2233YZVq1bhoYce
Imp3xIgRWL16NW65hfzZd5fkZOI29YTneSQlJRGz98QTTyA+Pp60m6dMJtMrP/O9mX8sWSyW/yLtwdSp
UxEREUHEVlc/UyAZiZsTye1fmM1mzJw5E4sXL0ZsbKwm/kZHR2Pp0qUYMoTshRij3CJVw623phGx06NH
D4wePZq4fzab7W4AcuO/bzYU2Psq8DeSTkRERBBb2migkLpD8oefn5+vyTtjU8ydOxdTpkwhZs8kBH6R
6m7dyNxdmDdvHnHfzGbzdI7jTjX1/657F8BqtRI/m+nfvz+RG4N8AL//+7DZbETsFBQU4Pbbb9fV99Gj
R6OwsJBIPEMgbwD6ILEPoFHczCmTydRs3rAbXQaSrFbrraQ9mjlzJiIjI1XZMHqyxpZAYhMzOzub2hXs
tLQ05OSoT3sWDN9lhMrfc2JioiaRszabbTCAZgf4hrcBeZ4/IAgC0YiV2NhY1Xea6+u0Oz4LJO68806q
7d96q/rnQzCsAKBSw7Q40jabzQ6O465btKJF14EtFgvx4HW1y1+nk3i8ku7Isqzq8xzHUQ8ptlqtqiew
LHuo9oEEauPnNDhiPWMymf77Rv+opfkAnN7YYWL4U8WlIZcuXybpDhXcbnUnreHh4bS7AED9d1kXBKu5
qip1ocBqx7AxNpttAJrY9W9MixOCeE8F1pFyUG3WoGNHj5JyhRo//qiulgLpH42/qF3NVaqcPEag+Gix
qs+T/C7NZvM0juNOt+TftiojkNVqJZaPSO0x3r59+0i5Qo2TJ0+q+nxcHNkINFp+6H3xSAt27typ6vME
v8vvTSZTi/fsWpsSzG21WomE4CUmJqr6/OEjh1W/Q9Nm2xfbVH3eKBeh1H6XO3Z8Q7sLqvB4PDh9ukUP
3GYh9V2KongvWrEl2eqcgDzPf2UymQrVOqr2RwMAF1UuoWmiKDL27NmjykawCMC2bdsC+iiQxCW3jh07
qrZhsVgeAtCqSeFXUlCz2bwQQIUaZ0kIwLcBXI33lMonBkDmR0Mi2lOtEMmyjMrKH1X3hRZffqUuo57J
ZEK7du3UuvG9IAitvnPvb1ZgjyAIf1HjrSAI6NpVXfjk2rVrA/bJsf4vqoYPwNW4cbVYrVbVCRVJ+LFl
yxbVNmigKArWr1+vyka3bt1U+yEIgl8q5HdacJ7nv1frtNogErfbjZMnS9W6oTuSU8L2r9Ul2ujcuTOJ
3PTlAFxqjSQkJKgOZPnTn/8UkPEAhw79W/VeVN++fVX7wfP8Qb8+52+Dje8V+0NaWprqji9dtizgVgHv
v/+eahu33XabahuCIHwGADzPq378kogI3Lp1q2obeqIoCpa9vEy1HULRlMf8+ZwaAVD9EkviR1xefg7/
/rfqxYhuVFZVYvPmzartEHpq7Pb+9zu1tkhcRlr55krU1RFNQ6Ep27/+CpcuXVJlw2azoVevXqp94Xne
r/mo5hXgvGqvcbWeoFoKXyqExxMYy8dFixaqttGmTRv84he/UG3Ht2zkOE61gqanpxO53fjmm2+qtqEH
brcLr7zyimo7pLIhcRz3gz+fU1MajMi2LYnkEm63G79fo3+G3dby+ZZ/4NSpU6rtDBkyhEi1YZ7nD3n/
q+48EoDFYsHAgQNV+/TFP7/AsWPGjvJUFAVLly0lYotgchW/winV/IoUnudVv7T17dsXbdq0Ud37zZs3
4/PP/6HajlaUnSvDypUridgi9KOpB3ABAHieP67SFgAQS/mWY89BTc0VIra04P/96Y/47jvVb02IjY0l
UmlYzVGuqseIIAgfqHVeEATcdx+Z4h4r31xpyKdHTU0NZs16noitjh07Ejk24nm+4TmkBAIrurS0NCIV
bGRZxvOznkddXZ1qW6T56qsv8eGHHxKxNWLECCJ2BEHw+xxSlQDwPP8ViQ786le/IjIQAJCVnYXz58mm
H1eDy+XC87NmEgtbHjduHBE7JpNpfaM/v0vCLql8dlVVVZg77wVDHQ0ePnwIryxX/94PXM3h+OCDZOry
CoLgdyy1WgEgkiy+Xbt2RDYDfcyYOQMXLlwgZs9faqVaPDttKqqqqojYi42NJbZpxPP8N43+/DEJu8OH
Dyd2s+3s2bPIzsmBxwAiUHK8BLl5ucTsDR06VHVWLB8cx5X6+1m1O0nOxj8kfxk7llyFX1mW8ey0qThR
eoKYzdZy/ofzmDJlsupjooY8/PDDpGohVHEcd67hXwiC8C0Jw1arldiTDQBKSo7B4bDD7VYdr+Q3+/bv
xfz5ZKtdk0r/5Y3h8PtdSfVWsslkWkyiIykpKcTTW82bNxfvvf8ePB79Ek4oioKP/m8Dpk+fBqfTScxu
dHQ0sXdGs9mc38Rf15IS80ceeYRohpujR4/i0QmPYt/+vcRstgSXy4Xf/vcSvPjii0TtDhs2DG3btiVi
y2w2q3KOIxBFJ0qSVEuiMxUVFZg6darqTDmNCQsLQ15ePnr26EnUbmPOnStD4UuFOHfunHpjjSgoKCCW
/NNms7Vt6tzY4/Hc73a7PyPRxqefforXX3+d+Dj06tkLDkcukZOj5lGwfft2LP/dcuJXziMiIrBmzRpi
/ouiaIGKFQAJAYDL5fpaluX+JDr00UcfYc2aNUQGpzHdunXD9GnT0alTZ6KJKMvPl+Odd97G7t27NfF7
wIABcDgcpMydEEWxuVI8RIvDZmZm4siRI5qMyahRv0LGIxnECs0AV1dvBw8ewBtvvIELFdrsIc2fPx+D
Bg0iYovn+XVWq/VRNTaICIDH47nX7Xary27RgNmzZ2tajDIqKgrjx49Hv379/a5Jf+XKFezavQsffLAO
588TCYpskrCwMKxatYpYtR+LxTL+ese3LpfrY1mWiVSFOnv2LGbOnKnpcV6PHj0xduxY3NLrFr8iERVF
xvkffsC2bVvxFwI3NK9Heno6Fi5cSMye1Wq9wxfO7S9EBAAAJ0nSJQBEslSWl5dj5syZRN+hmyMiIgIP
PzwGqX36IDIyCm3ahMFisUIQBHAcB4+nHi63G7U1tbh0qRolJSVY98E6/PijPvfX8/Ly0K9fP1Lm6sWr
W/TNboooitLd6XQWkWpw06ZNxAKgbkRycjIyHslAh8RERISHQxTDYLaYIfACAAV1dfVwuVy4UnMFlZWV
2LFjB/72N/Jl65siJiYGb7zxBrGdfwBloiiqTqpBSgBQX1//RF1d3f+S6t2WLVuwfPlyUuYCkhEjRmDG
jBnE7JnN5tkmk+nVG/07SZK+B9CbVLsLFy7U7PUoUCgsLCRy+9WHxWIZJQjC39XaUR9Q7sVkMv0JLUhD
3FLuu+++gC8brYakpCQ888wzRG1er0RUQ6xWK9GGMzMzNStYGghkZGQQnfwAnIIgbCJhiJgAAKg3m83k
IiUAvPDCC0TuSgcabdu2JVZ3z4fJZHoJLUz+4T0OJPaOEx4ejiVLlhimjoGeDB48GBMnTiRq02w2zwSh
hy2xVwAvVu9eALFfrtvtht1uR1ERsddSQxMfH49ly5YRialvgCyKYhsALd5UkWX5bpfLpS7ZXSNOnDiB
7Oxs1NYSOTU2PP369YPD4SByc7MBl0RRjAVAJDySqGcAXBaL5XGSBi0WCwoLC1XXEgwEYmJisGTJEtKT
HxaL5ddoxeQHAJ7nvyQVGOSjS5cuKCwsJFYV2cj069cPeXl5pCe/L/Mvsdho0isAAIAkSccBdCFp0+l0
oqCgAIcOHSLurxFo27YtlixZgoSEBNKmT4qi2AV+lK9UFKW90+ksI+3QiRMn4HA4cDkIyrs1xcCBA5Gd
nU188vM8/63VaiV2JASQXwEAAGw2G5Fz5EY28dJLLxFJhWU0OnbsiP/5n//RYvLDZrONgJ+1azmOO2cy
mX5L2qcuXbrg5ZdfJpHU1HAMHToUOTk5xCc/AFgslodJ29READiOOyIIAvHDX7PZjEWLFmHUqFFauE2F
9PR0LFu2DNHR0cRtC4LwOsdxh9XY8N4bUFUDoikSExOxfPlyIrkNjMLkyZMxZ84cTcqdm83m/MYXuEig
ySuAF0GSpKMg/CrgY9euXVi+fDnR23Z6YrFYMHnyZKI35xpx0hvyq3q3WFGUrk6nU5NMKx6PB2vXrsX6
9esDLruzj7Zt28LhcCAlJUWrJg6IopgGP1dy10NLAQCABEmSNIuTraqqwvLly1WX2NKblJQUZGVlEamO
1ByiKCbAm/KLBPX19Zl1dXXqc2A3w8GDB/Hyyy/j4sXAKvc2YsQITJ48WcuNzXpRFOMAaPKk01oA4PF4
HnO73X/Uso0tW7bgrbfeMvzxkslkwoQJE5CRkUHqXn+T3Cje319cLtc/ZVnWLDrL6XRizZo1+PTTTzUb
G1LEx8dj3rx5SE1N1bQdi8UyWBCEL7Syr7kAAIDb7X7f4/EQKy3eFBcvXsRrr71m2JDTrl27Yu7cuUhK
StK0HUEQ1lgsFrIhhP9BlCSpDEC0ln04cOAAXn31VSJFN7Vg+PDhmDx5MrHMR81hMpkWm83mAi3b0EUA
AHAul+tLWZbV542+AUePHsXatWsN81rQo0cPTJgwAenp6Zq3xfP8VqvVOhQavCs24CZJks6AYLBXU8iy
jG3btmHdunUoKyN+EtlqeJ7H4MGDMWHCBBKFPFvS3gar1TpG63b0EgAAMEuSVASNNgUbU1JSgo0bN2L7
9u263Cq8pqNmM9LT0zF8+HA9jy2PiqLYCwSDRJpDUZQUp9PpVykqf9i2bRs2b96Mgwf9Kn+niujoaAwa
NAgPPfSQJse0TcHz/DdWq/UuELxb0xx6CgAAhEuSdA6Erg23lF27duGLL77Ad999p1nwSVhYGG699VYM
GjSIWJWcVlAlimIHXE3vrQsej2eY2+1WX+OsFVy+fBnffPMN/vnPf2L//v2atdOhQwekp6dj4MCB6N2b
2KXIlnJSFMWuuM6VbZLoLQAAEOs9HqRyPezUqVPYv38/Dhw4gKNHj6Kiwr8j7ujoaHTv3h2pqalITU1V
XepcBT96I/10Pw/1eDwZbrdb2ywa1+HgwYPYt28fDh06hKNHj/q90uvUqRNSUlJw2223ITU1FfHx8bS6
dFQUxV+glWHbaqAhAAAQIUlSMQDtX6ZuQG1tLUpKSnD8+HFUVFSgtrYWtbW1qKmpgcfjQXh4OMLCwhAe
Ho6YmBgkJyeja9euRrnZdsa77KdWRsfj8Qxxu92qqwuToLy8HCdOnMDp06dRXV2NK1eu/PR9mkymn77L
yMhIJCQkoEuXLka6Y/JvURRvg4r8fv5ASwAAoI0kSQeh055AEHJSFMWe0PFp0RyyLN/hcrl20vYjUPG+
898DnZb917RNsd81oijewvM8kXz0oQTP898aZfJ7/dlls9luoe1HIMLz/Hrvhp/ukx+gKwAA4LRarf1I
1RYIBUwm02LvjTBDTH4fHMcdFkUxnPQV4mDGbDY/abVax0KH3f7moPkKcA3eZeS/AAT/ZXH/cFqt1kE8
zxt+qV1XV/difX19vnpLQUuFzWa7neO407QdMYwAeAl3uVybSdUYCBY4jvvOZrPdCyBgLtCzfYGm4Xn+
T1ar9UlQWvL/zB/aDjTiitVqHWA2m6fQdsQomM3m52w2W18E0OQHru4LiKIo8jyvOnNtkOC2WCz3W63W
x2CQyQ8YbwXwE4qitHU6nd8C6ETbF0qctNlsAziOox8HqxKPxzPK7XZ/BOM9cHSB5/ntVqt1BAwo4ob9
QjiOOy+KYrLZbCaXGD9AMJvNL4iimBwMkx8ABEH4myiKcaG4GrBYLI94d/kNN/kBA68AGmGur6+fXFdX
twIaX0KhSL3ZbJ5nMplWASBbHdVAKIrSzu12L5Nl+de0fdGQCovFMkUQhL+B4g5/SwgUAfBhqq+vf7qu
rm41bUdI4q3YE9QTvwlucrvdyzweD9mk+XT5wWKxPCsIwv9B2xuZxAg0AfDBe98rV8EA4cR+8qPFYnlO
EIT10OEGn4GJrKurm1tfX7+AtiMq+N5qtU4NxBiIQBWAn5BleaDL5fo9gF60fWkhJ73Lwy0IkKeETli9
q7vlCJBYEJ7n/2E2m2fzPK8q8SpNAl4AGhDj8Xjuqa+vnyHL8jDazjSE5/lvTCbTq95Jr03h+eCBUxSl
k8fjGVVXVzcPxjoFkgVBWCsIwruCIOwCUEPbIbUEkwA0xCLLch9Zlv+rrq7uKQCapWtthjKTyfS+IAgb
eZ7fB4OF7QYY0R6P55cej+cRj8czVe/GeZ7/1jvpP+c4rghBtmoLVgFojE2W5WRZlgd5PJ5hsiwPAsF8
BDzPfyoIwj94nt/K83wxAGNnJw1somRZTvV4PENlWb5PluW7CNo+IQjCF97v8iuO487C4Lv4agkVAWgK
HkC4oigJiqJ0UBQl2vvnSACR3j+bOI6rBlAJ4DLHcZcAVPM8f47juPO4erYbyht4RsGMq8LQXlGUBFz9
/iIARAGI8n6Xbo7jKgFUcRx3GcAljuMqOY47w3HcRYSoaIeyADAYIY9hIwEZDIb2MAFgMEIYJgAMRgjD
BIDBCGGYADAYIQwTAAYjhGECwGCEMEwAGIwQhgkAgxHCMAFgMEIYJgAMRgjDBIDBCGGYADAYIQwTAAYj
hGECwGCEMEwAGIwQhgkAgxHCMAFgMEIYJgAMRgjDBIDBCGGYADAYIQwTAAYjhGECwGCEMEwAGIwQhgkA
gxHCMAFgMEIYJgAMRgjDBIDBCGH+P7S1g4Ri6EQuAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -0,0 +1,204 @@
// <copyright file="Packet.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using MUnique.OpenMU.Network.Packets;
using MUnique.OpenMU.Network.PlugIns;
/// <summary>
/// A captured data packet.
/// </summary>
public sealed class Packet : INotifyPropertyChanged
{
private readonly byte[] _innerData;
private string? _dataAsString;
private ushort? _displayCode;
private string? _message;
private ClientVersion _analyzedByVersion;
private PacketDefinition? _definition;
/// <summary>
/// Initializes a new instance of the <see cref="Packet" /> class.
/// </summary>
/// <param name="timestamp">The timestamp.</param>
/// <param name="data">The data.</param>
/// <param name="toServer">If set to <c>true</c>, the packet was sent to server; Otherwise it was sent to the client.</param>
public Packet(TimeSpan timestamp, byte[] data, bool toServer)
{
this._innerData = data;
this.Timestamp = timestamp;
this.ToServer = toServer;
this.Direction = this.ToServer ? "C->S" : "S->C";
}
/// <summary>
/// Occurs when analyzing the packet requested, e.g. when the description is needed.
/// </summary>
public event EventHandler<AnalyzingRequestedEventArgs>? AnalyzingRequested;
/// <inheritdoc />
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
/// Gets the timestamp.
/// </summary>
public TimeSpan Timestamp { get; }
/// <summary>
/// Gets the raw data of the packet.
/// </summary>
public byte[] Data => this._innerData;
/// <summary>
/// Gets the type of the packet, which is the first byte of the packet byte array.
/// </summary>
public byte Type => this._innerData[0];
/// <summary>
/// Gets the code of the packet, which specifies the kind of the message.
/// </summary>
public byte Code => this._innerData.AsSpan().GetPacketType();
/// <summary>
/// Gets the sub code of the packet, which further specifies the kind of the message, if specified.
/// </summary>
public byte? SubCode => this._innerData.AsSpan().GetPacketSubType();
/// <summary>
/// Gets the display code of the packet, which specifies the kind of the message.
/// </summary>
public ushort DisplayCode
{
get
{
if (this._displayCode is not null)
{
return this._displayCode.Value;
}
if (this._definition?.SubCodeSpecified is not true)
{
return this.Code;
}
ushort result = this.Code;
if (this.SubCode is { } subCode)
{
result <<= 8;
result |= subCode;
}
this._displayCode = result;
return result;
}
}
/// <summary>
/// Gets the direction as string.
/// </summary>
public string Direction { get; }
/// <summary>
/// Gets the packet as text in a one-line string.
/// </summary>
public string Message
{
get
{
if (this._message is null && this.AnalyzingRequested is not null)
{
var request = new AnalyzingRequestedEventArgs(this);
this.AnalyzingRequested?.Invoke(this, request);
this._message = request.Message;
this._analyzedByVersion = request.ClientVersion;
this._definition = request.Definition;
this.RaisePropertyChanged(nameof(this.DisplayCode));
}
return this._message ?? string.Empty;
}
}
/// <summary>
/// Gets a value indicating whether the packet was sent to the server; Otherwise it was sent to the client.
/// </summary>
public bool ToServer { get; }
/// <summary>
/// Gets the size of the packet byte array.
/// </summary>
public int Size => this._innerData.Length;
/// <summary>
/// Gets the packet data as binary string.
/// </summary>
public string PacketData => this._dataAsString ??= this._innerData.AsString();
/// <summary>
/// Gets the protocol version which was applied when analyzing.
/// </summary>
public ClientVersion AnalyzedByVersion => this._analyzedByVersion;
/// <inheritdoc />
public override string ToString()
{
return $"{this.Direction}: {this.PacketData}";
}
/// <summary>
/// Clears the message which was generated by the packet analyzer based on a selected version.
/// </summary>
public void ClearMessage()
{
this._analyzedByVersion = default;
this._definition = null;
this._displayCode = null;
this._message = null;
this.RaisePropertyChanged(nameof(this.Message));
}
private void RaisePropertyChanged([CallerMemberName] string? propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// Event args for <see cref="Packet.AnalyzingRequested"/>.
/// </summary>
public class AnalyzingRequestedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="AnalyzingRequestedEventArgs"/> class.
/// </summary>
/// <param name="data">The data.</param>
public AnalyzingRequestedEventArgs(Packet data)
{
this.Packet = data;
}
/// <summary>
/// Gets the packet which should be analyzed.
/// </summary>
public Packet Packet { get; }
/// <summary>
/// Gets or sets the definition which was found during the analyzing.
/// </summary>
public PacketDefinition? Definition { get; set; }
/// <summary>
/// Gets or sets the client version which was set during analyzing.
/// </summary>
public ClientVersion ClientVersion { get; set; }
/// <summary>
/// Gets or sets the message which describes the packet in a one-line string.
/// </summary>
public string Message { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,513 @@
// <copyright file="PacketAnalyzer.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using MUnique.OpenMU.Network.Packets;
using MUnique.OpenMU.Network.PlugIns;
using static System.Buffers.Binary.BinaryPrimitives;
/// <summary>
/// Analyzer that analyzes data packets by considering the configuration files.
/// </summary>
public sealed class PacketAnalyzer : IDisposable
{
private const string ClientToServerPacketsFile = "ClientToServerPackets.xml";
private const string ServerToClientPacketsFile = "ServerToClientPackets.xml";
private const string CommonFile = "CommonEnums.xml";
private const int DefaultVersionValue = 100;
private const int ExtendedVersionValue = (106 * 100) + 3;
private readonly IList<IDisposable> _watchers = new List<IDisposable>();
private PacketDefinitions? _clientPacketDefinitions;
private PacketDefinitions? _serverPacketDefinitions;
private PacketDefinitions? _commonDefinitions;
private ClientVersion _clientVersion;
private int _clientVersionValue = DefaultVersionValue;
/// <summary>
/// Initializes a new instance of the <see cref="PacketAnalyzer"/> class.
/// The configuration is automatically loaded from the configuration files.
/// </summary>
public PacketAnalyzer()
{
this.LoadAndWatchConfiguration(def => this._serverPacketDefinitions = def, ServerToClientPacketsFile);
this.LoadAndWatchConfiguration(def => this._clientPacketDefinitions = def, ClientToServerPacketsFile);
this.LoadAndWatchConfiguration(def => this._commonDefinitions = def, CommonFile);
}
/// <summary>
/// Gets or sets the client version.
/// </summary>
public ClientVersion ClientVersion
{
get => this._clientVersion;
set
{
this._clientVersion = value;
this._clientVersionValue = (value.Season * 100) + value.Episode;
}
}
/// <summary>
/// Extracts the information of the packet and returns it as a formatted string.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns>The formatted string with the extracted information.</returns>
public string ExtractInformation(Packet packet)
{
var definitions = packet.ToServer ? this._clientPacketDefinitions : this._serverPacketDefinitions;
var definition = this.DeterminePacketDefinition(packet);
if (definition != null)
{
var stringBuilder = new StringBuilder()
.Append(definition.Caption ?? definition.Name);
foreach (var field in definition.Fields ?? Enumerable.Empty<Field>())
{
stringBuilder.Append(Environment.NewLine)
.Append(field.Name).Append(": ").Append(this.ExtractFieldValueOrGetError(packet.Data.AsSpan(), field, definition, definitions!));
}
return stringBuilder.ToString();
}
return string.Empty;
}
/// <summary>
/// Extracts the information of the packet and returns it as a short, formatted string.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns>The formatted string with the extracted information.</returns>
public (string, PacketDefinition?) ExtractShortInformation(Packet packet)
{
var definitions = packet.ToServer ? this._clientPacketDefinitions : this._serverPacketDefinitions;
var definition = this.DeterminePacketDefinition(packet);
if (definition is null)
{
return (packet.PacketData, null);
}
var stringBuilder = new StringBuilder(definition.Caption ?? definition.Name ?? string.Empty);
var relevantFields = definition.Fields?
.Where(f => f.Type != FieldType.Binary && f.Type != FieldType.StructureArray)
.Where(f => f.Name != "HeaderCode")
?? [];
if (relevantFields.Any())
{
stringBuilder.Append(" (");
var isFirst = true;
foreach (var field in relevantFields)
{
if (!isFirst)
{
stringBuilder.Append("; ");
}
isFirst = false;
stringBuilder.Append(field.Name)
.Append(": ")
.Append(this.ExtractFieldValueOrGetError(packet.Data.AsSpan(), field, definition, definitions!));
}
stringBuilder.Append(")");
}
return (stringBuilder.ToString(), definition);
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
foreach (var watcher in this._watchers)
{
watcher.Dispose();
}
this._watchers.Clear();
}
private PacketDefinition? DeterminePacketDefinition(Packet packet)
{
var allDefinitions = packet.ToServer ? this._clientPacketDefinitions : this._serverPacketDefinitions;
if (allDefinitions is null)
{
return null;
}
int GetVersion(string name)
{
if (name.EndsWith("Extended", StringComparison.InvariantCulture))
{
return ExtendedVersionValue;
}
var match = Regex.Match(name, "^[A-Za-z]+?([0-9]{3})$");
if (match.Success)
{
return int.Parse(match.Groups[1].Value);
}
return DefaultVersionValue;
}
var filteredDefinitions = allDefinitions.Packets?
.Where(p => (byte)p.Type == packet.Type && p.Code == packet.Code && (!p.SubCodeSpecified || p.SubCode == packet.SubCode))
.Select(p => (Version: GetVersion(p.Name ?? string.Empty), Definition: p))
.OrderBy(pair => pair.Version)
.ToList();
if (filteredDefinitions is null || !filteredDefinitions.Any())
{
return null;
}
if (filteredDefinitions.Count == 1)
{
return filteredDefinitions[0].Definition;
}
if (filteredDefinitions.FirstOrDefault(d => d.Version == this._clientVersionValue) is { Definition: { Name: { } } } exactMatch)
{
return exactMatch.Definition;
}
var sameLengthPackets = filteredDefinitions.Where(d => d.Definition.Length == packet.Size).Select(d => d.Definition).ToList();
if (sameLengthPackets.Count > 0)
{
if (sameLengthPackets.Count == 1 && sameLengthPackets.First() is { Name: { } } sameLengthMatch)
{
return sameLengthMatch;
}
var filteredByDefaults = this.GetPacketDefinitionsFilteredByDefaultValues(packet, sameLengthPackets, allDefinitions).ToList();
if (filteredByDefaults.Count == 1)
{
return filteredByDefaults.First();
}
if (filteredByDefaults.Count > 0)
{
filteredDefinitions.RemoveAll(def => !filteredByDefaults.Contains(def.Definition));
}
}
var current = filteredDefinitions.First();
foreach (var def in filteredDefinitions.Skip(1))
{
if (def.Version > this._clientVersionValue)
{
break;
}
current = def;
}
return current.Definition;
}
private IEnumerable<PacketDefinition> GetPacketDefinitionsFilteredByDefaultValues(Packet packet, IEnumerable<PacketDefinition> definitions, PacketDefinitions allDefinitions)
{
foreach (var def in definitions)
{
var defaultFields = def.Fields?.TakeWhile(f => !string.IsNullOrWhiteSpace(f.DefaultValue)).ToList();
if (defaultFields is null or { Count: 0 })
{
break;
}
if (defaultFields.TrueForAll(field => int.TryParse(this.ExtractFieldValueOrGetError(packet.Data, field, def, allDefinitions), out var actual)
&& (int.TryParse(field.DefaultValue, out var target) || int.TryParse(field.DefaultValue!.Replace("0x", string.Empty), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out target))
&& actual == target))
{
yield return def;
}
}
}
private void LoadAndWatchConfiguration(Action<PacketDefinitions?> assignAction, string fileName)
{
assignAction(PacketDefinitions.Load(fileName));
var watcher = new FileSystemWatcher(Environment.CurrentDirectory, fileName);
watcher.Changed += (_, _) =>
{
PacketDefinitions? definitions;
try
{
definitions = PacketDefinitions.Load(fileName);
}
catch
{
// I know, bad practice... but when it fails, because of some invalid xml file, we just don't assign it.
return;
}
if (definitions != null)
{
assignAction(definitions);
}
};
watcher.EnableRaisingEvents = true;
this._watchers.Add(watcher);
}
/// <summary>
/// Extracts the field value from this packet or returns an error message, if it couldn't be extracted.
/// </summary>
/// <param name="data">The data.</param>
/// <param name="field">The field definition.</param>
/// <param name="packet">The packet.</param>
/// <param name="definitions">The definitions.</param>
/// <returns>
/// The value of the field or the error message.
/// </returns>
private string ExtractFieldValueOrGetError(Span<byte> data, Field field, PacketDefinition packet, PacketDefinitions definitions)
{
try
{
return this.ExtractFieldValue(data, field, packet, definitions);
}
catch (Exception e)
{
return $"{e.GetType().Name}: {e.Message}";
}
}
/// <summary>
/// Extracts the field value from this packet.
/// </summary>
/// <param name="data">The data.</param>
/// <param name="field">The field definition.</param>
/// <param name="packet">The packet.</param>
/// <param name="definitions">The definitions.</param>
/// <returns>
/// The value of the field.
/// </returns>
private string ExtractFieldValue(Span<byte> data, Field field, PacketDefinition packet, PacketDefinitions definitions)
{
var fieldSize = field.GetFieldSizeInBytes();
if (field.Type == FieldType.String && field.Index < data.Length)
{
return data.ExtractString(field.Index, fieldSize ?? int.MaxValue, Encoding.UTF8);
}
if (field.Type == FieldType.Binary && field.Index < data.Length)
{
return fieldSize.HasValue
? data.Slice(field.Index, fieldSize.Value).AsString()
: data[field.Index..].AsString();
}
if (data.Length < field.Index + fieldSize)
{
return string.Empty;
}
return field.Type switch
{
FieldType.Byte => data[field.Index..]
.GetByteValue(field.LengthSpecified ? field.Length : 8, field.LeftShifted)
.ToString(),
FieldType.Boolean => data[field.Index..].GetBoolean(field.LeftShifted).ToString(),
FieldType.IntegerLittleEndian => ReadUInt32LittleEndian(data[field.Index..]).ToString(CultureInfo.InvariantCulture),
FieldType.IntegerBigEndian => ReadUInt32BigEndian(data[field.Index..]).ToString(CultureInfo.InvariantCulture),
FieldType.ShortLittleEndian => ReadUInt16LittleEndian(data[field.Index..]).ToString(CultureInfo.InvariantCulture),
FieldType.ShortBigEndian => ReadUInt16BigEndian(data[field.Index..]).ToString(CultureInfo.InvariantCulture),
FieldType.LongLittleEndian => ReadUInt64LittleEndian(data[field.Index..]).ToString(CultureInfo.InvariantCulture),
FieldType.LongBigEndian => ReadUInt64BigEndian(data[field.Index..]).ToString(CultureInfo.InvariantCulture),
FieldType.Enum => this.ExtractEnumValue(data, field, packet, definitions),
FieldType.StructureArray => this.ExtractStructureArrayValues(data, field, packet, definitions),
FieldType.Float => ReadSingleLittleEndian(data[field.Index..]).ToString(CultureInfo.InvariantCulture),
FieldType.Double => ReadDoubleBigEndian(data[field.Index..]).ToString(CultureInfo.InvariantCulture),
_ => string.Empty,
};
}
private string ExtractStructureArrayValues(Span<byte> data, Field arrayField, PacketDefinition packet, PacketDefinitions definitions)
{
var elementType = packet.Structures?.FirstOrDefault(s => s.Name == arrayField.TypeName)
?? definitions.Structures?.FirstOrDefault(s => s.Name == arrayField.TypeName)
?? this._commonDefinitions?.Structures?.FirstOrDefault(s => s.Name == arrayField.TypeName);
if (elementType is null)
{
return data[arrayField.Index..].AsString();
}
var countField = packet.Fields?.FirstOrDefault(f => f.Name == arrayField.ItemCountField)
?? packet.Structures?.SelectMany(s => s.Fields ?? Enumerable.Empty<Field>()).FirstOrDefault(f => f.Name == arrayField.ItemCountField);
int count = countField is null ? 0 : int.Parse(this.ExtractFieldValue(data, countField, packet, definitions), CultureInfo.InvariantCulture);
if (count == 0)
{
return string.Empty;
}
var typeLength = elementType.Length > 0 ? elementType.Length : this.DetermineFixedStructLength(data, arrayField, elementType, count);
var fixedLengthByCount = this.CalcFixStructLengthBySizeAndCount(data, arrayField, elementType, count);
var stringBuilder = new StringBuilder();
var restData = data[arrayField.Index..];
for (int i = 0; i < count; i++)
{
var currentLength = typeLength ?? this.DetermineDynamicStructLength(restData, elementType, packet) ?? fixedLengthByCount;
if (currentLength is null)
{
break;
}
var elementData = restData[..currentLength.Value];
restData = restData[currentLength.Value..];
stringBuilder.Append(Environment.NewLine)
.Append(arrayField.Name + $"[{i}]:");
stringBuilder.Append(Environment.NewLine)
.Append(" Raw: ").Append(elementData.AsString());
foreach (var structField in elementType.Fields ?? Enumerable.Empty<Field>())
{
stringBuilder.Append(Environment.NewLine)
.Append(" ").Append(structField.Name).Append(": ").Append(this.ExtractFieldValue(elementData, structField, packet, definitions));
}
}
return stringBuilder.ToString();
}
private string ExtractEnumValue(Span<byte> data, Field field, PacketDefinition packet, PacketDefinitions definitions)
{
var byteValue = data[field.Index..].GetByteValue(field.LengthSpecified ? field.Length : 8, field.LeftShifted);
var enumDefinition = packet.Enums?.FirstOrDefault(e => e.Name == field.TypeName)
?? definitions.Enums?.FirstOrDefault(e => e.Name == field.TypeName)
?? this._commonDefinitions?.Enums?.FirstOrDefault(e => e.Name == field.TypeName);
var enumValue = enumDefinition?.Values?.FirstOrDefault(v => v.Value == byteValue);
return $"{data[field.Index]} ({enumValue?.Name ?? "unknown"})";
}
private int? DetermineFixedStructLength(Span<byte> data, Field field, Structure type, int count)
{
if (type.Length > 0)
{
return type.Length;
}
return null;
}
private int? CalcFixStructLengthBySizeAndCount(Span<byte> data, Field field, Structure type, int count)
{
if (type.Fields?.All(f => f.Type != FieldType.StructureArray) ?? false)
{
return (data.Length - field.Index) / count;
}
return null;
}
/// <summary>
/// Determines the length of the dynamic structure.
/// We assume that a nested struct type has a fixed length specified in <see cref="Structure.Length"/>.
/// </summary>
/// <param name="restData">The rest data.</param>
/// <param name="type">The type.</param>
/// <param name="packetType">Type of the packet.</param>
/// <returns>The dynamic length of a struct with a nested structure array.</returns>
private int? DetermineDynamicStructLength(Span<byte> restData, Structure type, PacketDefinition packetType)
{
if (type.Fields is null)
{
return null;
}
if (packetType.Structures is not null
&& type.Fields.FirstOrDefault(f => f.Type == FieldType.StructureArray) is { } nestedStructField)
{
var countField = type.Fields.First(f => f.Name == nestedStructField.ItemCountField);
var count = restData[countField.Index];
var nestedStructType = packetType.Structures.First(s => s.Name == nestedStructField.TypeName);
return nestedStructField.Index + (count * nestedStructType.Length);
}
if (this._clientVersionValue == ExtendedVersionValue
&& type.Fields.FirstOrDefault(f => f.Type == FieldType.Binary) is { } binaryField
&& binaryField.Name?.EndsWith("ItemData") is true)
{
return binaryField.Index + this.DetermineItemSize(restData, binaryField);
}
if (type.Fields.MaxBy(f => f.Index) is { Type: not (FieldType.Binary or FieldType.StructureArray) } lastField)
{
return lastField.Index + this.FieldSize(lastField.Type);
}
return null;
}
private int DetermineItemSize(Span<byte> restData, Field binaryField)
{
var itemData = restData.Slice(binaryField.Index);
var size = 5;
var options = itemData[4];
// Option
if ((options & 1) == 1)
{
size++;
}
// Excellent
if ((options & 8) == 8)
{
size++;
}
// Ancient
if ((options & 0x10) == 0x10)
{
size++;
}
// Harmony
if ((options & 0x20) == 0x20)
{
size++;
}
// Sockets
if ((options & 0x80) == 0x80)
{
size++;
var socketCount = itemData[size] & 0xF;
size += socketCount;
}
return size;
}
private int FieldSize(FieldType fieldType)
{
return fieldType switch
{
FieldType.Byte => 1,
FieldType.Boolean => 1,
FieldType.IntegerLittleEndian => 4,
FieldType.IntegerBigEndian => 4,
FieldType.ShortLittleEndian => 2,
FieldType.ShortBigEndian => 2,
FieldType.LongLittleEndian => 8,
FieldType.LongBigEndian => 8,
FieldType.Enum => 1,
FieldType.StructureArray => 1,
FieldType.Float => 4,
FieldType.Double => 8,
_ => 1,
};
}
}

View File

@@ -0,0 +1,115 @@
namespace MUnique.OpenMU.Network.Analyzer
{
partial class PacketSenderForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private readonly System.ComponentModel.IContainer components = null!;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (this._connection is not null)
{
this._connection.PropertyChanged -= this.ConnectionOnPropertyChanged;
}
this.components?.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PacketSenderForm));
this.packetTextBox = new System.Windows.Forms.TextBox();
this.sendButton = new System.Windows.Forms.Button();
this.toClientRadioButton = new System.Windows.Forms.RadioButton();
this.toServerRadioButton = new System.Windows.Forms.RadioButton();
this.SuspendLayout();
//
// packetTextBox
//
this.packetTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.packetTextBox.ForeColor = System.Drawing.SystemColors.ControlText;
this.packetTextBox.Location = new System.Drawing.Point(12, 12);
this.packetTextBox.Multiline = true;
this.packetTextBox.Name = "packetTextBox";
this.packetTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.packetTextBox.Size = new System.Drawing.Size(567, 76);
this.packetTextBox.TabIndex = 4;
//
// sendButton
//
this.sendButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.sendButton.ForeColor = System.Drawing.SystemColors.ControlText;
this.sendButton.Location = new System.Drawing.Point(504, 94);
this.sendButton.Name = "sendButton";
this.sendButton.Size = new System.Drawing.Size(75, 23);
this.sendButton.TabIndex = 7;
this.sendButton.Text = "Send";
this.sendButton.UseVisualStyleBackColor = true;
//
// toClientRadioButton
//
this.toClientRadioButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.toClientRadioButton.AutoSize = true;
this.toClientRadioButton.Checked = true;
this.toClientRadioButton.ForeColor = System.Drawing.SystemColors.ControlText;
this.toClientRadioButton.Location = new System.Drawing.Point(12, 98);
this.toClientRadioButton.Name = "toClientRadioButton";
this.toClientRadioButton.Size = new System.Drawing.Size(71, 19);
this.toClientRadioButton.TabIndex = 6;
this.toClientRadioButton.TabStop = true;
this.toClientRadioButton.Text = "To Client";
this.toClientRadioButton.UseVisualStyleBackColor = true;
//
// toServerRadioButton
//
this.toServerRadioButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.toServerRadioButton.AutoSize = true;
this.toServerRadioButton.ForeColor = System.Drawing.SystemColors.ControlText;
this.toServerRadioButton.Location = new System.Drawing.Point(84, 98);
this.toServerRadioButton.Name = "toServerRadioButton";
this.toServerRadioButton.Size = new System.Drawing.Size(72, 19);
this.toServerRadioButton.TabIndex = 5;
this.toServerRadioButton.Text = "To Server";
this.toServerRadioButton.UseVisualStyleBackColor = true;
//
// PacketSenderForm
//
this.ClientSize = new System.Drawing.Size(591, 129);
this.Controls.Add(this.sendButton);
this.Controls.Add(this.toClientRadioButton);
this.Controls.Add(this.toServerRadioButton);
this.Controls.Add(this.packetTextBox);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "PacketSenderForm";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox packetTextBox = null!;
private System.Windows.Forms.Button sendButton = null!;
private System.Windows.Forms.RadioButton toClientRadioButton = null!;
private System.Windows.Forms.RadioButton toServerRadioButton = null!;
}
}

View File

@@ -0,0 +1,97 @@
// <copyright file="PacketSenderForm.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;
/// <summary>
/// A simple packet sender form which allows to send data packets to the client or the server.
/// </summary>
public partial class PacketSenderForm : Form
{
private readonly LiveConnection _connection = null!;
/// <summary>
/// Initializes a new instance of the <see cref="PacketSenderForm"/> class.
/// </summary>
public PacketSenderForm()
{
this.InitializeComponent();
}
/// <summary>
/// Initializes a new instance of the <see cref="PacketSenderForm"/> class.
/// </summary>
/// <param name="connection">The connection.</param>
public PacketSenderForm(LiveConnection connection)
{
this.InitializeComponent();
this._connection = connection;
this.SetText();
this.sendButton.Click += this.SendButtonClick;
connection.PropertyChanged += this.ConnectionOnPropertyChanged;
}
private void ConnectionOnPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (!this.InvokeRequired)
{
this.SetText();
return;
}
if (this.IsHandleCreated)
{
this.Invoke((Action)this.SetText);
}
}
private void SetText()
{
this.Text = $"Packet Sender ({this._connection.Name})";
if (!this._connection.IsConnected)
{
this.sendButton.Enabled = false;
}
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "Catching all Exceptions.")]
private async void SendButtonClick(object? sender, EventArgs e)
{
try
{
foreach (var line in this.packetTextBox.Lines.Where(l => !string.IsNullOrEmpty(l.Trim())))
{
if (!CapturedConnectionExtensions.TryParseArray(line.Trim(), out var data))
{
MessageBox.Show("Wrong format. Please enter the packet in hex format with a space between each byte. \n Example: C1 03 30", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (!this._connection.IsConnected)
{
return;
}
if (this.toClientRadioButton.Checked)
{
await this._connection.SendToClientAsync(data).ConfigureAwait(false);
}
else
{
await this._connection.SendToServerAsync(data).ConfigureAwait(false);
}
}
}
catch (Exception ex)
{
Debug.Fail(ex.Message, ex.StackTrace);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
// <copyright file="Program.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.Windows.Forms;
/// <summary>
/// The class of the main entry point.
/// </summary>
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
internal static void Main()
{
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// todo
}
}

View File

@@ -0,0 +1,10 @@
// <copyright file="AssemblyInfo.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
using System.Reflection;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MUnique.OpenMU.Network.Analyzer")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace MUnique.OpenMU.Network.Analyzer.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MUnique.OpenMU.Network.Analyzer.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,68 @@
# Network Analyzer
This little tool can be used to analyze the network traffic between a server
and client, when they use the mu online protocol.
It acts as a proxy, which means it waits for incoming connections and connects
to the actual server when a connection arrives. It then forwards all the
traffic between server and client.
It also decrypts incoming and encrypts outgoing traffic to allow to take a
closer look at the messages.
By default the analyzer contains packet definitions for packets which are sent
between game client and game server, defined by two separate XML files.
However, it's not limited to that. For example, you could basically write other
packet definitions and use it to analyze the communication between connect
server and game client, too. You can also edit these xml files on the fly - as
soon as they change, the analyzer reloads them automatically.
## Usage
### Setup
First, enter your local port, on which the tcp/ip listener should run at. For
example, I run it at port 55900.
Next, enter the ip and port of the (game) server you want to connect.
For example, I run a game server at 55901 on my local machine (127.x.x.x).
Next, change the MU version, if it's different from season 6. You can change
this anytime you want, however it only has effect on new connections.
Selecting the correct MU Version is required to correctly de & encrypt the
network traffic. Currently, there are 3 options for that.
Finally, click on 'Start Proxy' - then the application will listen on port
55900 and is waiting for client connections.
### Features
#### General
As soon as a client connects, it will be listed in the 'Connection' list and
the data packets are shown in the grid. When you click on one packet, it
extracts the included information based on the configured packet definition
(xml files).
It supports multiple concurrent connections, so when you click on one, you'll
see its traffic.
#### Context Menu
The connection list has the following context menu items:
* *Disconnect*: Disconnects a connected client
* *Save to file*: Saves the captured traffic into a file (*.mucap).
* *Load from file*: Loads the captured traffic from the file, so you can
continue your work.
* *Packet Sender*: Opens a new window with a simple packet sender.
## Known limitations
### Incomplete packet definitions
At the moment, at least every packet which is supported by OpenMU is contained
in the packet definitions.
There are other packets, which are not yet implemented by OpenMU, of course.
These are probably missing.
Feel free to submit pull requests to make them complete :)

View File

@@ -0,0 +1,41 @@
// <copyright file="SavedConnection.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.Analyzer;
using System.ComponentModel;
using System.IO;
/// <summary>
/// A <see cref="ICapturedConnection"/> which has been saved in a file and can be loaded again for analyzing.
/// </summary>
public class SavedConnection : ICapturedConnection
{
/// <summary>
/// Initializes a new instance of the <see cref="SavedConnection"/> class.
/// </summary>
/// <param name="filePath">The file path.</param>
public SavedConnection(string filePath)
{
this.PacketList = new BindingList<Packet>();
this.StartTimestamp = this.PacketList.LoadFromFile(filePath);
this.Name = new FileInfo(filePath).Name;
}
/// <summary>
/// Gets the name of the connection.
/// In this case it's simply the file name.
/// </summary>
public string Name { get; }
/// <summary>
/// Gets the packets of the connection.
/// </summary>
public BindingList<Packet> PacketList { get; }
/// <summary>
/// Gets the start timestamp.
/// </summary>
public DateTime StartTimestamp { get; }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,225 @@
// <copyright file="ArrayExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
/// <summary>
/// Extensions for arrays.
/// </summary>
public static class ArrayExtensions
{
/// <summary>
/// Extracts a string of an byte array with the specified encoding.
/// </summary>
/// <param name="array">The byte array.</param>
/// <param name="startIndex">The start index.</param>
/// <param name="maximumBytes">The maximum length.</param>
/// <param name="encoding">The encoding.</param>
/// <returns>The resulting string.</returns>
public static string ExtractString(this byte[] array, int startIndex, int maximumBytes, Encoding encoding)
{
int count = array.Skip(startIndex).Take(maximumBytes).TakeWhile(b => b != 0).Count();
return encoding.GetString(array, startIndex, count);
}
/// <summary>
/// Converts the byte array into a readable HEX string.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <returns>The HEX string.</returns>
public static string AsString(this byte[] bytes)
{
return BitConverter.ToString(bytes).Replace('-', ' ');
}
/// <summary>
/// Converts bytes of an array to an 32bit unsigned Integer, big endian.
/// </summary>
/// <param name="array">Byte array.</param>
/// <param name="startIndex">Starting index. The array needs 3 more elements.</param>
/// <returns>An unsigned integer.</returns>
public static uint MakeDwordBigEndian(this Span<byte> array, int startIndex)
{
var source = array.Slice(startIndex, 4);
return unchecked(((uint)source[3] << 24) | (uint)(source[2] << 16) | (uint)(source[1] << 8) | source[0]);
}
/// <summary>
/// Converts bytes of an array to an 32bit unsigned Integer, big endian.
/// </summary>
/// <param name="array">Byte array.</param>
/// <param name="startIndex">Starting index. The array needs 3 more elements.</param>
/// <returns>An unsigned integer.</returns>
public static uint MakeDwordBigEndian(this byte[] array, int startIndex) =>
MakeDwordBigEndian(array.AsSpan(), startIndex);
/// <summary>
/// Converts bytes of an array to an 32bit unsigned Integer, small endian.
/// </summary>
/// <param name="array">Byte array.</param>
/// <param name="startIndex">Starting index. The array needs 3 more elements.</param>
/// <returns>An unsigned integer.</returns>
public static uint MakeDwordSmallEndian(this Span<byte> array, int startIndex)
{
var source = array.Slice(startIndex, 4);
return unchecked(((uint)source[0] << 24) | (uint)(source[1] << 16) | (uint)(source[2] << 8) | source[3]);
}
/// <summary>
/// Converts bytes of an array to an unsigned short, small endian.
/// </summary>
/// <param name="array">The array.</param>
/// <param name="startIndex">The start index.</param>
/// <returns>An unsigned short.</returns>
public static ushort MakeWordSmallEndian(this Span<byte> array, int startIndex)
{
return (ushort)((array[startIndex] << 8) | array[startIndex + 1]);
}
/// <summary>
/// Converts bytes of an array to an unsigned short, big endian.
/// </summary>
/// <param name="array">The array.</param>
/// <param name="startIndex">The start index.</param>
/// <returns>An unsigned short.</returns>
public static ushort MakeWordBigEndian(this Span<byte> array, int startIndex)
{
return (ushort)((array[startIndex + 1] << 8) | array[startIndex]);
}
/// <summary>
/// Converts bytes of an array to an unsigned short, big endian.
/// If the array is not long enough, it returns 0.
/// </summary>
/// <param name="array">The array.</param>
/// <param name="startIndex">The start index.</param>
/// <returns>An unsigned short.</returns>
public static ushort TryMakeWordBigEndian(this Span<byte> array, int startIndex)
{
return array.Length > startIndex + 1 ? array.MakeWordBigEndian(startIndex) : default;
}
/// <summary>
/// Gets the size of the packet header.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns>The size of the header.</returns>
public static int GetPacketHeaderSize(this byte[] packet)
{
return GetPacketHeaderSize(packet[0]);
}
/// <summary>
/// Gets the size of the packet header.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns>The size of the header.</returns>
public static int GetPacketHeaderSize(this Span<byte> packet)
{
return GetPacketHeaderSize(packet[0]);
}
/// <summary>
/// Gets the size of the packet header.
/// </summary>
/// <param name="packetPrefix">The packet prefix.</param>
/// <returns>The size of the header.</returns>
public static int GetPacketHeaderSize(byte packetPrefix)
{
switch (packetPrefix)
{
case 0xC1:
case 0xC3:
return 2;
case 0xC2:
case 0xC4:
return 3;
default:
return 0;
}
}
/// <summary>
/// Gets the type of the packet. This only works when the packet type is not encrypted.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns>The type of the packet.</returns>
public static byte GetPacketType(this Span<byte> packet)
{
return packet[packet.GetPacketHeaderSize()];
}
/// <summary>
/// Gets the sub type of the packet. This only works when the packet type is not encrypted.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns>The sub type of the packet.</returns>
public static byte? GetPacketSubType(this Span<byte> packet)
{
var subTypeIndex = packet.GetPacketHeaderSize() + 1;
if (packet.Length > subTypeIndex)
{
return packet[subTypeIndex];
}
return null;
}
/// <summary>
/// Gets the size of a packet from its header.
/// C1 and C3 packets have a maximum length of 255, and the length defined in the second byte.
/// C2 and C4 packets have a maximum length of 65535, and the length defined in the second and third byte.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns>The size of a packet.</returns>
public static int GetPacketSize(this Span<byte> packet)
{
switch (packet[0])
{
case 0xC1:
case 0xC3:
return packet[1];
case 0xC2:
case 0xC4:
return packet[1] << 8 | packet[2];
default:
return 0;
}
}
/// <summary>
/// Gets the size of a packet from its header.
/// C1 and C3 packets have a maximum length of 255, and the length defined in the second byte.
/// C2 and C4 packets have a maximum length of 65535, and the length defined in the second and third byte.
/// </summary>
/// <param name="packet">The packet.</param>
/// <returns>The size of a packet.</returns>
public static int GetPacketSize(this byte[] packet)
{
return packet.AsSpan().GetPacketSize();
}
/// <summary>
/// Sets the size of the byte array as packet length in the corresponding indexes of the byte array.
/// </summary>
/// <param name="packet">The packet.</param>
public static void SetPacketSize(this Span<byte> packet)
{
var size = packet.Length;
switch (packet[0])
{
case 0xC1:
case 0xC3:
packet[1] = (byte)size;
break;
case 0xC2:
case 0xC4:
packet[1] = (byte)((size & 0xFF00) >> 8);
packet[2] = (byte)(size & 0x00FF);
break;
default:
throw new ArgumentException($"Unknown packet type {packet[0]:X}", nameof(packet));
}
}
}

View File

@@ -0,0 +1,25 @@
// <copyright file="ClientAcceptedEventArgs.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
/// <summary>
/// Event args for <see cref="Listener.ClientAccepted"/> which contains the connection of the client.
/// </summary>
public class ClientAcceptedEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="ClientAcceptedEventArgs"/> class.
/// </summary>
/// <param name="acceptedConnection">The accepted connection.</param>
public ClientAcceptedEventArgs(IConnection acceptedConnection)
{
this.AcceptedConnection = acceptedConnection;
}
/// <summary>
/// Gets the accepted connection.
/// </summary>
public IConnection AcceptedConnection { get; }
}

View File

@@ -0,0 +1,28 @@
// <copyright file="ClientAcceptingEventArgs.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.ComponentModel;
using System.Net.Sockets;
/// <summary>
/// Event args for <see cref="Listener.ClientAccepting"/> which contains the connection of the client.
/// </summary>
public class ClientAcceptingEventArgs : CancelEventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="ClientAcceptingEventArgs"/> class.
/// </summary>
/// <param name="socket">The accepting socket.</param>
public ClientAcceptingEventArgs(Socket socket)
{
this.AcceptingSocket = socket;
}
/// <summary>
/// Gets the accepted connection.
/// </summary>
public Socket AcceptingSocket { get; }
}

View File

@@ -0,0 +1,107 @@
// <copyright file="ConfigurableIpResolver.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Net;
using Microsoft.Extensions.Logging;
/// <summary>
/// A resolver, which can be re-configured during runtime.
/// </summary>
public class ConfigurableIpResolver : IIpAddressResolver
{
private readonly ILoggerFactory _loggerFactory;
private readonly bool _allowRuntimeReconfiguration;
private IpResolverType _resolverType;
private string? _parameter;
private IIpAddressResolver? _effectiveResolver;
/// <summary>
/// Initializes a new instance of the <see cref="ConfigurableIpResolver"/> class.
/// </summary>
/// <param name="resolverType">Type of the resolver.</param>
/// <param name="parameter">The parameter.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="allowRuntimeReconfiguration">
/// If set to <c>false</c>, calls to <see cref="Configure"/> are ignored after construction.
/// </param>
/// <exception cref="System.ArgumentException">When using a custom resolver type, a parameter with an IP or host name is required. - parameter.</exception>
public ConfigurableIpResolver(IpResolverType resolverType, string? parameter, ILoggerFactory loggerFactory, bool allowRuntimeReconfiguration = true)
{
this._loggerFactory = loggerFactory;
this._allowRuntimeReconfiguration = allowRuntimeReconfiguration;
this.ApplyConfiguration(resolverType, parameter, raiseEvent: false);
}
/// <summary>
/// Occurs when the configuration has been changed.
/// </summary>
public event EventHandler? ConfigurationChanged;
/// <inheritdoc />
public async ValueTask<IPAddress> ResolveIPv4Async()
{
var resolver = this._effectiveResolver ??= this.CreateResolver();
return await resolver.ResolveIPv4Async().ConfigureAwait(false);
}
/// <summary>
/// Configures this resolver.
/// </summary>
/// <param name="resolverType">Type of the resolver.</param>
/// <param name="parameter">The parameter.</param>
public void Configure(IpResolverType resolverType, string? parameter)
{
if (!this._allowRuntimeReconfiguration)
{
return;
}
this.ApplyConfiguration(resolverType, parameter, raiseEvent: true);
}
private void ApplyConfiguration(IpResolverType resolverType, string? parameter, bool raiseEvent)
{
if (resolverType == IpResolverType.Custom && string.IsNullOrWhiteSpace(parameter))
{
throw new ArgumentException("When using a custom resolver type, a parameter with an IP or host name is required.", nameof(parameter));
}
this._effectiveResolver = null;
this._resolverType = resolverType;
this._parameter = parameter;
if (raiseEvent)
{
this.ConfigurationChanged?.Invoke(this, EventArgs.Empty);
}
}
private IIpAddressResolver CreateResolver()
{
switch (this._resolverType)
{
case IpResolverType.Local:
return new LocalIpResolver();
case IpResolverType.Loopback:
return new LoopbackIpResolver();
case IpResolverType.Custom when IPAddress.TryParse(this._parameter, out var ip):
return new CustomIpResolver(ip);
case IpResolverType.Custom:
return new HostNameIpResolver(this._parameter!);
case IpResolverType.Auto when Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development":
// During development, we use a loopback IP (127.127.127.127).
return new LoopbackIpResolver();
// In production our systems should expose itself with their corresponding public IPs.
case IpResolverType.Auto:
case IpResolverType.Public:
default:
return new PublicIpResolver(this._loggerFactory.CreateLogger<PublicIpResolver>());
}
}
}

218
src/Network/Connection.cs Normal file
View File

@@ -0,0 +1,218 @@
// <copyright file="Connection.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Buffers;
using System.Diagnostics;
using System.Diagnostics.Metrics;
using System.IO.Pipelines;
using System.Net;
using System.Threading;
using Microsoft.Extensions.Logging;
using MUnique.OpenMU.Network.SimpleModulus;
using MUnique.OpenMU.PlugIns;
using Nito.AsyncEx;
using Nito.AsyncEx.Synchronous;
using Pipelines.Sockets.Unofficial;
/// <summary>
/// A connection which works on <see cref="IDuplexPipe"/>.
/// </summary>
/// <seealso cref="MUnique.OpenMU.Network.PacketPipeReaderBase" />
public sealed class Connection : PacketPipeReaderBase, IConnection
{
private static readonly ActivitySource ActivitySource = new(typeof(Connection).FullName ?? nameof(Connection));
private static readonly Meter ConnectionMeter = new(MeterName);
private static readonly Counter<long> IncomingBytesCounter = ConnectionMeter.CreateCounter<long>("IncomingBytes", "bytes");
private static readonly Counter<long> OutgoingBytesCounter = ConnectionMeter.CreateCounter<long>("OutgoingBytes", "bytes");
private static readonly Counter<long> InvalidBlocksCounter = ConnectionMeter.CreateCounter<long>("InvalidBlocks");
private static readonly Counter<long> ConnectionCounter = ConnectionMeter.CreateCounter<long>("ConnectionCount");
/// <summary>
/// The start of an RDP connection attempt.
/// </summary>
/// <remarks>
/// Some hackers try to break into servers.
/// The packet mostly contains the content "Cookie: mstshash=Administr".
/// </remarks>
private static readonly byte[] RdpConnectionAttemptHeader = { 0x03, 0x00, 0x00 };
private readonly IPipelinedEncryptor? _encryptionPipe;
private readonly ILogger<Connection> _logger;
private readonly EndPoint _remoteEndPoint;
private IDuplexPipe? _duplexPipe;
private bool _disconnected;
private PipeWriter? _outputWriter;
/// <summary>
/// Initializes a new instance of the <see cref="Connection" /> class.
/// </summary>
/// <param name="duplexPipe">The duplex pipe of the (socket) connection.</param>
/// <param name="decryptionPipe">The decryption pipe.</param>
/// <param name="encryptionPipe">The encryption pipe.</param>
/// <param name="logger">The logger.</param>
public Connection(IDuplexPipe duplexPipe, IPipelinedDecryptor? decryptionPipe, IPipelinedEncryptor? encryptionPipe, ILogger<Connection> logger)
{
this._duplexPipe = duplexPipe;
this._encryptionPipe = encryptionPipe;
this._logger = logger;
this.Source = decryptionPipe?.Reader ?? this._duplexPipe!.Input;
this._remoteEndPoint = this.SocketConnection?.Socket.RemoteEndPoint ?? new IPEndPoint(IPAddress.Any, 0);
this.LocalEndPoint = this.SocketConnection?.Socket.LocalEndPoint;
this.OutputLock = new();
}
/// <inheritdoc />
public event AsyncEventHandler<ReadOnlySequence<byte>>? PacketReceived;
/// <inheritdoc />
public event AsyncEventHandler? Disconnected;
/// <inheritdoc />
public bool Connected => this.SocketConnection != null ? this.SocketConnection.ShutdownKind == PipeShutdownKind.None && !this._disconnected : !this._disconnected;
/// <inheritdoc />
public EndPoint? EndPoint => this._remoteEndPoint;
/// <inheritdoc />
public EndPoint? LocalEndPoint { get; }
/// <inheritdoc />
public PipeWriter Output => this._outputWriter ??= new ExtendedPipeWriter(this._encryptionPipe?.Writer ?? this._duplexPipe!.Output, OutgoingBytesCounter);
/// <inheritdoc />
public AsyncLock OutputLock { get; }
/// <summary>
/// Gets the name of the meter.
/// </summary>
internal static string MeterName => typeof(Connection).FullName ?? nameof(Connection);
/// <summary>
/// Gets the socket connection, if the <see cref="_duplexPipe"/> is an instance of <see cref="SocketConnection"/>. Otherwise, it returns null.
/// </summary>
private SocketConnection? SocketConnection => this._duplexPipe as SocketConnection;
/// <inheritdoc/>
public override string ToString() => this._remoteEndPoint?.ToString() ?? $"{base.ToString()} {this.GetHashCode()}";
/// <inheritdoc/>
public async Task BeginReceiveAsync()
{
try
{
ConnectionCounter.Add(1);
await this.ReadSourceAsync().ConfigureAwait(false);
}
catch (OperationCanceledException)
{
// not an error which we need to handle.
}
catch (Exception ex)
{
await this.OnCompleteAsync(ex).ConfigureAwait(false);
return;
}
await this.OnCompleteAsync(null).ConfigureAwait(false);
}
/// <inheritdoc />
public async ValueTask DisconnectAsync()
{
using var scope = this._logger.BeginScope(this._remoteEndPoint);
if (this._disconnected)
{
this._logger.LogDebug("Connection already disconnected.");
return;
}
ConnectionCounter.Add(-1);
this._logger.LogDebug("Disconnecting...");
if (this._duplexPipe is not null)
{
await this.Source.CompleteAsync().ConfigureAwait(false);
await this.Output.CompleteAsync().ConfigureAwait(false);
(this._duplexPipe as IDisposable)?.Dispose();
this._duplexPipe = null;
}
this._logger.LogDebug("Disconnected");
this._disconnected = true;
await this.Disconnected.SafeInvokeAsync().ConfigureAwait(false);
}
/// <inheritdoc/>
public void Dispose()
{
this.DisconnectAsync().AsTask().WaitAndUnwrapException();
this.PacketReceived = null;
this.Disconnected = null;
}
/// <inheritdoc />
protected override async ValueTask OnCompleteAsync(Exception? exception)
{
using var scope = this._logger.BeginScope(this._remoteEndPoint);
if (exception is InvalidBlockChecksumException)
{
InvalidBlocksCounter.Add(1, new KeyValuePair<string, object?>("RemoteEndPoint", this._remoteEndPoint));
}
if (exception != null)
{
if (exception is ConnectionResetException)
{
this._logger.LogInformation(exception, "Connection was closed.");
}
else if (exception is ConnectionAbortedException)
{
this._logger.LogInformation(exception, "Connection was aborted by the server.");
}
else if (exception is InvalidOperationException && exception.Message == "Reading is not allowed after reader was completed.")
{
this._logger.LogInformation(exception, "Reader was completed.");
}
else if (exception is InvalidPacketHeaderException packetHeaderException
&& packetHeaderException.Header.Take(3).SequenceEqual(RdpConnectionAttemptHeader))
{
this._logger.LogWarning("Connection will be closed, RDP connection attempt by {endPoint}", this.EndPoint);
}
else
{
this._logger.LogError(exception, "Connection will be disconnected, because of an exception");
}
}
await this.Output.CompleteAsync(exception).ConfigureAwait(false);
await this.DisconnectAsync().ConfigureAwait(false);
}
/// <summary>
/// Reads the mu online packet by raising <see cref="PacketReceived" />.
/// </summary>
/// <param name="packet">The mu online packet.</param>
/// <returns><see langword="true" />, if the flush was successful or not required.<see langword="false" />, if the pipe reader is completed and no longer reading data.</returns>
protected override async ValueTask<bool> ReadPacketAsync(ReadOnlySequence<byte> packet)
{
IncomingBytesCounter.Add(packet.Length);
using var activity = ActivitySource.CreateActivity("Read Packet", ActivityKind.Server);
activity?.SetTag("remoteEndPoint", this._remoteEndPoint)
.SetTag("rawPacket", packet)
.Start();
try
{
await this.PacketReceived.SafeInvokeAsync(packet).ConfigureAwait(false);
return true;
}
finally
{
activity?.Stop();
}
}
}

View File

@@ -0,0 +1,29 @@
// <copyright file="ConnectionExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
/// <summary>
/// Extension methods for <see cref="IConnection"/>.
/// </summary>
public static class ConnectionExtensions
{
/// <summary>
/// Sends a message asynchronously.
/// </summary>
/// <param name="connection">The connection.</param>
/// <param name="packetBuilder">The packet builder which writes to the <see cref="IConnection.Output"/> and returns the length of the packet in bytes.</param>
public static async ValueTask SendAsync(this IConnection connection, Func<int> packetBuilder)
{
if (!connection.Connected)
{
return;
}
using var l = await connection.OutputLock.LockAsync().ConfigureAwait(false);
var length = packetBuilder();
connection.Output.Advance(length);
await connection.Output.FlushAsync().ConfigureAwait(false);
}
}

90
src/Network/Counter.cs Normal file
View File

@@ -0,0 +1,90 @@
// <copyright file="Counter.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
/// <summary>
/// Used as C3/C4 Packet Counter, and Skill Count.
/// When the maximum count is getting exceeded,
/// the counter will jump back to the minimum counter value.
/// </summary>
public class Counter
{
private readonly byte _maxCount;
private readonly byte _minCount;
private readonly object _lockObject = new();
private int _counter;
/// <summary>
/// Initializes a new instance of the <see cref="Counter"/> class.
/// </summary>
public Counter()
{
this._maxCount = 255;
}
/// <summary>
/// Initializes a new instance of the <see cref="Counter"/> class.
/// </summary>
/// <param name="min">The minimum counter value.</param>
/// <param name="max">The maximum counter value.</param>
public Counter(byte min, byte max)
{
this._minCount = min;
this._maxCount = max;
}
/// <summary>
/// Gets or sets the count.
/// </summary>
/// <value>
/// The count.
/// </value>
public int Count
{
get
{
lock (this._lockObject)
{
return this._counter;
}
}
set
{
lock (this._lockObject)
{
this._counter = value;
}
}
}
/// <summary>
/// Increases the counter value.
/// When the maximum count is getting exceeded,
/// the counter will jump back to the minimum counter value.
/// </summary>
public void Increase()
{
lock (this._lockObject)
{
if (this._counter == this._maxCount)
{
this._counter = this._minCount;
}
else
{
this._counter++;
}
}
}
/// <summary>
/// Resets the count to the minimum value.
/// </summary>
public void Reset()
{
this.Count = this._minCount;
}
}

View File

@@ -0,0 +1,28 @@
// <copyright file="CustomIpResolver.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Net;
using System.Threading.Tasks;
/// <summary>
/// Resolver which always returns the provided custom ip address.
/// </summary>
public class CustomIpResolver : IIpAddressResolver
{
private readonly IPAddress _address;
/// <summary>
/// Initializes a new instance of the <see cref="CustomIpResolver"/> class.
/// </summary>
/// <param name="address">The address.</param>
public CustomIpResolver(IPAddress address)
{
this._address = address;
}
/// <inheritdoc />
public ValueTask<IPAddress> ResolveIPv4Async() => ValueTask.FromResult(this._address);
}

44
src/Network/DuplexPipe.cs Normal file
View File

@@ -0,0 +1,44 @@
// <copyright file="DuplexPipe.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.IO.Pipelines;
/// <summary>
/// A simple implementation of a <see cref="IDuplexPipe"/> which is helpful for testing.
/// It's pipes are configured to forward incoming data as soon as they are written.
/// </summary>
public class DuplexPipe : IDuplexPipe
{
/// <summary>
/// Initializes a new instance of the <see cref="DuplexPipe"/> class.
/// </summary>
/// <param name="options">The optional pipe options. If null, the default options are applied.</param>
public DuplexPipe(PipeOptions? options = null)
{
this.SendPipe = new Pipe(options ?? PipeOptions.Default);
this.ReceivePipe = new Pipe(options ?? PipeOptions.Default);
}
/// <summary>
/// Gets the send pipe.
/// </summary>
public Pipe SendPipe { get; }
/// <summary>
/// Gets the receive pipe.
/// </summary>
public Pipe ReceivePipe { get; }
/// <summary>
/// Gets the input pipe reader. It's the reader of the <see cref="ReceivePipe"/>.
/// </summary>
public PipeReader Input => this.ReceivePipe.Reader;
/// <summary>
/// Gets the output pipe writer. It's the writer of the <see cref="SendPipe"/>.
/// </summary>
public PipeWriter Output => this.SendPipe.Writer;
}

View File

@@ -0,0 +1,68 @@
// <copyright file="ExtendedPipeWriter.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Diagnostics.Metrics;
using System.IO.Pipelines;
using System.Threading;
/// <summary>
/// A wrapper for an existing <see cref="PipeWriter"/>, which has metrics about the written bytes.
/// </summary>
public class ExtendedPipeWriter : PipeWriter
{
private readonly PipeWriter _target;
private readonly Counter<long> _writeCounter;
/// <summary>
/// Initializes a new instance of the <see cref="ExtendedPipeWriter"/> class.
/// </summary>
/// <param name="target">The target <see cref="PipeWriter"/>.</param>
/// <param name="writeCounter">A counter for the written bytes.</param>
public ExtendedPipeWriter(PipeWriter target, Counter<long> writeCounter)
{
this._target = target;
this._writeCounter = writeCounter;
}
/// <inheritdoc />
public override void Complete(Exception? exception = null)
{
this._target.Complete(exception);
}
/// <inheritdoc />
public override void CancelPendingFlush()
{
this._target.CancelPendingFlush();
}
/// <inheritdoc />
public override ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken = default)
{
return this._target.FlushAsync(cancellationToken);
}
/// <inheritdoc />
public override void Advance(int bytes)
{
this._target.Advance(bytes);
this._writeCounter.Add(bytes);
}
/// <inheritdoc />
public override Memory<byte> GetMemory(int sizeHint = 0)
{
return this._target.GetMemory(sizeHint);
}
/// <inheritdoc />
public override Span<byte> GetSpan(int sizeHint = 0)
{
var span = this._target.GetSpan(sizeHint);
span.Clear();
return span;
}
}

View File

@@ -0,0 +1,7 @@
// <copyright file="GlobalUsings.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
#pragma warning disable SA1200 // Using directives should be placed correctly
global using MUnique.OpenMU.Network.Properties;

View File

@@ -0,0 +1,50 @@
// <copyright file="HostNameIpResolver.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Net;
/// <summary>
/// Resolves the ip address by resolving a host name to get the <see cref="IPAddress"/> over DNS.
/// </summary>
public class HostNameIpResolver : IIpAddressResolver
{
private readonly string _hostName;
/// <summary>
/// Initializes a new instance of the <see cref="HostNameIpResolver"/> class.
/// </summary>
/// <param name="hostName">Name of the host.</param>
public HostNameIpResolver(string hostName)
{
this._hostName = hostName;
}
/// <inheritdoc />
public virtual async ValueTask<IPAddress> ResolveIPv4Async()
{
return await this.ResolveAsync().ConfigureAwait(false)
?? throw new InvalidOperationException("The host name could not be resolved.");
}
/// <summary>
/// Gets the resolved IPv4, if available.
/// </summary>
/// <returns>The resolved IPv4.</returns>
protected async ValueTask<IPAddress?> ResolveAsync()
{
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
return null;
}
var hostEntry = await Dns.GetHostEntryAsync(this._hostName).ConfigureAwait(false);
var ipAddress = hostEntry.AddressList
.FirstOrDefault(address => address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork
&& !IPAddress.IsLoopback(address));
return ipAddress;
}
}

View File

@@ -0,0 +1,73 @@
// <copyright file="IConnection.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Buffers;
using System.IO.Pipelines;
using System.Net;
using MUnique.OpenMU.PlugIns;
using Nito.AsyncEx;
/// <summary>
/// Interface for a connection.
/// </summary>
/// <seealso cref="System.IDisposable" />
public interface IConnection : IDisposable
{
/// <summary>
/// Occurs when a new packet got received.
/// </summary>
/// <remarks>
/// Remove and implement <see cref="IDuplexPipe"/> instead?
/// </remarks>
event AsyncEventHandler<ReadOnlySequence<byte>>? PacketReceived;
/// <summary>
/// Occurs when the client disconnected.
/// </summary>
event AsyncEventHandler? Disconnected;
/// <summary>
/// Gets a value indicating whether this <see cref="IConnection"/> is connected.
/// </summary>
/// <value>
/// <c>true</c> if connected; otherwise, <c>false</c>.
/// </value>
bool Connected { get; }
/// <summary>
/// Gets the remote endpoint of the connection.
/// </summary>
EndPoint? EndPoint { get; }
/// <summary>
/// Gets the local endpoint of the connection.
/// </summary>
EndPoint? LocalEndPoint { get; }
/// <summary>
/// Gets the pipe writer to send data.
/// </summary>
/// <value>
/// The pipe writer.
/// </value>
PipeWriter Output { get; }
/// <summary>
/// Gets an <see cref="AsyncLock"/> to synchronize writes to the <see cref="Output"/>.
/// </summary>
AsyncLock OutputLock { get; }
/// <summary>
/// Begins receiving from the client.
/// </summary>
/// <returns>The async task.</returns>
Task BeginReceiveAsync();
/// <summary>
/// Disconnects this instance.
/// </summary>
ValueTask DisconnectAsync();
}

View File

@@ -0,0 +1,19 @@
// <copyright file="IIpAddressResolver.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Net;
/// <summary>
/// Interface for an <see cref="IPAddress"/> resolver.
/// </summary>
public interface IIpAddressResolver
{
/// <summary>
/// Gets the resolved IPv4.
/// </summary>
/// <returns>The resolved IPv4.</returns>
ValueTask<IPAddress> ResolveIPv4Async();
}

View File

@@ -0,0 +1,18 @@
// <copyright file="IPipelinedDecryptor.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.IO.Pipelines;
/// <summary>
/// Interface for a pipelined decryptor.
/// </summary>
public interface IPipelinedDecryptor
{
/// <summary>
/// Gets the reader of the decryptor which contains the decrypted data.
/// </summary>
PipeReader Reader { get; }
}

View File

@@ -0,0 +1,20 @@
// <copyright file="IPipelinedEncryptor.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.IO.Pipelines;
/// <summary>
/// Interface for a pipelined encryptor.
/// </summary>
public interface IPipelinedEncryptor
{
/// <summary>
/// Gets the writer of the encryptor which takes the decrypted data.
/// The implementation can decide to foward the data written to it
/// to another pipe.
/// </summary>
PipeWriter Writer { get; }
}

View File

@@ -0,0 +1,17 @@
// <copyright file="ISpanDecryptor.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
/// <summary>
/// This interface specifies an decryptor, which decrypts span data packets in-place.
/// </summary>
public interface ISpanDecryptor
{
/// <summary>
/// Decrypts the packet.
/// </summary>
/// <param name="packet">The encrypted data packet. The decrypted result will be written back to the same span.</param>
void Decrypt(Span<byte> packet);
}

View File

@@ -0,0 +1,17 @@
// <copyright file="ISpanEncryptor.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
/// <summary>
/// This interface specifies an encryptor, which encrypts span data packets in-place.
/// </summary>
public interface ISpanEncryptor
{
/// <summary>
/// Encrypts the packet.
/// </summary>
/// <param name="packet">The decrypted data packet.</param>
void Encrypt(Span<byte> packet);
}

View File

@@ -0,0 +1,67 @@
// <copyright file="InvalidPacketHeaderException.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Buffers;
using System.Globalization;
/// <summary>
/// An exception which occurs when a packet header is invalid.
/// </summary>
/// <remarks>
/// This can be the case when:
/// * The first byte of the packet is not one of <c>0xC1</c>, <c>0xC2</c>, <c>0xC3</c>, <c>0xC4</c>.
/// * The length is defined as 0.
/// </remarks>
/// <seealso cref="System.Exception" />
public class InvalidPacketHeaderException : Exception
{
/// <summary>
/// The message, if built yet.
/// </summary>
private string? _message;
/// <summary>
/// Initializes a new instance of the <see cref="InvalidPacketHeaderException"/> class.
/// </summary>
/// <param name="header">The header which is invalid.</param>
/// <param name="bufferContent">Content of the buffer when the header was read. With this information you can e.g. find out if a previous packet was malformed.</param>
/// <param name="position">The position of the <paramref name="header"/> in the <paramref name="bufferContent"/>.</param>
public InvalidPacketHeaderException(byte[] header, ReadOnlySequence<byte> bufferContent, SequencePosition position)
{
this.Header = header.ToArray();
this.BufferContent = bufferContent.ToArray();
this.Position = position.GetInteger();
}
/// <summary>
/// Gets the header which is invalid.
/// </summary>
public byte[] Header { get; }
/// <summary>
/// Gets the content of the buffer when the header was read. With this information you can e.g. find out if a previous packet was malformed.
/// </summary>
public byte[] BufferContent { get; }
/// <summary>
/// Gets the position of the <see cref="Header"/> in the <see cref="BufferContent"/>.
/// </summary>
public int Position { get; }
/// <summary>
/// Gets a message that describes the current exception.
/// </summary>
public override string Message => this._message ??= this.BuildMessage();
private string BuildMessage()
{
var stringBuilder = new StringBuilder();
stringBuilder.Append("The packet header is invalid: ").AppendLine(this.Header.AsString())
.Append("Buffer position: ").AppendLine(this.Position.ToString(CultureInfo.InvariantCulture))
.Append("Buffer content: ").AppendLine(this.BufferContent.AsString());
return stringBuilder.ToString();
}
}

View File

@@ -0,0 +1,39 @@
// <copyright file="IpAddressExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Diagnostics.CodeAnalysis;
using System.Net;
/// <summary>
/// Extensions for <see cref="IPAddress"/>.
/// </summary>
public static class IpAddressExtensions
{
private static HashSet<IPAddress>? _localIpAddresses;
/// <summary>
/// Determines whether the address in on same (this) host.
/// </summary>
/// <param name="address">The next server address.</param>
/// <returns>
/// <c>true</c> if the specified address is on same host as this machine; otherwise, <c>false</c>.
/// </returns>
public static bool IsOnSameHost([NotNullWhen(true)] this IPAddress? address)
{
if (address is null)
{
return false;
}
if (IPAddress.IsLoopback(address))
{
return true;
}
_localIpAddresses ??= Dns.GetHostAddresses(Dns.GetHostName()).ToHashSet();
return _localIpAddresses.Contains(address);
}
}

View File

@@ -0,0 +1,124 @@
// <copyright file="IpAddressResolverFactory.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using Microsoft.Extensions.Logging;
/// <summary>
/// Factory which creates an <see cref="IIpAddressResolver"/> depending on command line arguments.
/// </summary>
public static class IpAddressResolverFactory
{
private const string ResolveParameterPrefix = "-resolveIP:";
private const string PublicIpResolve = "-resolveIP:public";
private const string LocalIpResolve = "-resolveIP:local";
private const string LoopbackIpResolve = "-resolveIP:loopback";
/// <summary>
/// Determines the ip resolver based on command line arguments.
/// </summary>
/// <param name="args">The arguments.</param>
/// <param name="configuration">The configuration, if available.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <returns>The determined resolver.</returns>
public static IIpAddressResolver CreateIpResolver(string[] args, (IpResolverType, string?)? configuration, ILoggerFactory loggerFactory)
{
var (resolver, source) = DetermineBestFittingResolverWithSource(args, configuration);
var allowRuntimeReconfiguration = source is not ResolverSource.StartParameter and not ResolverSource.EnvironmentVariable;
return new ConfigurableIpResolver(resolver.Type, resolver.Parameter, loggerFactory, allowRuntimeReconfiguration);
}
/// <summary>
/// Determines the best fitting ip resolver.
/// </summary>
/// <param name="args">The arguments.</param>
/// <param name="configuration">The configuration.</param>
/// <returns>The resolver type with its parameter.</returns>
public static (IpResolverType Type, string? Parameter) DetermineBestFittingResolver(string[] args, (IpResolverType Type, string? Parameter)? configuration = default)
{
var (resolver, _) = DetermineBestFittingResolverWithSource(args, configuration);
return resolver;
}
private static (IpResolverType Type, string? Parameter)? DetermineIpResolverByParameters(string[] args)
{
var parameter = GetParameter(args)?.Trim();
if (string.IsNullOrWhiteSpace(parameter))
{
return default;
}
return parameter! switch
{
{ } when parameter.Equals(LoopbackIpResolve, StringComparison.InvariantCultureIgnoreCase) => (IpResolverType.Loopback, null),
{ } when parameter.Equals(PublicIpResolve, StringComparison.InvariantCultureIgnoreCase) => (IpResolverType.Public, null),
{ } when parameter.Equals(LocalIpResolve, StringComparison.InvariantCultureIgnoreCase) => ((IpResolverType, string?)?)(IpResolverType.Local, null),
_ => (IpResolverType.Custom, ExtractIpFromParameter(parameter)),
};
}
private static (IpResolverType Type, string? Parameter)? DetermineResolverByEnvironmentVariable(string variableName = "RESOLVE_IP")
{
if (Environment.GetEnvironmentVariable(variableName) is { } resolveIp
&& !string.IsNullOrWhiteSpace(resolveIp))
{
return resolveIp switch
{
"local" => (IpResolverType.Local, null),
"public" => (IpResolverType.Public, null),
"loopback" => (IpResolverType.Loopback, null),
_ => (IpResolverType.Custom, resolveIp),
};
}
return default;
}
private static (IpResolverType Type, string? Parameter) DetermineResolverByEnvironment()
{
var isDevelopmentEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";
if (isDevelopmentEnvironment)
{
// During development, we use a loopback IP (127.127.127.127).
return (IpResolverType.Loopback, null);
}
// In production our systems should expose itself with their corresponding public IPs.
return (IpResolverType.Public, null);
}
private static string ExtractIpFromParameter(string parameter) => parameter.Substring(parameter.IndexOf(':') + 1);
private static string? GetParameter(string[] args) => args.FirstOrDefault(a => a.StartsWith(ResolveParameterPrefix, StringComparison.InvariantCultureIgnoreCase));
private static ((IpResolverType Type, string? Parameter) Resolver, ResolverSource Source) DetermineBestFittingResolverWithSource(string[] args, (IpResolverType Type, string? Parameter)? configuration = default)
{
if (DetermineIpResolverByParameters(args) is { } byParameters)
{
return (byParameters, ResolverSource.StartParameter);
}
if (DetermineResolverByEnvironmentVariable() is { } byEnvironmentVariable)
{
return (byEnvironmentVariable, ResolverSource.EnvironmentVariable);
}
if (configuration is { } byConfiguration)
{
return (byConfiguration, ResolverSource.Configuration);
}
return (DetermineResolverByEnvironment(), ResolverSource.Environment);
}
private enum ResolverSource
{
StartParameter,
EnvironmentVariable,
Configuration,
Environment,
}
}

View File

@@ -0,0 +1,44 @@
// <copyright file="IpResolverType.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.ComponentModel.DataAnnotations;
/// <summary>
/// Defines how the own IP should be resolved and reported to the game client.
/// </summary>
public enum IpResolverType
{
/// <summary>
/// The IP is detected automatically by considering the environment.
/// </summary>
[Display(ResourceType = typeof(Resources), Name = nameof(Resources.IpResolverType_Auto_Name), Description = nameof(Resources.IpResolverType_Auto_Description))]
Auto,
/// <summary>
/// The IP is detected by asking an external service. As a result, we resolve
/// to the public IP.
/// </summary>
[Display(ResourceType = typeof(Resources), Name = nameof(Resources.IpResolverType_Public_Name), Description = nameof(Resources.IpResolverType_Public_Description))]
Public,
/// <summary>
/// The IP is detected by asking the DNS about the IP of the own host name.
/// </summary>
[Display(ResourceType = typeof(Resources), Name = "IpResolverType_Local_Name", Description = "IpResolverType_Local_Description")]
Local,
/// <summary>
/// The IP is resolved as '127.127.127.127'.
/// </summary>
[Display(ResourceType = typeof(Resources), Name = "IpResolverType_Loopback_Name", Description = "IpResolverType_Loopback_Description")]
Loopback,
/// <summary>
/// The IP or a host name can be set manually.
/// </summary>
[Display(ResourceType = typeof(Resources), Name = "IpResolverType_Custom_Name", Description = "IpResolverType_Custom_Description")]
Custom,
}

168
src/Network/Listener.cs Normal file
View File

@@ -0,0 +1,168 @@
// <copyright file="Listener.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.IO.Pipelines;
using System.Net;
using System.Net.Sockets;
using Microsoft.Extensions.Logging;
using MUnique.OpenMU.PlugIns;
using Pipelines.Sockets.Unofficial;
/// <summary>
/// A tcp listener which automatically creates instances of <see cref="Connection"/>s for accepted clients.
/// </summary>
public class Listener
{
private readonly ILogger _logger;
private readonly int _port;
private readonly Func<PipeReader, IPipelinedDecryptor?>? _decryptorCreator;
private readonly Func<PipeWriter, IPipelinedEncryptor?>? _encryptorCreator;
private readonly ILoggerFactory _loggerFactory;
private TcpListener? _clientListener;
/// <summary>
/// Initializes a new instance of the <see cref="Listener" /> class.
/// </summary>
/// <param name="port">The port on which the tcp listener should listen to.</param>
/// <param name="decryptorCreator">The decryptor creator function.</param>
/// <param name="encryptorCreator">The encryptor creator function.</param>
/// <param name="loggerFactory">The logger factory.</param>
public Listener(int port, Func<PipeReader, IPipelinedDecryptor?>? decryptorCreator, Func<PipeWriter, IPipelinedEncryptor?>? encryptorCreator, ILoggerFactory loggerFactory)
{
this._port = port;
this._decryptorCreator = decryptorCreator;
this._encryptorCreator = encryptorCreator;
this._loggerFactory = loggerFactory;
this._logger = this._loggerFactory.CreateLogger<Listener>();
}
/// <summary>
/// Occurs when a client has been accepted by the tcp listener.
/// </summary>
public event AsyncEventHandler<ClientAcceptedEventArgs>? ClientAccepted;
/// <summary>
/// Occurs when a client has been accepted by the tcp listener, but before a <see cref="Connection"/> is created.
/// </summary>
public event AsyncEventHandler<ClientAcceptingEventArgs>? ClientAccepting;
/// <summary>
/// Gets a value indicating whether this listener is bound to a specific local port.
/// </summary>
public bool IsBound => this._clientListener?.Server.IsBound ?? false;
/// <summary>
/// Starts the tcp listener and begins to accept connections.
/// </summary>
/// <param name="backlog">The maximum length of the pending connections queue.</param>
public void Start(int backlog = (int)SocketOptionName.MaxConnections)
{
this._clientListener = new TcpListener(IPAddress.Any, this._port);
this._clientListener.Start(backlog);
this._clientListener.BeginAcceptSocket(this.OnAccept, null);
}
/// <summary>
/// Stops the tcp listener.
/// </summary>
public void Stop()
{
this._clientListener?.Stop();
}
/// <summary>
/// Creates the decryptor for the specified reader.
/// </summary>
/// <param name="reader">The reader.</param>
/// <returns>The created decryptor.</returns>
protected virtual IPipelinedDecryptor? CreateDecryptor(PipeReader reader)
{
return this._decryptorCreator?.Invoke(reader);
}
/// <summary>
/// Creates the encryptor for the specified writer.
/// </summary>
/// <param name="writer">The writer.</param>
/// <returns>The created encryptor.</returns>
protected virtual IPipelinedEncryptor? CreateEncryptor(PipeWriter writer)
{
return this._encryptorCreator?.Invoke(writer);
}
private IConnection CreateConnection(Socket clientSocket)
{
var socketConnection = SocketConnection.Create(clientSocket);
return new Connection(socketConnection, this.CreateDecryptor(socketConnection.Input), this.CreateEncryptor(socketConnection.Output), this._loggerFactory.CreateLogger<Connection>());
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "Exceptions are catched.")]
private async void OnAccept(IAsyncResult result)
{
try
{
Socket socket;
try
{
if (this._clientListener is null)
{
return;
}
socket = this._clientListener.EndAcceptSocket(result);
}
catch (ObjectDisposedException)
{
// this exception is expected when the clientListener got disposed. In this case we don't want to spam the log.
return;
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.OperationAborted)
{
this._logger.LogDebug(ex, "The listener was stopped.");
return;
}
catch (Exception ex)
{
this._logger.LogError(ex, "Error accepting the client socket");
return;
}
// Accept the next client:
if (this._clientListener?.Server.IsBound ?? false)
{
// todo: refactor to use AcceptSocketAsync
this._clientListener.BeginAcceptSocket(this.OnAccept, null);
}
ClientAcceptingEventArgs? cancel = null;
if (this.ClientAccepting is { } clientAccepting)
{
cancel = new ClientAcceptingEventArgs(socket);
await clientAccepting.Invoke(cancel).ConfigureAwait(false);
}
if (cancel is null || !cancel.Cancel)
{
socket.NoDelay = true; // todo: option?
var connection = this.CreateConnection(socket);
if (this.ClientAccepted is { } clientAccepted)
{
await clientAccepted.Invoke(new ClientAcceptedEventArgs(connection)).ConfigureAwait(false);
}
}
else
{
socket.Dispose();
}
}
catch (Exception ex)
{
this._logger.LogError(ex, "Unexpected error in OnAccept.");
}
}
}

View File

@@ -0,0 +1,28 @@
// <copyright file="LocalIpResolver.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Net;
/// <summary>
/// Resolves the own ip address by resolving the local host name to get the local <see cref="IPAddress"/> over DNS.
/// </summary>
public class LocalIpResolver : HostNameIpResolver
{
/// <summary>
/// Initializes a new instance of the <see cref="LocalIpResolver"/> class.
/// </summary>
public LocalIpResolver()
: base(Dns.GetHostName())
{
}
/// <inheritdoc />
public override async ValueTask<IPAddress> ResolveIPv4Async()
{
return await this.ResolveAsync().ConfigureAwait(false)
?? LoopbackIpResolver.LoopbackAddress;
}
}

View File

@@ -0,0 +1,27 @@
// <copyright file="LoopbackIpResolver.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Net;
/// <summary>
/// Resolves the ip address as 127.127.127.127.
/// Usually only used at development time.
/// </summary>
public class LoopbackIpResolver : CustomIpResolver
{
/// <summary>
/// Initializes a new instance of the <see cref="LoopbackIpResolver"/> class.
/// </summary>
public LoopbackIpResolver()
: base(LoopbackAddress)
{
}
/// <summary>
/// Gets the local address.
/// </summary>
internal static IPAddress LoopbackAddress { get; } = new IPAddress(0x7F7F7F7F);
}

View File

@@ -0,0 +1,77 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable;CS4014;VSTHRD110;VSTHRD100</WarningsAsErrors>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Authors>MUnique</Authors>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<RepositoryUrl>https://github.com/MUnique/OpenMU/tree/master/src/Network</RepositoryUrl>
<PackageProjectUrl>https://munique.net</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageTags>MUnique OpenMU MUOnline Network TCP</PackageTags>
<PackageId>MUnique.OpenMU.Network</PackageId>
<Description>
MUnique.OpenMU.Network contains all what's required to connect from and to a MU Online game, connect or chat server. It implements the MU Online network protocol.
It also contains several the encryption algorithms and keys which were used until a few years ago up to Season 6 Episode 3.
</Description>
<PackageVersion>0.9.9</PackageVersion>
<Version>0.9.9</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>..\..\bin\Debug\</OutputPath>
<DocumentationFile>..\..\bin\Debug\MUnique.OpenMU.Network.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>..\..\bin\Release\</OutputPath>
<DocumentationFile>..\..\bin\Release\MUnique.OpenMU.Network.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Analyzer\**" />
<EmbeddedResource Remove="Analyzer\**" />
<None Remove="Analyzer\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Packets\**" />
<EmbeddedResource Remove="Packets\**" />
<None Remove="Packets\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Nito.AsyncEx.Tasks" />
<PackageReference Include="Pipelines.Sockets.Unofficial" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PlugIns\MUnique.OpenMU.PlugIns.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\PlugInResources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>PlugInResources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\PlugInResources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>PlugInResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

19
src/Network/Metrics.cs Normal file
View File

@@ -0,0 +1,19 @@
// <copyright file="Metrics.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
/// <summary>
/// Provides information about the available metrics of this project.
/// </summary>
public static class Metrics
{
/// <summary>
/// Gets all available meters of this project.
/// </summary>
public static IEnumerable<string> Meters
{
get { yield return Connection.MeterName; }
}
}

View File

@@ -0,0 +1,88 @@
// <copyright file="NumberConversionExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
/// <summary>
/// Number conversion extensions.
/// </summary>
public static class NumberConversionExtensions
{
/// <summary>
/// Converts 4 bytes to an 32bit unsigned Integer.
/// </summary>
/// <param name="lowest">The lowest.</param>
/// <param name="lower">The lower.</param>
/// <param name="higher">The higher.</param>
/// <param name="highest">The highest.</param>
/// <returns>
/// The unsigned integer.
/// </returns>
public static uint MakeDword(byte lowest, byte lower, byte higher, byte highest)
{
return (uint)(MakeWord(lowest, lower) + (MakeWord(higher, highest) << 0x10));
}
/// <summary>
/// Converts 2 bytes to one 16bit unsigned short.
/// </summary>
/// <param name="lowByte">The low byte.</param>
/// <param name="highByte">The high byte.</param>
/// <returns>The unsigned short.</returns>
public static ushort MakeWord(byte lowByte, byte highByte)
{
return (ushort)(lowByte + ((highByte << 8) & 0xFF00));
}
/// <summary>
/// Gets the high byte.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The high byte.</returns>
public static byte GetHighByte(this ushort value)
{
return (byte)(value >> 8 & 0xFF);
}
/// <summary>
/// Gets the low byte.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The low byte.</returns>
public static byte GetLowByte(this ushort value)
{
return (byte)(value & 0xFF);
}
/// <summary>
/// Converts the signed short to an unsigned short.
/// </summary>
/// <param name="value">The signed value.</param>
/// <returns>The unsigned value.</returns>
public static ushort ToUnsigned(this short value)
{
return unchecked((ushort)value);
}
/// <summary>
/// Converts the unsigned short to a signed short.
/// </summary>
/// <param name="value">The usigned value.</param>
/// <returns>The signed value.</returns>
public static short ToSigned(this ushort value)
{
return unchecked((short)value);
}
/// <summary>
/// Gets the byte of an integer at a specific index position.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="index">The index.</param>
/// <returns>The byte of the integer at the specific index position.</returns>
public static byte GetByte(this uint value, int index)
{
return (byte)((value >> (8 * index)) & 0xFF);
}
}

View File

@@ -0,0 +1,156 @@
// <copyright file="PacketPipeReaderBase.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network;
using System.Buffers;
using System.IO.Pipelines;
using Pipelines.Sockets.Unofficial;
/// <summary>
/// Base class for all classes which read mu online data packets from a <see cref="PipeReader"/>.
/// </summary>
/// <remarks>
/// Things to consider here:
/// * Do not call FlushAsync if the reader can't start until FlushAsync finishes, as that may cause a deadlock.
/// * Ensure that only one context "owns" a PipeReader or PipeWriter or accesses them. These types are not thread-safe.
/// </remarks>
public abstract class PacketPipeReaderBase
{
private readonly byte[] _headerBuffer = new byte[3];
/// <summary>
/// Gets or sets the <see cref="PipeReader"/> from which the packets can be read from at <see cref="ReadSourceAsync"/>.
/// </summary>
protected PipeReader Source { get; set; } = null!; // will be set in derived classes
/// <summary>
/// Reads the mu online packet.
/// </summary>
/// <param name="packet">The mu online packet.</param>
/// <returns><see langword="true" />, if the flush was successful or not required.<see langword="false" />, if the pipe reader is completed and no longer reading data.</returns>
protected abstract ValueTask<bool> ReadPacketAsync(ReadOnlySequence<byte> packet);
/// <summary>
/// Called when the <see cref="Source"/> completed.
/// </summary>
/// <param name="exception">The exception, if any occurred; Otherwise, <c>null</c>.</param>
protected abstract ValueTask OnCompleteAsync(Exception? exception);
/// <summary>
/// Reads from the <see cref="Source"/> until it's completed or cancelled.
/// </summary>
/// <returns>The task.</returns>
protected async Task ReadSourceAsync()
{
if (this.Source is null)
{
throw new InvalidOperationException("Source must be set before.");
}
try
{
while (true)
{
var completed = await this.ReadBufferAsync().ConfigureAwait(false);
// Stop reading if there's no more data coming
if (completed)
{
break;
}
}
}
catch (ConnectionAbortedException)
{
// we can ignore that.
}
catch (Exception e)
{
await this.OnCompleteAsync(e).ConfigureAwait(false);
return;
}
await this.OnCompleteAsync(null).ConfigureAwait(false);
}
/// <summary>
/// Tries to flush the writer.
/// </summary>
/// <param name="pipeWriter">The pipe writer.</param>
/// <returns>
/// <see langword="true" />, if the flush was successful or not required.<see langword="false" />, if the pipe reader is completed and no longer reading data.
/// </returns>
protected async ValueTask<bool> TryFlushWriterAsync(PipeWriter pipeWriter)
{
if (pipeWriter is { CanGetUnflushedBytes: true, UnflushedBytes: 0 })
{
// It was flushed already in the background.
return true;
}
// todo: what happens if it was flushed in the background in the meantime? race-condition?
var flushResult = await pipeWriter.FlushAsync().ConfigureAwait(false);
return !flushResult.IsCompleted;
}
private async Task<bool> ReadBufferAsync()
{
ReadResult result = await this.Source.ReadAsync().ConfigureAwait(false);
ReadOnlySequence<byte> buffer = result.Buffer;
int? length = null;
var readingCancelledOrCompleted = false;
do
{
if (buffer.Length > 2)
{
// peek the length of the next packet
buffer.Slice(0, 3).CopyTo(this._headerBuffer);
length = this._headerBuffer.AsSpan().GetPacketSize();
if (length == 0)
{
var exception = new InvalidPacketHeaderException(this._headerBuffer, result.Buffer, buffer.Start);
// Notify our source, that we don't intend to read anymore.
await this.Source.CompleteAsync(exception).ConfigureAwait(false);
await this.OnCompleteAsync(exception).ConfigureAwait(false);
throw exception;
}
}
if (length is > 0 && buffer.Length >= length)
{
var packet = buffer.Slice(0, length.Value);
if (!await this.ReadPacketAsync(packet).ConfigureAwait(false))
{
readingCancelledOrCompleted = true;
break;
}
buffer = buffer.Slice(buffer.GetPosition(length.Value), buffer.End);
length = null;
}
else
{
// read more
break;
}
}
while (buffer.Length > 2);
if (result.IsCanceled || result.IsCompleted)
{
// Not possible to advance any further, e.g. because of a disconnected network connection.
await this.OnCompleteAsync(null).ConfigureAwait(false);
}
else
{
// Tell the PipeReader how much of the buffer we have consumed
this.Source.AdvanceTo(buffer.Start);
}
return result.IsCompleted || readingCancelledOrCompleted;
}
}

View File

@@ -0,0 +1,23 @@
// <copyright file="IPacketTwister.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// Interface for a packet twister of a specific packet type.
/// </summary>
internal interface IPacketTwister
{
/// <summary>
/// Twists (encrypts) the specified data.
/// </summary>
/// <param name="data">The data.</param>
void Twist(Span<byte> data);
/// <summary>
/// Corrects (decrypts) the specified data.
/// </summary>
/// <param name="data">The data.</param>
void Correct(Span<byte> data);
}

View File

@@ -0,0 +1,123 @@
// <copyright file="PacketTwistRunner.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// The main entry point to decrypt packets with the packet twisting algorithm.
/// </summary>
public class PacketTwistRunner : ISpanDecryptor, ISpanEncryptor
{
private readonly IDictionary<byte, IPacketTwister> _twisters = new Dictionary<byte, IPacketTwister>();
/// <summary>
/// Initializes a new instance of the <see cref="PacketTwistRunner"/> class.
/// </summary>
public PacketTwistRunner()
{
this._twisters.Add(0x0E, new PacketTwisterOfPing());
this._twisters.Add(0xF1, new PacketTwisterOfLoginLogout());
this._twisters.Add(0xF3, new PacketTwisterOfCharacterManagement());
this._twisters.Add(0x00, new PacketTwisterOfChat());
this._twisters.Add(0x01, new PacketTwister5());
this._twisters.Add(0x02, new PacketTwisterOfWhisper());
this._twisters.Add(0x03, new PacketTwisterOfClientChecksum());
this._twisters.Add(0x18, new PacketTwisterOfAnimation());
this._twisters.Add(0x19, new PacketTwisterOfSkill());
this._twisters.Add(0x22, new PacketTwisterOfItemPickup());
this._twisters.Add(0x23, new PacketTwisterOfItemDrop());
this._twisters.Add(0x24, new PacketTwisterOfItemMove());
this._twisters.Add(0x26, new PacketTwisterOfItemConsume());
this._twisters.Add(0x30, new PacketTwisterOfNpcTalkRequest());
this._twisters.Add(0x31, new PacketTwisterOfNpcDialogClose());
this._twisters.Add(0x32, new PacketTwisterOfNpcItemBuyRequest());
this._twisters.Add(0x33, new PacketTwisterOfNpcItemSellRequest());
this._twisters.Add(0x34, new PacketTwisterOfItemRepairRequest());
this._twisters.Add(0x36, new PacketTwisterOfTradeRequest());
this._twisters.Add(0x37, new PacketTwisterOfTradeResponse());
this._twisters.Add(0x3A, new PacketTwisterOfTradeMoney());
this._twisters.Add(0x3C, new PacketTwisterOfTradeButton());
this._twisters.Add(0x3D, new PacketTwisterOfTradeCancel());
this._twisters.Add(0x3F, new PacketTwisterOfPersonalShop());
this._twisters.Add(0x40, new PacketTwisterOfPartyRequest());
this._twisters.Add(0x41, new PacketTwisterOfPartyRequestAnswer());
this._twisters.Add(0x42, new PacketTwisterOfPartyList());
this._twisters.Add(0x43, new PacketTwisterOfPartyKick());
this._twisters.Add(0x4A, new PacketTwister29());
this._twisters.Add(0x4B, new PacketTwister30());
this._twisters.Add(0x50, new PacketTwisterOfGuildJoinRequest());
this._twisters.Add(0x51, new PacketTwisterOfGuildJoinResponse());
this._twisters.Add(0x52, new PacketTwisterOfGuildList());
this._twisters.Add(0x53, new PacketTwisterOfGuildKick());
//// this.twisters.Add(0x54, new PacketTwisterOfGuildMasterResponse()); // implementation seems to be wrong
this._twisters.Add(0x55, new PacketTwisterOfGuildMasterInfo());
this._twisters.Add(0x57, new PacketTwister37());
this._twisters.Add(0x61, new PacketTwisterOfGuildWarRequest());
this._twisters.Add(0x66, new PacketTwisterOfGuildInfo());
this._twisters.Add(0xB1, new PacketTwisterOfCastleSiege());
this._twisters.Add(0xB2, new PacketTwister41());
this._twisters.Add(0xB3, new PacketTwister42());
this._twisters.Add(0xB7, new PacketTwisterOfCastleSiegeWeapon());
this._twisters.Add(0xBD, new PacketTwisterOfCrywolf());
this._twisters.Add(0xE2, new PacketTwisterOfGuildAssign());
this._twisters.Add(0xE5, new PacketTwisterOfAllianceJoinRequest());
this._twisters.Add(0x71, new PacketTwister47());
this._twisters.Add(0x72, new PacketTwister48());
this._twisters.Add(0x73, new PacketTwisterOfGameGuardAuth());
this._twisters.Add(0x81, new PacketTwisterOfVaultMoney());
this._twisters.Add(0x82, new PacketTwisterOfVaultClose());
this._twisters.Add(0x83, new PacketTwisterOfVaultPassword());
this._twisters.Add(0x86, new PacketTwisterOfChaosMachineMix());
this._twisters.Add(0x87, new PacketTwisterOfChaosMachineClose());
this._twisters.Add(0x90, new PacketTwisterOfDevilSquareEnter());
this._twisters.Add(0x91, new PacketTwisterDevilSquareRemainingTime());
this._twisters.Add(0x95, new PacketTwisterOfEventChipRegistration());
this._twisters.Add(0x96, new PacketTwister58());
this._twisters.Add(0x97, new PacketTwister59());
this._twisters.Add(0xA0, new PacketTwisterOfQuestInfoRequest());
this._twisters.Add(0xA2, new PacketTwisterOfQuestState());
this._twisters.Add(0xA7, new PacketTwisterOfPetItemCommand());
this._twisters.Add(0xA9, new PacketTwisterOfPetItemInfoRequest());
this._twisters.Add(0x9A, new PacketTwisterOfBloodCastleEnterRequest());
this._twisters.Add(0x9F, new PacketTwisterOfBloodCastleInfoRequest());
this._twisters.Add(0x9D, new PacketTwisterOfLottoRegistration());
this._twisters.Add(0xC0, new PacketTwisterOfFriendList());
this._twisters.Add(0xC1, new PacketTwisterOfFriendAddRequest());
this._twisters.Add(0xC2, new PacketTwisterOfFriendAddResponse());
this._twisters.Add(0xC3, new PacketTwisterOfFriendDeleteRequest());
this._twisters.Add(0xC4, new PacketTwisterOfFriendStateChange());
this._twisters.Add(0xC5, new PacketTwisterOfLetterSendRequest());
this._twisters.Add(0xC7, new PacketTwisterOfLetterReadRequest());
this._twisters.Add(0xC8, new PacketTwisterOfLetterDeleteRequest());
this._twisters.Add(0xC9, new PacketTwisterOfLetterListRequest());
this._twisters.Add(0xCA, new PacketTwisterOfChatRoomCreateRequest());
this._twisters.Add(0xCB, new PacketTwisterOfChatInvitationRequest());
this._twisters.Add(0xF7, new PacketTwister78());
this._twisters.Add(0xF6, new PacketTwister79());
this._twisters.Add(0xD2, new PacketTwisterOfCashShop());
this._twisters.Add(0xFA, new PacketTwister81());
}
/// <inheritdoc/>
public void Encrypt(Span<byte> packet)
{
var packetType = packet.GetPacketType();
var data = packet.Slice(packet.GetPacketHeaderSize() + 1);
if (this._twisters.TryGetValue(packetType, out var twister))
{
twister.Twist(data);
}
}
/// <inheritdoc/>
public void Decrypt(Span<byte> packet)
{
var packetType = packet.GetPacketType();
var data = packet.Slice(packet.GetPacketHeaderSize() + 1);
if (this._twisters.TryGetValue(packetType, out var twister))
{
twister.Correct(data);
}
}
}

View File

@@ -0,0 +1,428 @@
// <copyright file="PacketTwister29.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister29 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v12 = (byte)((data[1] >> 6) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
if (v12 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v10 = data[6];
data[6] = data[28];
data[28] = v10;
var v11 = (byte)((data[31] >> 2) & 1);
if (((data[31] >> 2) & 1) != 0)
{
data[31] |= 4;
}
else
{
data[31] &= 0xFB;
}
if (v11 != 0)
{
data[31] |= 4;
}
else
{
data[31] &= 0xFB;
}
}
else
{
var v14 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 5) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v14 != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
data[14] ^= 0x46;
var v8 = (byte)(data[4] >> 3);
data[4] *= 32;
data[4] |= v8;
var v13 = (byte)((data[13] >> 7) & 1);
if (((data[13] >> 5) & 1) != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
if (v13 != 0)
{
data[13] |= 0x20;
}
else
{
data[13] &= 0xDF;
}
var v9 = (byte)(data[10] >> 3);
data[10] *= 32;
data[10] |= v9;
data[1] ^= 0xEF;
data[12] ^= 0x9E;
}
}
else
{
var v5 = data[6];
data[6] = data[7];
data[7] = v5;
var v6 = data[3];
data[3] = data[4];
data[4] = v6;
data[7] ^= 0x85;
var v15 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 2) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v15 != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
var v7 = data[2];
data[2] = data[1];
data[1] = v7;
data[4] ^= 0x1F;
}
}
else
{
data[3] ^= 0x49;
data[1] ^= 0xD5;
var v2 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v2 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v3 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v3;
var v4 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v4;
var v17 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 2) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v17 != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
var v16 = (byte)((data[0] >> 6) & 1);
if (((data[0] >> 2) & 1) != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
if (v16 != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
data[3] ^= 0xC0;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v12 = (byte)((data[31] >> 2) & 1);
if (((data[31] >> 2) & 1) != 0)
{
data[31] |= 4;
}
else
{
data[31] &= 0xFB;
}
if (v12 != 0)
{
data[31] |= 4;
}
else
{
data[31] &= 0xFB;
}
var v10 = data[6];
data[6] = data[28];
data[28] = v10;
var v11 = (byte)((data[1] >> 6) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
if (v11 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
}
else
{
data[12] ^= 0x9E;
data[1] ^= 0xEF;
var v8 = (byte)(data[10] >> 5);
data[10] *= 8;
data[10] |= v8;
var v14 = (byte)((data[13] >> 7) & 1);
if (((data[13] >> 5) & 1) != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
if (v14 != 0)
{
data[13] |= 0x20;
}
else
{
data[13] &= 0xDF;
}
var v9 = (byte)(data[4] >> 5);
data[4] *= 8;
data[4] |= v9;
data[14] ^= 0x46;
var v13 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 5) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v13 != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
}
}
else
{
data[4] ^= 0x1F;
var v5 = data[2];
data[2] = data[1];
data[1] = v5;
var v15 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 2) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v15 != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
data[7] ^= 0x85;
var v6 = data[3];
data[3] = data[4];
data[4] = v6;
var v7 = data[6];
data[6] = data[7];
data[7] = v7;
}
}
else
{
data[3] ^= 0xC0;
var v2 = (byte)((data[0] >> 6) & 1);
if (((data[0] >> 2) & 1) != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
if (v2 != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
var v17 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 2) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v17 != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
var v3 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v3;
var v4 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v4;
var v16 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v16 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[1] ^= 0xD5;
data[3] ^= 0x49;
}
}
}
}

View File

@@ -0,0 +1,446 @@
// <copyright file="PacketTwister30.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister30 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v16 = data[16];
data[16] = data[9];
data[9] = v16;
data[18] ^= 0x8F;
var v17 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v17;
var v21 = (byte)((data[22] >> 1) & 1);
if (((data[22] >> 4) & 1) != 0)
{
data[22] |= 2;
}
else
{
data[22] &= 0xFD;
}
if (v21 != 0)
{
data[22] |= 0x10;
}
else
{
data[22] &= 0xEF;
}
var v18 = data[23];
data[23] = data[24];
data[24] = v18;
var v19 = data[18];
data[18] = data[21];
data[21] = v19;
var v20 = data[8];
data[8] = data[14];
data[14] = v20;
}
else
{
var v13 = (byte)(data[13] >> 4);
data[13] *= 16;
data[13] |= v13;
var v14 = (byte)(data[6] >> 6);
data[6] *= 4;
data[6] |= v14;
data[1] ^= 0xA3;
var v23 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 7) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v23 != 0)
{
data[15] |= 0x80;
}
else
{
data[15] &= 0x7F;
}
var v22 = (byte)((data[8] >> 2) & 1);
if (((data[8] >> 1) & 1) != 0)
{
data[8] |= 4;
}
else
{
data[8] &= 0xFB;
}
if (v22 != 0)
{
data[8] |= 2;
}
else
{
data[8] &= 0xFD;
}
var v15 = data[2];
data[2] = data[8];
data[8] = v15;
}
}
else
{
var v7 = data[0];
data[0] = data[4];
data[4] = v7;
var v8 = (byte)(data[5] >> 5);
data[5] *= 8;
data[5] |= v8;
var v26 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 3) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v26 != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
var v9 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v9;
var v10 = data[3];
data[3] = data[5];
data[5] = v10;
var v25 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v25 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
var v11 = data[6];
data[6] = data[3];
data[3] = v11;
var v12 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v12;
var v24 = (byte)((data[5] >> 1) & 1);
if (((data[5] >> 2) & 1) != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
if (v24 != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
}
}
else
{
var v3 = data[3];
data[3] = data[0];
data[0] = v3;
var v2 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 7) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v2 != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
data[0] ^= 0x18;
var v4 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v4;
data[0] ^= 0x8E;
data[0] ^= 0xE7;
var v5 = (byte)(data[1] >> 3);
data[1] *= 32;
data[1] |= v5;
var v6 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v6;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v16 = data[8];
data[8] = data[14];
data[14] = v16;
var v17 = data[18];
data[18] = data[21];
data[21] = v17;
var v18 = data[23];
data[23] = data[24];
data[24] = v18;
var v21 = (byte)((data[22] >> 1) & 1);
if (((data[22] >> 4) & 1) != 0)
{
data[22] |= 2;
}
else
{
data[22] &= 0xFD;
}
if (v21 != 0)
{
data[22] |= 0x10;
}
else
{
data[22] &= 0xEF;
}
var v19 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v19;
data[18] ^= 0x8F;
var v20 = data[16];
data[16] = data[9];
data[9] = v20;
}
else
{
var v13 = data[2];
data[2] = data[8];
data[8] = v13;
var v23 = (byte)((data[8] >> 2) & 1);
if (((data[8] >> 1) & 1) != 0)
{
data[8] |= 4;
}
else
{
data[8] &= 0xFB;
}
if (v23 != 0)
{
data[8] |= 2;
}
else
{
data[8] &= 0xFD;
}
var v22 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 7) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v22 != 0)
{
data[15] |= 0x80;
}
else
{
data[15] &= 0x7F;
}
data[1] ^= 0xA3;
var v14 = (byte)(data[6] >> 2);
data[6] <<= 6;
data[6] |= v14;
var v15 = (byte)(data[13] >> 4);
data[13] *= 16;
data[13] |= v15;
}
}
else
{
var v26 = (byte)((data[5] >> 1) & 1);
if (((data[5] >> 2) & 1) != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
if (v26 != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
var v7 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v7;
var v8 = data[6];
data[6] = data[3];
data[3] = v8;
var v25 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v25 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
var v9 = data[3];
data[3] = data[5];
data[5] = v9;
var v10 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v10;
var v24 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 3) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v24 != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
var v11 = (byte)(data[5] >> 3);
data[5] *= 32;
data[5] |= v11;
var v12 = data[0];
data[0] = data[4];
data[4] = v12;
}
}
else
{
var v3 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v3;
var v4 = (byte)(data[1] >> 5);
data[1] *= 8;
data[1] |= v4;
data[0] ^= 0xE7;
data[0] ^= 0x8E;
var v5 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v5;
data[0] ^= 0x18;
var v2 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 7) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v2 != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
var v6 = data[3];
data[3] = data[0];
data[0] = v6;
}
}
}
}

View File

@@ -0,0 +1,471 @@
// <copyright file="PacketTwister37.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister37 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v19 = (byte)((data[31] >> 4) & 1);
if (((data[31] >> 4) & 1) != 0)
{
data[31] |= 0x10;
}
else
{
data[31] &= 0xEF;
}
if (v19 != 0)
{
data[31] |= 0x10;
}
else
{
data[31] &= 0xEF;
}
var v14 = data[29];
data[29] = data[7];
data[7] = v14;
data[17] ^= 0xE6;
var v15 = (byte)(data[9] >> 6);
data[9] *= 4;
data[9] |= v15;
var v18 = (byte)((data[24] >> 1) & 1);
if (((data[24] >> 3) & 1) != 0)
{
data[24] |= 2;
}
else
{
data[24] &= 0xFD;
}
if (v18 != 0)
{
data[24] |= 8;
}
else
{
data[24] &= 0xF7;
}
var v16 = (byte)(data[1] >> 4);
data[1] *= 16;
data[1] |= v16;
data[10] ^= 0x97;
var v17 = (byte)(data[16] >> 5);
data[16] *= 8;
data[16] |= v17;
}
else
{
var v9 = data[7];
data[7] = data[3];
data[3] = v9;
var v10 = data[10];
data[10] = data[8];
data[8] = v10;
var v21 = (byte)((data[9] >> 2) & 1);
if (((data[9] >> 6) & 1) != 0)
{
data[9] |= 4;
}
else
{
data[9] &= 0xFB;
}
if (v21 != 0)
{
data[9] |= 0x40;
}
else
{
data[9] &= 0xBF;
}
data[5] ^= 0x7E;
data[6] ^= 0xDF;
var v11 = data[10];
data[10] = data[8];
data[8] = v11;
var v12 = data[13];
data[13] = data[7];
data[7] = v12;
var v20 = (byte)((data[11] >> 6) & 1);
if (((data[11] >> 4) & 1) != 0)
{
data[11] |= 0x40;
}
else
{
data[11] &= 0xBF;
}
if (v20 != 0)
{
data[11] |= 0x10;
}
else
{
data[11] &= 0xEF;
}
var v13 = data[13];
data[13] = data[3];
data[3] = v13;
}
}
else
{
var v6 = data[1];
data[1] = data[1];
data[1] = v6;
var v23 = (byte)((data[5] >> 2) & 1);
if (((data[5] >> 3) & 1) != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
if (v23 != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
data[5] ^= 0x83;
var v7 = (byte)(data[7] >> 2);
data[7] <<= 6;
data[7] |= v7;
data[5] ^= 0x5D;
var v22 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v22 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
var v8 = data[1];
data[1] = data[0];
data[0] = v8;
data[4] ^= 0x98;
}
}
else
{
data[2] ^= 0x63;
var v2 = (byte)((data[3] >> 3) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
if (v2 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v3 = data[3];
data[3] = data[0];
data[0] = v3;
var v4 = data[1];
data[1] = data[3];
data[3] = v4;
var v5 = data[0];
data[0] = data[3];
data[3] = v5;
var v24 = (byte)((data[0] >> 6) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
if (v24 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v14 = (byte)(data[16] >> 3);
data[16] *= 32;
data[16] |= v14;
data[10] ^= 0x97;
var v15 = (byte)(data[1] >> 4);
data[1] *= 16;
data[1] |= v15;
var v19 = (byte)((data[24] >> 1) & 1);
if (((data[24] >> 3) & 1) != 0)
{
data[24] |= 2;
}
else
{
data[24] &= 0xFD;
}
if (v19 != 0)
{
data[24] |= 8;
}
else
{
data[24] &= 0xF7;
}
var v16 = (byte)(data[9] >> 2);
data[9] <<= 6;
data[9] |= v16;
data[17] ^= 0xE6;
var v17 = data[29];
data[29] = data[7];
data[7] = v17;
var v18 = (byte)((data[31] >> 4) & 1);
if (((data[31] >> 4) & 1) != 0)
{
data[31] |= 0x10;
}
else
{
data[31] &= 0xEF;
}
if (v18 != 0)
{
data[31] |= 0x10;
}
else
{
data[31] &= 0xEF;
}
}
else
{
var v9 = data[13];
data[13] = data[3];
data[3] = v9;
var v21 = (byte)((data[11] >> 6) & 1);
if (((data[11] >> 4) & 1) != 0)
{
data[11] |= 0x40;
}
else
{
data[11] &= 0xBF;
}
if (v21 != 0)
{
data[11] |= 0x10;
}
else
{
data[11] &= 0xEF;
}
var v10 = data[13];
data[13] = data[7];
data[7] = v10;
var v11 = data[10];
data[10] = data[8];
data[8] = v11;
data[6] ^= 0xDF;
data[5] ^= 0x7E;
var v20 = (byte)((data[9] >> 2) & 1);
if (((data[9] >> 6) & 1) != 0)
{
data[9] |= 4;
}
else
{
data[9] &= 0xFB;
}
if (v20 != 0)
{
data[9] |= 0x40;
}
else
{
data[9] &= 0xBF;
}
var v12 = data[10];
data[10] = data[8];
data[8] = v12;
var v13 = data[7];
data[7] = data[3];
data[3] = v13;
}
}
else
{
data[4] ^= 0x98;
var v6 = data[1];
data[1] = data[0];
data[0] = v6;
var v23 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v23 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
data[5] ^= 0x5D;
var v7 = (byte)(data[7] >> 6);
data[7] *= 4;
data[7] |= v7;
data[5] ^= 0x83;
var v22 = (byte)((data[5] >> 2) & 1);
if (((data[5] >> 3) & 1) != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
if (v22 != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
var v8 = data[1];
data[1] = data[1];
data[1] = v8;
}
}
else
{
var v2 = (byte)((data[0] >> 6) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
if (v2 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v3 = data[0];
data[0] = data[3];
data[3] = v3;
var v4 = data[1];
data[1] = data[3];
data[3] = v4;
var v5 = data[3];
data[3] = data[0];
data[0] = v5;
var v24 = (byte)((data[3] >> 3) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
if (v24 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
data[2] ^= 0x63;
}
}
}
}

View File

@@ -0,0 +1,441 @@
// <copyright file="PacketTwister41.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister41 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[10] ^= 0x1B;
var v11 = data[14];
data[14] = data[22];
data[22] = v11;
var v12 = (byte)(data[14] >> 1);
data[14] <<= 7;
data[14] |= v12;
var v14 = (byte)((data[19] >> 7) & 1);
if (((data[19] >> 5) & 1) != 0)
{
data[19] |= 0x80;
}
else
{
data[19] &= 0x7F;
}
if (v14 != 0)
{
data[19] |= 0x20;
}
else
{
data[19] &= 0xDF;
}
var v13 = data[27];
data[27] = data[16];
data[16] = v13;
}
else
{
var v18 = (byte)((data[15] >> 5) & 1);
if (((data[15] >> 7) & 1) != 0)
{
data[15] |= 0x20;
}
else
{
data[15] &= 0xDF;
}
if (v18 != 0)
{
data[15] |= 0x80;
}
else
{
data[15] &= 0x7F;
}
data[5] ^= 0x2C;
var v17 = (byte)((data[7] >> 2) & 1);
if (((data[7] >> 1) & 1) != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
if (v17 != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
var v9 = data[3];
data[3] = data[12];
data[12] = v9;
var v16 = (byte)((data[13] >> 7) & 1);
if (((data[13] >> 6) & 1) != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
if (v16 != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
var v15 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 4) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v15 != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
var v10 = (byte)(data[0] >> 5);
data[0] *= 8;
data[0] |= v10;
}
}
else
{
var v4 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v4;
var v5 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v5;
var v20 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v20 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
var v6 = data[0];
data[0] = data[0];
data[0] = v6;
var v7 = (byte)(data[7] >> 7);
data[7] *= 2;
data[7] |= v7;
data[7] ^= 0x9B;
data[1] ^= 0x68;
var v19 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 1) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v19 != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
var v8 = (byte)(data[2] >> 5);
data[2] *= 8;
data[2] |= v8;
}
}
else
{
var v3 = data[2];
data[2] = data[1];
data[1] = v3;
data[1] ^= 0xED;
var v2 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 7) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v2 != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v11 = data[27];
data[27] = data[16];
data[16] = v11;
var v14 = (byte)((data[19] >> 7) & 1);
if (((data[19] >> 5) & 1) != 0)
{
data[19] |= 0x80;
}
else
{
data[19] &= 0x7F;
}
if (v14 != 0)
{
data[19] |= 0x20;
}
else
{
data[19] &= 0xDF;
}
var v12 = (byte)(data[14] >> 7);
data[14] *= 2;
data[14] |= v12;
var v13 = data[14];
data[14] = data[22];
data[22] = v13;
data[10] ^= 0x1B;
}
else
{
var v9 = (byte)(data[0] >> 3);
data[0] *= 32;
data[0] |= v9;
var v18 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 4) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v18 != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
var v17 = (byte)((data[13] >> 7) & 1);
if (((data[13] >> 6) & 1) != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
if (v17 != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
var v10 = data[3];
data[3] = data[12];
data[12] = v10;
var v16 = (byte)((data[7] >> 2) & 1);
if (((data[7] >> 1) & 1) != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
if (v16 != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
data[5] ^= 0x2C;
var v15 = (byte)((data[15] >> 5) & 1);
if (((data[15] >> 7) & 1) != 0)
{
data[15] |= 0x20;
}
else
{
data[15] &= 0xDF;
}
if (v15 != 0)
{
data[15] |= 0x80;
}
else
{
data[15] &= 0x7F;
}
}
}
else
{
var v4 = (byte)(data[2] >> 3);
data[2] *= 32;
data[2] |= v4;
var v20 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 1) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v20 != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
data[1] ^= 0x68;
data[7] ^= 0x9B;
var v5 = (byte)(data[7] >> 1);
data[7] <<= 7;
data[7] |= v5;
var v6 = data[0];
data[0] = data[0];
data[0] = v6;
var v19 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v19 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
var v7 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v7;
var v8 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v8;
}
}
else
{
var v2 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 7) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v2 != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
data[1] ^= 0xED;
var v3 = data[2];
data[2] = data[1];
data[1] = v3;
}
}
}
}

View File

@@ -0,0 +1,192 @@
// <copyright file="PacketTwister42.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister42 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v8 = (byte)(data[8] >> 7);
data[8] *= 2;
data[8] |= v8;
var v9 = (byte)(data[10] >> 2);
data[10] <<= 6;
data[10] |= v9;
data[28] ^= 0xAE;
}
else
{
var v2 = (byte)((data[14] >> 2) & 1);
if (((data[14] >> 1) & 1) != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
if (v2 != 0)
{
data[14] |= 2;
}
else
{
data[14] &= 0xFD;
}
data[4] ^= 0x40;
var v10 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 3) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v10 != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
data[0] ^= 0xC7;
var v7 = (byte)(data[4] >> 4);
data[4] *= 16;
data[4] |= v7;
}
}
else
{
var v4 = data[4];
data[4] = data[1];
data[1] = v4;
data[1] ^= 0x64;
var v5 = data[4];
data[4] = data[1];
data[1] = v5;
var v6 = (byte)(data[1] >> 5);
data[1] *= 8;
data[1] |= v6;
}
}
else
{
data[1] ^= 0x3C;
data[2] ^= 0x96;
var v3 = data[1];
data[1] = data[2];
data[2] = v3;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[28] ^= 0xAE;
var v8 = (byte)(data[10] >> 6);
data[10] *= 4;
data[10] |= v8;
var v9 = (byte)(data[8] >> 1);
data[8] <<= 7;
data[8] |= v9;
}
else
{
var v7 = (byte)(data[4] >> 4);
data[4] *= 16;
data[4] |= v7;
data[0] ^= 0xC7;
var v2 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 3) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v2 != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
data[4] ^= 0x40;
var v10 = (byte)((data[14] >> 2) & 1);
if (((data[14] >> 1) & 1) != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
if (v10 != 0)
{
data[14] |= 2;
}
else
{
data[14] &= 0xFD;
}
}
}
else
{
var v4 = (byte)(data[1] >> 3);
data[1] *= 32;
data[1] |= v4;
var v5 = data[4];
data[4] = data[1];
data[1] = v5;
data[1] ^= 0x64;
var v6 = data[4];
data[4] = data[1];
data[1] = v6;
}
}
else
{
var v3 = data[1];
data[1] = data[2];
data[2] = v3;
data[2] ^= 0x96;
data[1] ^= 0x3C;
}
}
}
}

View File

@@ -0,0 +1,440 @@
// <copyright file="PacketTwister47.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister47 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = (byte)((data[14] >> 2) & 1);
if (((data[14] >> 1) & 1) != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
if (v17 != 0)
{
data[14] |= 2;
}
else
{
data[14] &= 0xFD;
}
var v11 = data[9];
data[9] = data[20];
data[20] = v11;
var v12 = data[24];
data[24] = data[29];
data[29] = v12;
var v13 = (byte)(data[17] >> 6);
data[17] *= 4;
data[17] |= v13;
var v14 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v14;
data[17] ^= 0x2A;
var v16 = (byte)((data[16] >> 2) & 1);
if (((data[16] >> 3) & 1) != 0)
{
data[16] |= 4;
}
else
{
data[16] &= 0xFB;
}
if (v16 != 0)
{
data[16] |= 8;
}
else
{
data[16] &= 0xF7;
}
var v15 = (byte)((data[6] >> 4) & 1);
if (((data[6] >> 3) & 1) != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
if (v15 != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
}
else
{
var v8 = data[10];
data[10] = data[1];
data[1] = v8;
var v9 = (byte)(data[10] >> 1);
data[10] <<= 7;
data[10] |= v9;
var v10 = data[6];
data[6] = data[5];
data[5] = v10;
}
}
else
{
var v19 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 1) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v19 != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
var v18 = (byte)((data[5] >> 3) & 1);
if (((data[5] >> 2) & 1) != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
if (v18 != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
data[7] ^= 0xFA;
}
}
else
{
var v2 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v2 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v3 = (byte)(data[1] >> 5);
data[1] *= 8;
data[1] |= v3;
var v4 = data[0];
data[0] = data[1];
data[1] = v4;
var v21 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v21 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v5 = data[0];
data[0] = data[0];
data[0] = v5;
var v6 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v6;
var v7 = data[3];
data[3] = data[0];
data[0] = v7;
data[2] ^= 0x20;
var v20 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v20 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = (byte)((data[6] >> 4) & 1);
if (((data[6] >> 3) & 1) != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
if (v17 != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
var v16 = (byte)((data[16] >> 2) & 1);
if (((data[16] >> 3) & 1) != 0)
{
data[16] |= 4;
}
else
{
data[16] &= 0xFB;
}
if (v16 != 0)
{
data[16] |= 8;
}
else
{
data[16] &= 0xF7;
}
data[17] ^= 0x2A;
var v11 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v11;
var v12 = (byte)(data[17] >> 2);
data[17] <<= 6;
data[17] |= v12;
var v13 = data[24];
data[24] = data[29];
data[29] = v13;
var v14 = data[9];
data[9] = data[20];
data[20] = v14;
var v15 = (byte)((data[14] >> 2) & 1);
if (((data[14] >> 1) & 1) != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
if (v15 != 0)
{
data[14] |= 2;
}
else
{
data[14] &= 0xFD;
}
}
else
{
var v8 = data[6];
data[6] = data[5];
data[5] = v8;
var v9 = (byte)(data[10] >> 7);
data[10] *= 2;
data[10] |= v9;
var v10 = data[10];
data[10] = data[1];
data[1] = v10;
}
}
else
{
data[7] ^= 0xFA;
var v19 = (byte)((data[5] >> 3) & 1);
if (((data[5] >> 2) & 1) != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
if (v19 != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
var v18 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 1) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v18 != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
}
}
else
{
var v2 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v2 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
data[2] ^= 0x20;
var v3 = data[3];
data[3] = data[0];
data[0] = v3;
var v4 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v4;
var v5 = data[0];
data[0] = data[0];
data[0] = v5;
var v21 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v21 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v6 = data[0];
data[0] = data[1];
data[1] = v6;
var v7 = (byte)(data[1] >> 3);
data[1] *= 32;
data[1] |= v7;
var v20 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v20 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
}
}
}
}

View File

@@ -0,0 +1,365 @@
// <copyright file="PacketTwister48.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister48 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[27] = data[27];
var v13 = (byte)((data[13] >> 7) & 1);
if (((data[13] >> 6) & 1) != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
if (v13 != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
data[11] ^= 0xD3;
var v11 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v11;
var v12 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v12 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
}
else
{
var v8 = (byte)(data[2] >> 5);
data[2] *= 8;
data[2] |= v8;
data[7] ^= 0x3C;
var v9 = data[3];
data[3] = data[11];
data[11] = v9;
data[12] ^= 0xF9;
var v14 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v14 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
var v10 = data[15];
data[15] = data[7];
data[7] = v10;
data[11] ^= 0xB;
data[0] ^= 0x2A;
}
}
else
{
data[5] ^= 0xC1;
var v7 = data[0];
data[0] = data[2];
data[2] = v7;
data[7] ^= 0x34;
}
}
else
{
var v3 = data[2];
data[2] = data[3];
data[3] = v3;
data[2] ^= 0x95;
data[0] ^= 0xDA;
var v4 = data[0];
data[0] = data[0];
data[0] = v4;
var v5 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v5;
var v6 = data[3];
data[3] = data[3];
data[3] = v6;
var v2 = (byte)((data[0] >> 5) & 1);
if (((data[0] >> 7) & 1) != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
if (v2 != 0)
{
data[0] |= 0x80;
}
else
{
data[0] &= 0x7F;
}
data[1] ^= 0x89;
var v16 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 4) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v16 != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
var v15 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v15 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v13 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v13 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v11 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v11;
data[11] ^= 0xD3;
var v12 = (byte)((data[13] >> 7) & 1);
if (((data[13] >> 6) & 1) != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
if (v12 != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
data[27] = data[27];
}
else
{
data[0] ^= 0x2A;
data[11] ^= 0xB;
var v8 = data[15];
data[15] = data[7];
data[7] = v8;
var v14 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v14 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
data[12] ^= 0xF9;
var v9 = data[3];
data[3] = data[11];
data[11] = v9;
data[7] ^= 0x3C;
var v10 = (byte)(data[2] >> 3);
data[2] *= 32;
data[2] |= v10;
}
}
else
{
data[7] ^= 0x34;
var v7 = data[0];
data[0] = data[2];
data[2] = v7;
data[5] ^= 0xC1;
}
}
else
{
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v16 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 4) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v16 != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
data[1] ^= 0x89;
var v15 = (byte)((data[0] >> 5) & 1);
if (((data[0] >> 7) & 1) != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
if (v15 != 0)
{
data[0] |= 0x80;
}
else
{
data[0] &= 0x7F;
}
var v3 = data[3];
data[3] = data[3];
data[3] = v3;
var v4 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v4;
var v5 = data[0];
data[0] = data[0];
data[0] = v5;
data[0] ^= 0xDA;
data[2] ^= 0x95;
var v6 = data[2];
data[2] = data[3];
data[3] = v6;
}
}
}
}

View File

@@ -0,0 +1,396 @@
// <copyright file="PacketTwister5.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister5 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v12 = (byte)(data[13] >> 7);
data[13] *= 2;
data[13] |= v12;
var v13 = (byte)(data[8] >> 7);
data[8] *= 2;
data[8] |= v13;
var v14 = data[0];
data[0] = data[30];
data[30] = v14;
var v21 = (byte)((data[12] >> 3) & 1);
if (((data[12] >> 1) & 1) != 0)
{
data[12] |= 8;
}
else
{
data[12] &= 0xF7;
}
if (v21 != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
var v20 = (byte)((data[24] >> 3) & 1);
if (((data[24] >> 6) & 1) != 0)
{
data[24] |= 8;
}
else
{
data[24] &= 0xF7;
}
if (v20 != 0)
{
data[24] |= 0x40;
}
else
{
data[24] &= 0xBF;
}
var v15 = (byte)(data[20] >> 4);
data[20] *= 16;
data[20] |= v15;
var v19 = (byte)((data[22] >> 5) & 1);
if (((data[22] >> 1) & 1) != 0)
{
data[22] |= 0x20;
}
else
{
data[22] &= 0xDF;
}
if (v19 != 0)
{
data[22] |= 2;
}
else
{
data[22] &= 0xFD;
}
var v16 = data[22];
data[22] = data[17];
data[17] = v16;
data[5] ^= 0xF9;
var v17 = (byte)(data[6] >> 6);
data[6] *= 4;
data[6] |= v17;
var v18 = (byte)(data[29] >> 1);
data[29] <<= 7;
data[29] |= v18;
}
else
{
var v22 = (byte)((data[13] >> 1) & 1);
if (((data[13] >> 3) & 1) != 0)
{
data[13] |= 2;
}
else
{
data[13] &= 0xFD;
}
if (v22 != 0)
{
data[13] |= 8;
}
else
{
data[13] &= 0xF7;
}
var v10 = data[14];
data[14] = data[12];
data[12] = v10;
var v11 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v11;
}
}
else
{
data[1] ^= 0xA;
data[4] ^= 0xA0;
var v5 = data[2];
data[2] = data[3];
data[3] = v5;
var v2 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v2 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v6 = data[1];
data[1] = data[7];
data[7] = v6;
var v7 = data[1];
data[1] = data[4];
data[4] = v7;
var v8 = (byte)(data[3] >> 7);
data[3] *= 2;
data[3] |= v8;
var v23 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 2) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v23 != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
var v9 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v9;
}
}
else
{
data[1] ^= 0x51;
var v3 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v3;
data[2] ^= 0xED;
var v4 = (byte)(data[0] >> 4);
data[0] *= 16;
data[0] |= v4;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v12 = (byte)(data[29] >> 7);
data[29] *= 2;
data[29] |= v12;
var v13 = (byte)(data[6] >> 2);
data[6] <<= 6;
data[6] |= v13;
data[5] ^= 0xF9;
var v14 = data[22];
data[22] = data[17];
data[17] = v14;
var v21 = (byte)((data[22] >> 5) & 1);
if (((data[22] >> 1) & 1) != 0)
{
data[22] |= 0x20;
}
else
{
data[22] &= 0xDF;
}
if (v21 != 0)
{
data[22] |= 2;
}
else
{
data[22] &= 0xFD;
}
var v15 = (byte)(data[20] >> 4);
data[20] *= 16;
data[20] |= v15;
var v20 = (byte)((data[24] >> 3) & 1);
if (((data[24] >> 6) & 1) != 0)
{
data[24] |= 8;
}
else
{
data[24] &= 0xF7;
}
if (v20 != 0)
{
data[24] |= 0x40;
}
else
{
data[24] &= 0xBF;
}
var v19 = (byte)((data[12] >> 3) & 1);
if (((data[12] >> 1) & 1) != 0)
{
data[12] |= 8;
}
else
{
data[12] &= 0xF7;
}
if (v19 != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
var v16 = data[0];
data[0] = data[30];
data[30] = v16;
var v17 = (byte)(data[8] >> 1);
data[8] <<= 7;
data[8] |= v17;
var v18 = (byte)(data[13] >> 1);
data[13] <<= 7;
data[13] |= v18;
}
else
{
var v10 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v10;
var v11 = data[14];
data[14] = data[12];
data[12] = v11;
var v22 = (byte)((data[13] >> 1) & 1);
if (((data[13] >> 3) & 1) != 0)
{
data[13] |= 2;
}
else
{
data[13] &= 0xFD;
}
if (v22 != 0)
{
data[13] |= 8;
}
else
{
data[13] &= 0xF7;
}
}
}
else
{
var v5 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v5;
var v2 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 2) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v2 != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
var v6 = (byte)(data[3] >> 1);
data[3] <<= 7;
data[3] |= v6;
var v7 = data[1];
data[1] = data[4];
data[4] = v7;
var v8 = data[1];
data[1] = data[7];
data[7] = v8;
var v23 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v23 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v9 = data[2];
data[2] = data[3];
data[3] = v9;
data[4] ^= 0xA0;
data[1] ^= 0xA;
}
}
else
{
var v3 = (byte)(data[0] >> 4);
data[0] *= 16;
data[0] |= v3;
data[2] ^= 0xED;
var v4 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v4;
data[1] ^= 0x51;
}
}
}
}

View File

@@ -0,0 +1,371 @@
// <copyright file="PacketTwister58.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister58 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = data[13];
data[13] = data[31];
data[31] = v17;
data[31] ^= 0xCD;
var v18 = data[25];
data[25] = data[27];
data[27] = v18;
}
else
{
data[12] ^= 0x9A;
data[7] ^= 0xC1;
data[8] ^= 0xF9;
data[0] ^= 0x9D;
var v15 = data[4];
data[4] = data[3];
data[3] = v15;
data[6] ^= 0xC3;
var v16 = data[11];
data[11] = data[11];
data[11] = v16;
}
}
else
{
var v21 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 7) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v21 != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
var v20 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v20 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
data[3] ^= 0xA1;
data[0] ^= 0x5A;
var v11 = (byte)(data[6] >> 5);
data[6] *= 8;
data[6] |= v11;
var v19 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 5) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v19 != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
var v12 = (byte)(data[7] >> 1);
data[7] <<= 7;
data[7] |= v12;
var v13 = (byte)(data[5] >> 7);
data[5] *= 2;
data[5] |= v13;
data[7] ^= 0x53;
var v14 = data[3];
data[3] = data[4];
data[4] = v14;
}
}
else
{
data[3] ^= 0x87;
var v3 = data[3];
data[3] = data[0];
data[0] = v3;
var v4 = (byte)(data[1] >> 4);
data[1] *= 16;
data[1] |= v4;
var v5 = data[1];
data[1] = data[0];
data[0] = v5;
data[2] ^= 0x44;
var v6 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v6;
var v7 = data[2];
data[2] = data[0];
data[0] = v7;
var v8 = data[2];
data[2] = data[0];
data[0] = v8;
var v9 = data[3];
data[3] = data[2];
data[2] = v9;
var v10 = data[0];
data[0] = data[3];
data[3] = v10;
data[2] ^= 0x50;
var v2 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v2 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v22 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v22 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = data[25];
data[25] = data[27];
data[27] = v17;
data[31] ^= 0xCD;
var v18 = data[13];
data[13] = data[31];
data[31] = v18;
}
else
{
var v15 = data[11];
data[11] = data[11];
data[11] = v15;
data[6] ^= 0xC3;
var v16 = data[4];
data[4] = data[3];
data[3] = v16;
data[0] ^= 0x9D;
data[8] ^= 0xF9;
data[7] ^= 0xC1;
data[12] ^= 0x9A;
}
}
else
{
var v11 = data[3];
data[3] = data[4];
data[4] = v11;
data[7] ^= 0x53;
var v12 = (byte)(data[5] >> 1);
data[5] <<= 7;
data[5] |= v12;
var v13 = (byte)(data[7] >> 7);
data[7] *= 2;
data[7] |= v13;
var v21 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 5) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v21 != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
var v14 = (byte)(data[6] >> 3);
data[6] *= 32;
data[6] |= v14;
data[0] ^= 0x5A;
data[3] ^= 0xA1;
var v20 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v20 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v19 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 7) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v19 != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
}
}
else
{
var v2 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v2 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v22 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v22 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
data[2] ^= 0x50;
var v3 = data[0];
data[0] = data[3];
data[3] = v3;
var v4 = data[3];
data[3] = data[2];
data[2] = v4;
var v5 = data[2];
data[2] = data[0];
data[0] = v5;
var v6 = data[2];
data[2] = data[0];
data[0] = v6;
var v7 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v7;
data[2] ^= 0x44;
var v8 = data[1];
data[1] = data[0];
data[0] = v8;
var v9 = (byte)(data[1] >> 4);
data[1] *= 16;
data[1] |= v9;
var v10 = data[3];
data[3] = data[0];
data[0] = v10;
data[3] ^= 0x87;
}
}
}
}

View File

@@ -0,0 +1,437 @@
// <copyright file="PacketTwister59.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister59 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v15 = (byte)(data[20] >> 1);
data[20] <<= 7;
data[20] |= v15;
var v16 = (byte)(data[14] >> 6);
data[14] *= 4;
data[14] |= v16;
data[7] ^= 0x87;
var v17 = (byte)(data[17] >> 1);
data[17] <<= 7;
data[17] |= v17;
var v18 = (byte)(data[17] >> 6);
data[17] *= 4;
data[17] |= v18;
}
else
{
var v20 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v20 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
data[7] ^= 0xB6;
var v12 = data[12];
data[12] = data[6];
data[6] = v12;
var v13 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v13;
var v14 = data[9];
data[9] = data[7];
data[7] = v14;
var v19 = (byte)((data[9] >> 7) & 1);
if (((data[9] >> 1) & 1) != 0)
{
data[9] |= 0x80;
}
else
{
data[9] &= 0x7F;
}
if (v19 != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
data[4] ^= 0x5B;
}
}
else
{
data[1] ^= 0x9D;
data[7] ^= 0xC2;
var v6 = (byte)(data[3] >> 1);
data[3] <<= 7;
data[3] |= v6;
var v23 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 5) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v23 != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
var v22 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 1) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v22 != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
var v7 = data[0];
data[0] = data[2];
data[2] = v7;
var v8 = data[7];
data[7] = data[2];
data[2] = v8;
var v9 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v9;
var v10 = data[5];
data[5] = data[6];
data[6] = v10;
var v11 = data[5];
data[5] = data[6];
data[6] = v11;
var v21 = (byte)((data[4] >> 1) & 1);
if (((data[4] >> 4) & 1) != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
if (v21 != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
}
}
else
{
data[3] ^= 0x4F;
var v3 = data[2];
data[2] = data[0];
data[0] = v3;
var v2 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v2 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
data[3] ^= 0x2E;
var v4 = data[3];
data[3] = data[2];
data[2] = v4;
var v24 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v24 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v5 = data[3];
data[3] = data[0];
data[0] = v5;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v15 = (byte)(data[17] >> 2);
data[17] <<= 6;
data[17] |= v15;
var v16 = (byte)(data[17] >> 7);
data[17] *= 2;
data[17] |= v16;
data[7] ^= 0x87;
var v17 = (byte)(data[14] >> 2);
data[14] <<= 6;
data[14] |= v17;
var v18 = (byte)(data[20] >> 7);
data[20] *= 2;
data[20] |= v18;
}
else
{
data[4] ^= 0x5B;
var v20 = (byte)((data[9] >> 7) & 1);
if (((data[9] >> 1) & 1) != 0)
{
data[9] |= 0x80;
}
else
{
data[9] &= 0x7F;
}
if (v20 != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
var v12 = data[9];
data[9] = data[7];
data[7] = v12;
var v13 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v13;
var v14 = data[12];
data[12] = data[6];
data[6] = v14;
data[7] ^= 0xB6;
var v19 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v19 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
}
}
else
{
var v23 = (byte)((data[4] >> 1) & 1);
if (((data[4] >> 4) & 1) != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
if (v23 != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
var v6 = data[5];
data[5] = data[6];
data[6] = v6;
var v7 = data[5];
data[5] = data[6];
data[6] = v7;
var v8 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v8;
var v9 = data[7];
data[7] = data[2];
data[2] = v9;
var v10 = data[0];
data[0] = data[2];
data[2] = v10;
var v22 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 1) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v22 != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
var v21 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 5) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v21 != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
var v11 = (byte)(data[3] >> 7);
data[3] *= 2;
data[3] |= v11;
data[7] ^= 0xC2;
data[1] ^= 0x9D;
}
}
else
{
var v3 = data[3];
data[3] = data[0];
data[0] = v3;
var v2 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v2 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v4 = data[3];
data[3] = data[2];
data[2] = v4;
data[3] ^= 0x2E;
var v24 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v24 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
var v5 = data[2];
data[2] = data[0];
data[0] = v5;
data[3] ^= 0x4F;
}
}
}
}

View File

@@ -0,0 +1,568 @@
// <copyright file="PacketTwister78.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister78 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v17 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
var v16 = (byte)((data[28] >> 4) & 1);
if (((data[28] >> 5) & 1) != 0)
{
data[28] |= 0x10;
}
else
{
data[28] &= 0xEF;
}
if (v16 != 0)
{
data[28] |= 0x20;
}
else
{
data[28] &= 0xDF;
}
var v13 = (byte)(data[17] >> 6);
data[17] *= 4;
data[17] |= v13;
var v15 = (byte)((data[23] >> 1) & 1);
if (((data[23] >> 5) & 1) != 0)
{
data[23] |= 2;
}
else
{
data[23] &= 0xFD;
}
if (v15 != 0)
{
data[23] |= 0x20;
}
else
{
data[23] &= 0xDF;
}
data[16] ^= 0x45;
var v14 = (byte)(data[27] >> 6);
data[27] *= 4;
data[27] |= v14;
}
else
{
var v10 = (byte)(data[11] >> 4);
data[11] *= 16;
data[11] |= v10;
var v19 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 3) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v19 != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
var v18 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v18 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v11 = (byte)(data[10] >> 2);
data[10] <<= 6;
data[10] |= v11;
data[2] ^= 0x24;
var v12 = (byte)(data[7] >> 6);
data[7] *= 4;
data[7] |= v12;
}
}
else
{
data[4] ^= 0x17;
var v21 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 1) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v21 != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
data[6] ^= 0xBE;
var v6 = (byte)(data[4] >> 2);
data[4] <<= 6;
data[4] |= v6;
var v7 = data[3];
data[3] = data[1];
data[1] = v7;
var v8 = (byte)(data[7] >> 6);
data[7] *= 4;
data[7] |= v8;
var v20 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v20 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v9 = data[2];
data[2] = data[3];
data[3] = v9;
}
}
else
{
data[3] ^= 0xC8;
var v2 = (byte)((data[0] >> 4) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
if (v2 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[3] ^= 0xC0;
var v24 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v24 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v23 = (byte)((data[0] >> 5) & 1);
if (((data[0] >> 7) & 1) != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
if (v23 != 0)
{
data[0] |= 0x80;
}
else
{
data[0] &= 0x7F;
}
var v3 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v3;
data[3] ^= 0x80;
var v4 = data[0];
data[0] = data[0];
data[0] = v4;
var v5 = data[2];
data[2] = data[1];
data[1] = v5;
var v22 = (byte)((data[3] >> 4) & 1);
if (((data[3] >> 7) & 1) != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
if (v22 != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
data[2] ^= 0x57;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v13 = (byte)(data[27] >> 2);
data[27] <<= 6;
data[27] |= v13;
data[16] ^= 0x45;
var v17 = (byte)((data[23] >> 1) & 1);
if (((data[23] >> 5) & 1) != 0)
{
data[23] |= 2;
}
else
{
data[23] &= 0xFD;
}
if (v17 != 0)
{
data[23] |= 0x20;
}
else
{
data[23] &= 0xDF;
}
var v14 = (byte)(data[17] >> 2);
data[17] <<= 6;
data[17] |= v14;
var v16 = (byte)((data[28] >> 4) & 1);
if (((data[28] >> 5) & 1) != 0)
{
data[28] |= 0x10;
}
else
{
data[28] &= 0xEF;
}
if (v16 != 0)
{
data[28] |= 0x20;
}
else
{
data[28] &= 0xDF;
}
var v15 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v15 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
}
else
{
var v10 = (byte)(data[7] >> 2);
data[7] <<= 6;
data[7] |= v10;
data[2] ^= 0x24;
var v11 = (byte)(data[10] >> 6);
data[10] *= 4;
data[10] |= v11;
var v19 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v19 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v18 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 3) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v18 != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
var v12 = (byte)(data[11] >> 4);
data[11] *= 16;
data[11] |= v12;
}
}
else
{
var v6 = data[2];
data[2] = data[3];
data[3] = v6;
var v21 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v21 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v7 = (byte)(data[7] >> 2);
data[7] <<= 6;
data[7] |= v7;
var v8 = data[3];
data[3] = data[1];
data[1] = v8;
var v9 = (byte)(data[4] >> 6);
data[4] *= 4;
data[4] |= v9;
data[6] ^= 0xBE;
var v20 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 1) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v20 != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
data[4] ^= 0x17;
}
}
else
{
data[2] ^= 0x57;
var v2 = (byte)((data[3] >> 4) & 1);
if (((data[3] >> 7) & 1) != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
if (v2 != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
var v3 = data[2];
data[2] = data[1];
data[1] = v3;
var v4 = data[0];
data[0] = data[0];
data[0] = v4;
data[3] ^= 0x80;
var v5 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v5;
var v24 = (byte)((data[0] >> 5) & 1);
if (((data[0] >> 7) & 1) != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
if (v24 != 0)
{
data[0] |= 0x80;
}
else
{
data[0] &= 0x7F;
}
var v23 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v23 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
data[3] ^= 0xC0;
var v22 = (byte)((data[0] >> 4) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
if (v22 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[3] ^= 0xC8;
}
}
}
}

View File

@@ -0,0 +1,556 @@
// <copyright file="PacketTwister79.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister79 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v25 = (byte)((data[11] >> 4) & 1);
if (((data[11] >> 1) & 1) != 0)
{
data[11] |= 0x10;
}
else
{
data[11] &= 0xEF;
}
if (v25 != 0)
{
data[11] |= 2;
}
else
{
data[11] &= 0xFD;
}
data[13] ^= 0xF3;
data[18] ^= 0xB5;
var v21 = data[9];
data[9] = data[27];
data[27] = v21;
var v22 = (byte)(data[30] >> 3);
data[30] *= 32;
data[30] |= v22;
var v23 = data[25];
data[25] = data[4];
data[4] = v23;
var v24 = (byte)(data[4] >> 7);
data[4] *= 2;
data[4] |= v24;
}
else
{
var v30 = (byte)((data[12] >> 2) & 1);
if (((data[12] >> 3) & 1) != 0)
{
data[12] |= 4;
}
else
{
data[12] &= 0xFB;
}
if (v30 != 0)
{
data[12] |= 8;
}
else
{
data[12] &= 0xF7;
}
var v29 = (byte)((data[9] >> 6) & 1);
if (((data[9] >> 5) & 1) != 0)
{
data[9] |= 0x40;
}
else
{
data[9] &= 0xBF;
}
if (v29 != 0)
{
data[9] |= 0x20;
}
else
{
data[9] &= 0xDF;
}
data[8] ^= 0x7F;
var v28 = (byte)((data[7] >> 7) & 1);
if (((data[7] >> 3) & 1) != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
if (v28 != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
var v27 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 3) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v27 != 0)
{
data[15] |= 8;
}
else
{
data[15] &= 0xF7;
}
var v17 = data[3];
data[3] = data[13];
data[13] = v17;
data[1] ^= 0x89;
var v18 = (byte)(data[4] >> 6);
data[4] *= 4;
data[4] |= v18;
var v19 = data[14];
data[14] = data[8];
data[8] = v19;
var v26 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 3) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v26 != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
data[12] ^= 0x76;
var v20 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v20;
}
}
else
{
data[5] ^= 0x78;
var v13 = data[5];
data[5] = data[4];
data[4] = v13;
var v32 = (byte)((data[0] >> 4) & 1);
if (((data[0] >> 5) & 1) != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
if (v32 != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
data[0] ^= 0xB8;
var v31 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v31 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v14 = (byte)(data[7] >> 4);
data[7] *= 16;
data[7] |= v14;
var v15 = data[4];
data[4] = data[6];
data[6] = v15;
data[4] ^= 0x4F;
data[0] ^= 0xD;
var v16 = data[7];
data[7] = data[2];
data[2] = v16;
}
}
else
{
var v3 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v3;
var v4 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v4;
var v5 = data[3];
data[3] = data[3];
data[3] = v5;
data[1] ^= 0xA7;
var v6 = data[1];
data[1] = data[0];
data[0] = v6;
var v7 = data[3];
data[3] = data[0];
data[0] = v7;
var v8 = data[3];
data[3] = data[0];
data[0] = v8;
var v9 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v9;
var v10 = data[0];
data[0] = data[1];
data[1] = v10;
var v11 = (byte)(data[2] >> 4);
data[2] *= 16;
data[2] |= v11;
data[2] ^= 0xCF;
var v12 = data[0];
data[0] = data[2];
data[2] = v12;
var v2 = (byte)((data[3] >> 6) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
if (v2 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v21 = (byte)(data[4] >> 1);
data[4] <<= 7;
data[4] |= v21;
var v22 = data[25];
data[25] = data[4];
data[4] = v22;
var v23 = (byte)(data[30] >> 5);
data[30] *= 8;
data[30] |= v23;
var v24 = data[9];
data[9] = data[27];
data[27] = v24;
data[18] ^= 0xB5;
data[13] ^= 0xF3;
var v25 = (byte)((data[11] >> 4) & 1);
if (((data[11] >> 1) & 1) != 0)
{
data[11] |= 0x10;
}
else
{
data[11] &= 0xEF;
}
if (v25 != 0)
{
data[11] |= 2;
}
else
{
data[11] &= 0xFD;
}
}
else
{
var v17 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v17;
data[12] ^= 0x76;
var v30 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 3) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v30 != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
var v18 = data[14];
data[14] = data[8];
data[8] = v18;
var v19 = (byte)(data[4] >> 2);
data[4] <<= 6;
data[4] |= v19;
data[1] ^= 0x89;
var v20 = data[3];
data[3] = data[13];
data[13] = v20;
var v29 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 3) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v29 != 0)
{
data[15] |= 8;
}
else
{
data[15] &= 0xF7;
}
var v28 = (byte)((data[7] >> 7) & 1);
if (((data[7] >> 3) & 1) != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
if (v28 != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
data[8] ^= 0x7F;
var v27 = (byte)((data[9] >> 6) & 1);
if (((data[9] >> 5) & 1) != 0)
{
data[9] |= 0x40;
}
else
{
data[9] &= 0xBF;
}
if (v27 != 0)
{
data[9] |= 0x20;
}
else
{
data[9] &= 0xDF;
}
var v26 = (byte)((data[12] >> 2) & 1);
if (((data[12] >> 3) & 1) != 0)
{
data[12] |= 4;
}
else
{
data[12] &= 0xFB;
}
if (v26 != 0)
{
data[12] |= 8;
}
else
{
data[12] &= 0xF7;
}
}
}
else
{
var v13 = data[7];
data[7] = data[2];
data[2] = v13;
data[0] ^= 0xD;
data[4] ^= 0x4F;
var v14 = data[4];
data[4] = data[6];
data[6] = v14;
var v15 = (byte)(data[7] >> 4);
data[7] *= 16;
data[7] |= v15;
var v32 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v32 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
data[0] ^= 0xB8;
var v31 = (byte)((data[0] >> 4) & 1);
if (((data[0] >> 5) & 1) != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
if (v31 != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
var v16 = data[5];
data[5] = data[4];
data[4] = v16;
data[5] ^= 0x78;
}
}
else
{
var v2 = (byte)((data[3] >> 6) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
if (v2 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v3 = data[0];
data[0] = data[2];
data[2] = v3;
data[2] ^= 0xCF;
var v4 = (byte)(data[2] >> 4);
data[2] *= 16;
data[2] |= v4;
var v5 = data[0];
data[0] = data[1];
data[1] = v5;
var v6 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v6;
var v7 = data[3];
data[3] = data[0];
data[0] = v7;
var v8 = data[3];
data[3] = data[0];
data[0] = v8;
var v9 = data[1];
data[1] = data[0];
data[0] = v9;
data[1] ^= 0xA7;
var v10 = data[3];
data[3] = data[3];
data[3] = v10;
var v11 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v11;
var v12 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v12;
}
}
}
}

View File

@@ -0,0 +1,521 @@
// <copyright file="PacketTwister81.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of an unknown type.
/// </summary>
internal class PacketTwister81 : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v16 = (byte)((data[14] >> 6) & 1);
if (((data[14] >> 2) & 1) != 0)
{
data[14] |= 0x40;
}
else
{
data[14] &= 0xBF;
}
if (v16 != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
var v13 = (byte)(data[9] >> 1);
data[9] <<= 7;
data[9] |= v13;
data[4] ^= 0xCE;
var v14 = (byte)(data[22] >> 2);
data[22] <<= 6;
data[22] |= v14;
var v15 = (byte)((data[6] >> 3) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
if (v15 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
data[28] ^= 0x6D;
}
else
{
var v19 = (byte)((data[13] >> 5) & 1);
if (((data[13] >> 7) & 1) != 0)
{
data[13] |= 0x20;
}
else
{
data[13] &= 0xDF;
}
if (v19 != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
var v12 = (byte)(data[14] >> 3);
data[14] *= 32;
data[14] |= v12;
var v18 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 5) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v18 != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
var v17 = (byte)((data[14] >> 2) & 1);
if (((data[14] >> 7) & 1) != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
if (v17 != 0)
{
data[14] |= 0x80;
}
else
{
data[14] &= 0x7F;
}
data[7] ^= 0x79;
data[4] ^= 0x3A;
}
}
else
{
var v21 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v21 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
var v9 = (byte)(data[6] >> 4);
data[6] *= 16;
data[6] |= v9;
var v20 = (byte)((data[7] >> 3) & 1);
if (((data[7] >> 7) & 1) != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
if (v20 != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
var v10 = data[5];
data[5] = data[2];
data[2] = v10;
var v11 = data[0];
data[0] = data[4];
data[4] = v11;
}
}
else
{
var v3 = data[3];
data[3] = data[1];
data[1] = v3;
var v4 = data[2];
data[2] = data[0];
data[0] = v4;
var v5 = (byte)(data[0] >> 5);
data[0] *= 8;
data[0] |= v5;
var v6 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v6;
data[0] ^= 0x7C;
var v7 = data[0];
data[0] = data[1];
data[1] = v7;
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v23 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 5) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v23 != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
var v8 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v8;
var v22 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v22 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[28] ^= 0x6D;
var v16 = (byte)((data[6] >> 3) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
if (v16 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
var v13 = (byte)(data[22] >> 6);
data[22] *= 4;
data[22] |= v13;
data[4] ^= 0xCE;
var v14 = (byte)(data[9] >> 7);
data[9] *= 2;
data[9] |= v14;
var v15 = (byte)((data[14] >> 6) & 1);
if (((data[14] >> 2) & 1) != 0)
{
data[14] |= 0x40;
}
else
{
data[14] &= 0xBF;
}
if (v15 != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
}
else
{
data[4] ^= 0x3A;
data[7] ^= 0x79;
var v19 = (byte)((data[14] >> 2) & 1);
if (((data[14] >> 7) & 1) != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
if (v19 != 0)
{
data[14] |= 0x80;
}
else
{
data[14] &= 0x7F;
}
var v18 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 5) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v18 != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
var v12 = (byte)(data[14] >> 5);
data[14] *= 8;
data[14] |= v12;
var v17 = (byte)((data[13] >> 5) & 1);
if (((data[13] >> 7) & 1) != 0)
{
data[13] |= 0x20;
}
else
{
data[13] &= 0xDF;
}
if (v17 != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
}
}
else
{
var v9 = data[0];
data[0] = data[4];
data[4] = v9;
var v10 = data[5];
data[5] = data[2];
data[2] = v10;
var v21 = (byte)((data[7] >> 3) & 1);
if (((data[7] >> 7) & 1) != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
if (v21 != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
var v11 = (byte)(data[6] >> 4);
data[6] *= 16;
data[6] |= v11;
var v20 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v20 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
}
}
else
{
var v2 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v2 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v3 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v3;
var v23 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 5) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v23 != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
var v22 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v22 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v4 = data[0];
data[0] = data[1];
data[1] = v4;
data[0] ^= 0x7C;
var v5 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v5;
var v6 = (byte)(data[0] >> 3);
data[0] *= 32;
data[0] |= v6;
var v7 = data[2];
data[2] = data[0];
data[0] = v7;
var v8 = data[3];
data[3] = data[1];
data[1] = v8;
}
}
}
}

View File

@@ -0,0 +1,459 @@
// <copyright file="PacketTwisterDevilSquareRemainingTime.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'DevilSquareRemainingTime' type.
/// </summary>
internal class PacketTwisterDevilSquareRemainingTime : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = data[11];
data[11] = data[16];
data[16] = v17;
var v18 = (byte)(data[29] >> 2);
data[29] <<= 6;
data[29] |= v18;
var v19 = (byte)(data[31] >> 1);
data[31] <<= 7;
data[31] |= v19;
var v20 = data[3];
data[3] = data[30];
data[30] = v20;
var v21 = (byte)(data[31] >> 5);
data[31] *= 8;
data[31] |= v21;
var v22 = data[23];
data[23] = data[27];
data[27] = v22;
var v23 = data[7];
data[7] = data[5];
data[5] = v23;
var v24 = data[1];
data[1] = data[19];
data[19] = v24;
var v25 = data[31];
data[31] = data[27];
data[27] = v25;
var v26 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v26;
data[29] ^= 0x2D;
var v27 = (byte)(data[28] >> 7);
data[28] *= 2;
data[28] |= v27;
}
else
{
var v14 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v14;
data[13] ^= 0x1F;
var v15 = (byte)(data[12] >> 2);
data[12] <<= 6;
data[12] |= v15;
data[11] ^= 0x88;
data[0] ^= 0x90;
var v28 = (byte)((data[14] >> 2) & 1);
if (((data[14] >> 7) & 1) != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
if (v28 != 0)
{
data[14] |= 0x80;
}
else
{
data[14] &= 0x7F;
}
var v16 = data[8];
data[8] = data[9];
data[9] = v16;
data[9] ^= 0x28;
}
}
else
{
var v9 = data[3];
data[3] = data[6];
data[6] = v9;
var v30 = (byte)((data[4] >> 4) & 1);
if (((data[4] >> 5) & 1) != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
if (v30 != 0)
{
data[4] |= 0x20;
}
else
{
data[4] &= 0xDF;
}
var v10 = data[1];
data[1] = data[2];
data[2] = v10;
data[2] ^= 0x5C;
var v29 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 5) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v29 != 0)
{
data[4] |= 0x20;
}
else
{
data[4] &= 0xDF;
}
var v11 = data[0];
data[0] = data[0];
data[0] = v11;
data[6] ^= 1;
data[7] ^= 0x23;
var v12 = data[3];
data[3] = data[5];
data[5] = v12;
var v13 = data[1];
data[1] = data[6];
data[6] = v13;
}
}
else
{
var v3 = data[2];
data[2] = data[1];
data[1] = v3;
var v4 = data[1];
data[1] = data[3];
data[3] = v4;
var v5 = data[1];
data[1] = data[0];
data[0] = v5;
data[2] ^= 0x46;
var v2 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v2 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v6 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v6;
var v7 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v7;
var v32 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v32 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v31 = (byte)((data[1] >> 4) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
if (v31 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v8 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v8;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = (byte)(data[28] >> 1);
data[28] <<= 7;
data[28] |= v17;
data[29] ^= 0x2D;
var v18 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v18;
var v19 = data[31];
data[31] = data[27];
data[27] = v19;
var v20 = data[1];
data[1] = data[19];
data[19] = v20;
var v21 = data[7];
data[7] = data[5];
data[5] = v21;
var v22 = data[23];
data[23] = data[27];
data[27] = v22;
var v23 = (byte)(data[31] >> 3);
data[31] *= 32;
data[31] |= v23;
var v24 = data[3];
data[3] = data[30];
data[30] = v24;
var v25 = (byte)(data[31] >> 7);
data[31] *= 2;
data[31] |= v25;
var v26 = (byte)(data[29] >> 6);
data[29] *= 4;
data[29] |= v26;
var v27 = data[11];
data[11] = data[16];
data[16] = v27;
}
else
{
data[9] ^= 0x28;
var v14 = data[8];
data[8] = data[9];
data[9] = v14;
var v28 = (byte)((data[14] >> 2) & 1);
if (((data[14] >> 7) & 1) != 0)
{
data[14] |= 4;
}
else
{
data[14] &= 0xFB;
}
if (v28 != 0)
{
data[14] |= 0x80;
}
else
{
data[14] &= 0x7F;
}
data[0] ^= 0x90;
data[11] ^= 0x88;
var v15 = (byte)(data[12] >> 6);
data[12] *= 4;
data[12] |= v15;
data[13] ^= 0x1F;
var v16 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v16;
}
}
else
{
var v9 = data[1];
data[1] = data[6];
data[6] = v9;
var v10 = data[3];
data[3] = data[5];
data[5] = v10;
data[7] ^= 0x23;
data[6] ^= 1;
var v11 = data[0];
data[0] = data[0];
data[0] = v11;
var v30 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 5) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v30 != 0)
{
data[4] |= 0x20;
}
else
{
data[4] &= 0xDF;
}
data[2] ^= 0x5C;
var v12 = data[1];
data[1] = data[2];
data[2] = v12;
var v29 = (byte)((data[4] >> 4) & 1);
if (((data[4] >> 5) & 1) != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
if (v29 != 0)
{
data[4] |= 0x20;
}
else
{
data[4] &= 0xDF;
}
var v13 = data[3];
data[3] = data[6];
data[6] = v13;
}
}
else
{
var v3 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v3;
var v2 = (byte)((data[1] >> 4) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
if (v2 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v32 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v32 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v4 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v4;
var v5 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v5;
var v31 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v31 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[2] ^= 0x46;
var v6 = data[1];
data[1] = data[0];
data[0] = v6;
var v7 = data[1];
data[1] = data[3];
data[3] = v7;
var v8 = data[2];
data[2] = data[1];
data[1] = v8;
}
}
}
}

View File

@@ -0,0 +1,486 @@
// <copyright file="PacketTwisterOfAllianceJoinRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'AllianceJoinRequest' type.
/// </summary>
internal class PacketTwisterOfAllianceJoinRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[8] ^= 0x15;
var v20 = data[1];
data[1] = data[17];
data[17] = v20;
data[2] ^= 0x27;
var v21 = data[3];
data[3] = data[20];
data[20] = v21;
var v26 = (byte)((data[30] >> 3) & 1);
if (((data[30] >> 7) & 1) != 0)
{
data[30] |= 8;
}
else
{
data[30] &= 0xF7;
}
if (v26 != 0)
{
data[30] |= 0x80;
}
else
{
data[30] &= 0x7F;
}
var v22 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v22;
var v25 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v25 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v23 = data[16];
data[16] = data[16];
data[16] = v23;
data[31] ^= 0x97;
var v24 = (byte)(data[6] >> 6);
data[6] *= 4;
data[6] |= v24;
}
else
{
var v11 = data[14];
data[14] = data[2];
data[2] = v11;
var v12 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v12;
var v13 = (byte)(data[7] >> 2);
data[7] <<= 6;
data[7] |= v13;
data[10] ^= 0x94;
var v14 = (byte)(data[2] >> 3);
data[2] *= 32;
data[2] |= v14;
var v15 = data[0];
data[0] = data[5];
data[5] = v15;
var v16 = data[1];
data[1] = data[15];
data[15] = v16;
var v17 = data[15];
data[15] = data[15];
data[15] = v17;
var v18 = data[13];
data[13] = data[1];
data[1] = v18;
var v19 = data[5];
data[5] = data[12];
data[12] = v19;
}
}
else
{
data[4] ^= 0xAF;
data[2] ^= 0x77;
data[0] ^= 0xA7;
var v29 = (byte)((data[3] >> 3) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
if (v29 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v28 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v28 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v10 = (byte)(data[7] >> 6);
data[7] *= 4;
data[7] |= v10;
var v27 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v27 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
data[7] ^= 0xE1;
data[2] ^= 5;
data[2] ^= 0x73;
}
}
else
{
var v2 = (byte)((data[3] >> 1) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
if (v2 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v3 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v3;
data[2] ^= 0xED;
data[3] ^= 0x52;
var v4 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v4;
var v5 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v5;
var v6 = data[2];
data[2] = data[0];
data[0] = v6;
var v7 = data[3];
data[3] = data[3];
data[3] = v7;
var v8 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v8;
data[1] ^= 0x67;
var v30 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 3) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v30 != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
var v9 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v9;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v20 = (byte)(data[6] >> 2);
data[6] <<= 6;
data[6] |= v20;
data[31] ^= 0x97;
var v21 = data[16];
data[16] = data[16];
data[16] = v21;
var v26 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v26 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v22 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v22;
var v25 = (byte)((data[30] >> 3) & 1);
if (((data[30] >> 7) & 1) != 0)
{
data[30] |= 8;
}
else
{
data[30] &= 0xF7;
}
if (v25 != 0)
{
data[30] |= 0x80;
}
else
{
data[30] &= 0x7F;
}
var v23 = data[3];
data[3] = data[20];
data[20] = v23;
data[2] ^= 0x27;
var v24 = data[1];
data[1] = data[17];
data[17] = v24;
data[8] ^= 0x15;
}
else
{
var v11 = data[5];
data[5] = data[12];
data[12] = v11;
var v12 = data[13];
data[13] = data[1];
data[1] = v12;
var v13 = data[15];
data[15] = data[15];
data[15] = v13;
var v14 = data[1];
data[1] = data[15];
data[15] = v14;
var v15 = data[0];
data[0] = data[5];
data[5] = v15;
var v16 = (byte)(data[2] >> 5);
data[2] *= 8;
data[2] |= v16;
data[10] ^= 0x94;
var v17 = (byte)(data[7] >> 6);
data[7] *= 4;
data[7] |= v17;
var v18 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v18;
var v19 = data[14];
data[14] = data[2];
data[2] = v19;
}
}
else
{
data[2] ^= 0x73;
data[2] ^= 5;
data[7] ^= 0xE1;
var v29 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v29 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v10 = (byte)(data[7] >> 2);
data[7] <<= 6;
data[7] |= v10;
var v28 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v28 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v27 = (byte)((data[3] >> 3) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
if (v27 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
data[0] ^= 0xA7;
data[2] ^= 0x77;
data[4] ^= 0xAF;
}
}
else
{
var v3 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v3;
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 3) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
data[1] ^= 0x67;
var v4 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v4;
var v5 = data[3];
data[3] = data[3];
data[3] = v5;
var v6 = data[2];
data[2] = data[0];
data[0] = v6;
var v7 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v7;
var v8 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v8;
data[3] ^= 0x52;
data[2] ^= 0xED;
var v9 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v9;
var v30 = (byte)((data[3] >> 1) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
if (v30 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
}
}
}
}

View File

@@ -0,0 +1,690 @@
// <copyright file="PacketTwisterOfAnimation.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'Animation' type.
/// </summary>
internal class PacketTwisterOfAnimation : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[29] ^= 0x7A;
var v23 = (byte)((data[18] >> 7) & 1);
if (((data[18] >> 3) & 1) != 0)
{
data[18] |= 0x80;
}
else
{
data[18] &= 0x7F;
}
if (v23 != 0)
{
data[18] |= 8;
}
else
{
data[18] &= 0xF7;
}
var v22 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 4) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v22 != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
var v15 = data[27];
data[27] = data[2];
data[2] = v15;
var v16 = (byte)(data[9] >> 5);
data[9] *= 8;
data[9] |= v16;
var v21 = (byte)((data[19] >> 6) & 1);
if (((data[19] >> 3) & 1) != 0)
{
data[19] |= 0x40;
}
else
{
data[19] &= 0xBF;
}
if (v21 != 0)
{
data[19] |= 8;
}
else
{
data[19] &= 0xF7;
}
var v17 = (byte)(data[11] >> 1);
data[11] <<= 7;
data[11] |= v17;
var v20 = (byte)((data[27] >> 6) & 1);
if (((data[27] >> 5) & 1) != 0)
{
data[27] |= 0x40;
}
else
{
data[27] &= 0xBF;
}
if (v20 != 0)
{
data[27] |= 0x20;
}
else
{
data[27] &= 0xDF;
}
var v19 = (byte)((data[24] >> 2) & 1);
if (((data[24] >> 6) & 1) != 0)
{
data[24] |= 4;
}
else
{
data[24] &= 0xFB;
}
if (v19 != 0)
{
data[24] |= 0x40;
}
else
{
data[24] &= 0xBF;
}
var v18 = (byte)((data[28] >> 6) & 1);
if (((data[28] >> 5) & 1) != 0)
{
data[28] |= 0x40;
}
else
{
data[28] &= 0xBF;
}
if (v18 != 0)
{
data[28] |= 0x20;
}
else
{
data[28] &= 0xDF;
}
}
else
{
var v9 = (byte)(data[12] >> 5);
data[12] *= 8;
data[12] |= v9;
var v10 = data[8];
data[8] = data[1];
data[1] = v10;
var v11 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v11;
var v25 = (byte)((data[14] >> 6) & 1);
if (((data[14] >> 1) & 1) != 0)
{
data[14] |= 0x40;
}
else
{
data[14] &= 0xBF;
}
if (v25 != 0)
{
data[14] |= 2;
}
else
{
data[14] &= 0xFD;
}
var v12 = (byte)(data[7] >> 4);
data[7] *= 16;
data[7] |= v12;
data[8] ^= 0xCE;
var v24 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v24 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v13 = (byte)(data[9] >> 6);
data[9] *= 4;
data[9] |= v13;
var v14 = (byte)(data[4] >> 3);
data[4] *= 32;
data[4] |= v14;
}
}
else
{
var v3 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v3;
var v30 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v30 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
var v29 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v29 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v4 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v4;
var v5 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v5;
var v28 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v28 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v27 = (byte)((data[6] >> 7) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
if (v27 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
var v6 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v6;
var v7 = data[0];
data[0] = data[2];
data[2] = v7;
var v8 = (byte)(data[6] >> 4);
data[6] *= 16;
data[6] |= v8;
var v26 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 7) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v26 != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
}
}
else
{
var v2 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v2 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
data[1] = data[1];
data[1] ^= 0xB2;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v23 = (byte)((data[28] >> 6) & 1);
if (((data[28] >> 5) & 1) != 0)
{
data[28] |= 0x40;
}
else
{
data[28] &= 0xBF;
}
if (v23 != 0)
{
data[28] |= 0x20;
}
else
{
data[28] &= 0xDF;
}
var v22 = (byte)((data[24] >> 2) & 1);
if (((data[24] >> 6) & 1) != 0)
{
data[24] |= 4;
}
else
{
data[24] &= 0xFB;
}
if (v22 != 0)
{
data[24] |= 0x40;
}
else
{
data[24] &= 0xBF;
}
var v21 = (byte)((data[27] >> 6) & 1);
if (((data[27] >> 5) & 1) != 0)
{
data[27] |= 0x40;
}
else
{
data[27] &= 0xBF;
}
if (v21 != 0)
{
data[27] |= 0x20;
}
else
{
data[27] &= 0xDF;
}
var v15 = (byte)(data[11] >> 7);
data[11] *= 2;
data[11] |= v15;
var v20 = (byte)((data[19] >> 6) & 1);
if (((data[19] >> 3) & 1) != 0)
{
data[19] |= 0x40;
}
else
{
data[19] &= 0xBF;
}
if (v20 != 0)
{
data[19] |= 8;
}
else
{
data[19] &= 0xF7;
}
var v16 = (byte)(data[9] >> 3);
data[9] *= 32;
data[9] |= v16;
var v17 = data[27];
data[27] = data[2];
data[2] = v17;
var v19 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 4) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v19 != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
var v18 = (byte)((data[18] >> 7) & 1);
if (((data[18] >> 3) & 1) != 0)
{
data[18] |= 0x80;
}
else
{
data[18] &= 0x7F;
}
if (v18 != 0)
{
data[18] |= 8;
}
else
{
data[18] &= 0xF7;
}
data[29] ^= 0x7A;
}
else
{
var v9 = (byte)(data[4] >> 5);
data[4] *= 8;
data[4] |= v9;
var v10 = (byte)(data[9] >> 2);
data[9] <<= 6;
data[9] |= v10;
var v25 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v25 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[8] ^= 0xCE;
var v11 = (byte)(data[7] >> 4);
data[7] *= 16;
data[7] |= v11;
var v24 = (byte)((data[14] >> 6) & 1);
if (((data[14] >> 1) & 1) != 0)
{
data[14] |= 0x40;
}
else
{
data[14] &= 0xBF;
}
if (v24 != 0)
{
data[14] |= 2;
}
else
{
data[14] &= 0xFD;
}
var v12 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v12;
var v13 = data[8];
data[8] = data[1];
data[1] = v13;
var v14 = (byte)(data[12] >> 3);
data[12] *= 32;
data[12] |= v14;
}
}
else
{
var v30 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 7) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v30 != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
var v3 = (byte)(data[6] >> 4);
data[6] *= 16;
data[6] |= v3;
var v4 = data[0];
data[0] = data[2];
data[2] = v4;
var v5 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v5;
var v29 = (byte)((data[6] >> 7) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
if (v29 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
var v28 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v28 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v6 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v6;
var v7 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v7;
var v27 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v27 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v26 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v26 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
var v8 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v8;
}
}
else
{
data[1] ^= 0xB2;
data[1] = data[1];
var v2 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v2 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
}
}
}
}

View File

@@ -0,0 +1,402 @@
// <copyright file="PacketTwisterOfBloodCastleEnterRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'BloodCastleEnterRequest' type.
/// </summary>
internal class PacketTwisterOfBloodCastleEnterRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v21 = (byte)((data[11] >> 7) & 1);
if (((data[11] >> 3) & 1) != 0)
{
data[11] |= 0x80;
}
else
{
data[11] &= 0x7F;
}
if (v21 != 0)
{
data[11] |= 8;
}
else
{
data[11] &= 0xF7;
}
var v14 = data[1];
data[1] = data[13];
data[13] = v14;
var v15 = data[3];
data[3] = data[5];
data[5] = v15;
var v16 = data[20];
data[20] = data[7];
data[7] = v16;
var v17 = data[15];
data[15] = data[4];
data[4] = v17;
data[4] ^= 0x6B;
var v20 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v20 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
var v18 = data[1];
data[1] = data[28];
data[28] = v18;
var v19 = data[24];
data[24] = data[9];
data[9] = v19;
}
else
{
var v7 = data[1];
data[1] = data[2];
data[2] = v7;
var v8 = (byte)(data[12] >> 2);
data[12] <<= 6;
data[12] |= v8;
var v9 = data[12];
data[12] = data[9];
data[9] = v9;
var v10 = data[3];
data[3] = data[7];
data[7] = v10;
var v11 = (byte)(data[9] >> 3);
data[9] *= 32;
data[9] |= v11;
var v12 = (byte)(data[12] >> 1);
data[12] <<= 7;
data[12] |= v12;
var v13 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v13;
}
}
else
{
data[0] ^= 0x4D;
var v5 = (byte)(data[4] >> 5);
data[4] *= 8;
data[4] |= v5;
var v24 = (byte)((data[7] >> 2) & 1);
if (((data[7] >> 3) & 1) != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
if (v24 != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
var v23 = (byte)((data[4] >> 1) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
if (v23 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v6 = data[5];
data[5] = data[3];
data[3] = v6;
var v22 = (byte)((data[3] >> 1) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
if (v22 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
data[7] ^= 0xC2;
data[7] ^= 0xCB;
}
}
else
{
var v3 = data[0];
data[0] = data[1];
data[1] = v3;
data[2] ^= 0x46;
var v2 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v2 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v4 = data[1];
data[1] = data[1];
data[1] = v4;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v14 = data[24];
data[24] = data[9];
data[9] = v14;
var v15 = data[1];
data[1] = data[28];
data[28] = v15;
var v21 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v21 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
data[4] ^= 0x6B;
var v16 = data[15];
data[15] = data[4];
data[4] = v16;
var v17 = data[20];
data[20] = data[7];
data[7] = v17;
var v18 = data[3];
data[3] = data[5];
data[5] = v18;
var v19 = data[1];
data[1] = data[13];
data[13] = v19;
var v20 = (byte)((data[11] >> 7) & 1);
if (((data[11] >> 3) & 1) != 0)
{
data[11] |= 0x80;
}
else
{
data[11] &= 0x7F;
}
if (v20 != 0)
{
data[11] |= 8;
}
else
{
data[11] &= 0xF7;
}
}
else
{
var v7 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v7;
var v8 = (byte)(data[12] >> 7);
data[12] *= 2;
data[12] |= v8;
var v9 = (byte)(data[9] >> 5);
data[9] *= 8;
data[9] |= v9;
var v10 = data[3];
data[3] = data[7];
data[7] = v10;
var v11 = data[12];
data[12] = data[9];
data[9] = v11;
var v12 = (byte)(data[12] >> 6);
data[12] *= 4;
data[12] |= v12;
var v13 = data[1];
data[1] = data[2];
data[2] = v13;
}
}
else
{
data[7] ^= 0xCB;
data[7] ^= 0xC2;
var v24 = (byte)((data[3] >> 1) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
if (v24 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v5 = data[5];
data[5] = data[3];
data[3] = v5;
var v23 = (byte)((data[4] >> 1) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
if (v23 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v22 = (byte)((data[7] >> 2) & 1);
if (((data[7] >> 3) & 1) != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
if (v22 != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
var v6 = (byte)(data[4] >> 3);
data[4] *= 32;
data[4] |= v6;
data[0] ^= 0x4D;
}
}
else
{
var v3 = data[1];
data[1] = data[1];
data[1] = v3;
var v2 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v2 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
data[2] ^= 0x46;
var v4 = data[0];
data[0] = data[1];
data[1] = v4;
}
}
}
}

View File

@@ -0,0 +1,456 @@
// <copyright file="PacketTwisterOfBloodCastleInfoRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'BloodCastleInfoRequest' type.
/// </summary>
internal class PacketTwisterOfBloodCastleInfoRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v22 = data[7];
data[7] = data[4];
data[4] = v22;
var v24 = (byte)((data[7] >> 3) & 1);
if (((data[7] >> 1) & 1) != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
if (v24 != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
data[12] ^= 0x56;
var v23 = (byte)((data[13] >> 5) & 1);
if (((data[13] >> 2) & 1) != 0)
{
data[13] |= 0x20;
}
else
{
data[13] &= 0xDF;
}
if (v23 != 0)
{
data[13] |= 4;
}
else
{
data[13] &= 0xFB;
}
}
else
{
var v16 = (byte)(data[5] >> 3);
data[5] *= 32;
data[5] |= v16;
var v17 = (byte)(data[11] >> 6);
data[11] *= 4;
data[11] |= v17;
data[3] ^= 0xF4;
var v27 = (byte)((data[1] >> 4) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
if (v27 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
var v26 = (byte)((data[9] >> 1) & 1);
if (((data[9] >> 4) & 1) != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
if (v26 != 0)
{
data[9] |= 0x10;
}
else
{
data[9] &= 0xEF;
}
var v18 = data[3];
data[3] = data[7];
data[7] = v18;
var v19 = data[3];
data[3] = data[0];
data[0] = v19;
var v20 = (byte)(data[14] >> 7);
data[14] *= 2;
data[14] |= v20;
var v25 = (byte)((data[2] >> 3) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
if (v25 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v21 = (byte)(data[1] >> 3);
data[1] *= 32;
data[1] |= v21;
}
}
else
{
var v13 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v13;
data[2] ^= 0xFE;
var v14 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v14;
var v15 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v15;
}
}
else
{
data[3] ^= 0x96;
var v3 = (byte)(data[0] >> 5);
data[0] *= 8;
data[0] |= v3;
var v4 = data[1];
data[1] = data[2];
data[2] = v4;
var v5 = (byte)(data[1] >> 4);
data[1] *= 16;
data[1] |= v5;
var v6 = data[0];
data[0] = data[2];
data[2] = v6;
var v7 = (byte)(data[3] >> 7);
data[3] *= 2;
data[3] |= v7;
var v2 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v2 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v8 = data[1];
data[1] = data[3];
data[3] = v8;
var v9 = data[2];
data[2] = data[1];
data[1] = v9;
var v10 = data[2];
data[2] = data[2];
data[2] = v10;
var v28 = (byte)((data[1] >> 6) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
if (v28 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v11 = data[3];
data[3] = data[0];
data[0] = v11;
var v12 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v12;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v24 = (byte)((data[13] >> 5) & 1);
if (((data[13] >> 2) & 1) != 0)
{
data[13] |= 0x20;
}
else
{
data[13] &= 0xDF;
}
if (v24 != 0)
{
data[13] |= 4;
}
else
{
data[13] &= 0xFB;
}
data[12] ^= 0x56;
var v23 = (byte)((data[7] >> 3) & 1);
if (((data[7] >> 1) & 1) != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
if (v23 != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
var v22 = data[7];
data[7] = data[4];
data[4] = v22;
}
else
{
var v16 = (byte)(data[1] >> 5);
data[1] *= 8;
data[1] |= v16;
var v27 = (byte)((data[2] >> 3) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
if (v27 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v17 = (byte)(data[14] >> 1);
data[14] <<= 7;
data[14] |= v17;
var v18 = data[3];
data[3] = data[0];
data[0] = v18;
var v19 = data[3];
data[3] = data[7];
data[7] = v19;
var v26 = (byte)((data[9] >> 1) & 1);
if (((data[9] >> 4) & 1) != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
if (v26 != 0)
{
data[9] |= 0x10;
}
else
{
data[9] &= 0xEF;
}
var v25 = (byte)((data[1] >> 4) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
if (v25 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
data[3] ^= 0xF4;
var v20 = (byte)(data[11] >> 2);
data[11] <<= 6;
data[11] |= v20;
var v21 = (byte)(data[5] >> 5);
data[5] *= 8;
data[5] |= v21;
}
}
else
{
var v13 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v13;
var v14 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v14;
data[2] ^= 0xFE;
var v15 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v15;
}
}
else
{
var v3 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v3;
var v4 = data[3];
data[3] = data[0];
data[0] = v4;
var v2 = (byte)((data[1] >> 6) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
if (v2 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v5 = data[2];
data[2] = data[2];
data[2] = v5;
var v6 = data[2];
data[2] = data[1];
data[1] = v6;
var v7 = data[1];
data[1] = data[3];
data[3] = v7;
var v28 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v28 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v8 = (byte)(data[3] >> 1);
data[3] <<= 7;
data[3] |= v8;
var v9 = data[0];
data[0] = data[2];
data[2] = v9;
var v10 = (byte)(data[1] >> 4);
data[1] *= 16;
data[1] |= v10;
var v11 = data[1];
data[1] = data[2];
data[2] = v11;
var v12 = (byte)(data[0] >> 3);
data[0] *= 32;
data[0] |= v12;
data[3] ^= 0x96;
}
}
}
}

View File

@@ -0,0 +1,293 @@
// <copyright file="PacketTwisterOfCashShop.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'CashShop' type.
/// </summary>
internal class PacketTwisterOfCashShop : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[21] ^= 0x1A;
var v17 = (byte)((data[13] >> 1) & 1);
if (((data[13] >> 7) & 1) != 0)
{
data[13] |= 2;
}
else
{
data[13] &= 0xFD;
}
if (v17 != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
var v11 = data[4];
data[4] = data[13];
data[13] = v11;
var v16 = (byte)((data[27] >> 1) & 1);
if (((data[27] >> 4) & 1) != 0)
{
data[27] |= 2;
}
else
{
data[27] &= 0xFD;
}
if (v16 != 0)
{
data[27] |= 0x10;
}
else
{
data[27] &= 0xEF;
}
var v12 = data[28];
data[28] = data[6];
data[6] = v12;
var v13 = (byte)(data[27] >> 1);
data[27] <<= 7;
data[27] |= v13;
data[13] ^= 0x77;
var v14 = (byte)(data[29] >> 2);
data[29] <<= 6;
data[29] |= v14;
var v15 = (byte)((data[26] >> 2) & 1);
if (((data[26] >> 4) & 1) != 0)
{
data[26] |= 4;
}
else
{
data[26] &= 0xFB;
}
if (v15 != 0)
{
data[26] |= 0x10;
}
else
{
data[26] &= 0xEF;
}
}
else
{
var v8 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v8;
data[13] ^= 0x5D;
var v9 = data[0];
data[0] = data[10];
data[10] = v9;
var v10 = (byte)(data[6] >> 7);
data[6] *= 2;
data[6] |= v10;
}
}
else
{
var v5 = data[3];
data[3] = data[1];
data[1] = v5;
var v6 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v6;
var v7 = data[6];
data[6] = data[7];
data[7] = v7;
}
}
else
{
var v2 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v2 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
var v3 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v3;
data[1] ^= 0x9F;
var v4 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v4;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = (byte)((data[26] >> 2) & 1);
if (((data[26] >> 4) & 1) != 0)
{
data[26] |= 4;
}
else
{
data[26] &= 0xFB;
}
if (v17 != 0)
{
data[26] |= 0x10;
}
else
{
data[26] &= 0xEF;
}
var v11 = (byte)(data[29] >> 6);
data[29] *= 4;
data[29] |= v11;
data[13] ^= 0x77;
var v12 = (byte)(data[27] >> 7);
data[27] *= 2;
data[27] |= v12;
var v13 = data[28];
data[28] = data[6];
data[6] = v13;
var v16 = (byte)((data[27] >> 1) & 1);
if (((data[27] >> 4) & 1) != 0)
{
data[27] |= 2;
}
else
{
data[27] &= 0xFD;
}
if (v16 != 0)
{
data[27] |= 0x10;
}
else
{
data[27] &= 0xEF;
}
var v14 = data[4];
data[4] = data[13];
data[13] = v14;
var v15 = (byte)((data[13] >> 1) & 1);
if (((data[13] >> 7) & 1) != 0)
{
data[13] |= 2;
}
else
{
data[13] &= 0xFD;
}
if (v15 != 0)
{
data[13] |= 0x80;
}
else
{
data[13] &= 0x7F;
}
data[21] ^= 0x1A;
}
else
{
var v8 = (byte)(data[6] >> 1);
data[6] <<= 7;
data[6] |= v8;
var v9 = data[0];
data[0] = data[10];
data[10] = v9;
data[13] ^= 0x5D;
var v10 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v10;
}
}
else
{
var v5 = data[6];
data[6] = data[7];
data[7] = v5;
var v6 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v6;
var v7 = data[3];
data[3] = data[1];
data[1] = v7;
}
}
else
{
var v3 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v3;
data[1] ^= 0x9F;
var v4 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v4;
var v2 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v2 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
}
}
}
}

View File

@@ -0,0 +1,719 @@
// <copyright file="PacketTwisterOfCastleSiege.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'CastleSiege' type.
/// </summary>
internal class PacketTwisterOfCastleSiege : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v19 = (byte)((data[10] >> 4) & 1);
if (((data[10] >> 4) & 1) != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
if (v19 != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
var v18 = (byte)((data[16] >> 2) & 1);
if (((data[16] >> 7) & 1) != 0)
{
data[16] |= 4;
}
else
{
data[16] &= 0xFB;
}
if (v18 != 0)
{
data[16] |= 0x80;
}
else
{
data[16] &= 0x7F;
}
var v14 = (byte)(data[19] >> 3);
data[19] *= 32;
data[19] |= v14;
data[22] ^= 0xD4;
var v17 = (byte)((data[11] >> 1) & 1);
if (((data[11] >> 1) & 1) != 0)
{
data[11] |= 2;
}
else
{
data[11] &= 0xFD;
}
if (v17 != 0)
{
data[11] |= 2;
}
else
{
data[11] &= 0xFD;
}
var v16 = (byte)((data[7] >> 7) & 1);
if (((data[7] >> 3) & 1) != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
if (v16 != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
var v15 = (byte)((data[22] >> 6) & 1);
if (((data[22] >> 4) & 1) != 0)
{
data[22] |= 0x40;
}
else
{
data[22] &= 0xBF;
}
if (v15 != 0)
{
data[22] |= 0x10;
}
else
{
data[22] &= 0xEF;
}
}
else
{
var v12 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v12;
data[0] ^= 0x62;
var v24 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 4) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v24 != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
var v23 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 2) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v23 != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
var v22 = (byte)((data[9] >> 2) & 1);
if (((data[9] >> 1) & 1) != 0)
{
data[9] |= 4;
}
else
{
data[9] &= 0xFB;
}
if (v22 != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
var v13 = data[7];
data[7] = data[5];
data[5] = v13;
var v21 = (byte)((data[4] >> 6) & 1);
if (((data[4] >> 2) & 1) != 0)
{
data[4] |= 0x40;
}
else
{
data[4] &= 0xBF;
}
if (v21 != 0)
{
data[4] |= 4;
}
else
{
data[4] &= 0xFB;
}
var v20 = (byte)((data[12] >> 6) & 1);
if (((data[12] >> 1) & 1) != 0)
{
data[12] |= 0x40;
}
else
{
data[12] &= 0xBF;
}
if (v20 != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
}
}
else
{
data[4] ^= 0x3B;
var v27 = (byte)((data[5] >> 6) & 1);
if (((data[5] >> 5) & 1) != 0)
{
data[5] |= 0x40;
}
else
{
data[5] &= 0xBF;
}
if (v27 != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
data[4] ^= 0x1D;
var v5 = data[3];
data[3] = data[5];
data[5] = v5;
var v26 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 3) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v26 != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
var v6 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v6;
var v7 = data[6];
data[6] = data[1];
data[1] = v7;
data[0] ^= 0x7C;
var v8 = (byte)(data[5] >> 5);
data[5] *= 8;
data[5] |= v8;
var v9 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v9;
var v10 = data[1];
data[1] = data[6];
data[6] = v10;
var v11 = data[3];
data[3] = data[1];
data[1] = v11;
var v25 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v25 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
}
}
else
{
var v3 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v3;
data[3] ^= 0xCA;
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v28 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 5) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v28 != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
var v4 = (byte)(data[0] >> 3);
data[0] *= 32;
data[0] |= v4;
data[1] ^= 0x1A;
data[2] ^= 0x20;
data[3] ^= 0x3C;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v19 = (byte)((data[22] >> 6) & 1);
if (((data[22] >> 4) & 1) != 0)
{
data[22] |= 0x40;
}
else
{
data[22] &= 0xBF;
}
if (v19 != 0)
{
data[22] |= 0x10;
}
else
{
data[22] &= 0xEF;
}
var v18 = (byte)((data[7] >> 7) & 1);
if (((data[7] >> 3) & 1) != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
if (v18 != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
var v17 = (byte)((data[11] >> 1) & 1);
if (((data[11] >> 1) & 1) != 0)
{
data[11] |= 2;
}
else
{
data[11] &= 0xFD;
}
if (v17 != 0)
{
data[11] |= 2;
}
else
{
data[11] &= 0xFD;
}
data[22] ^= 0xD4;
var v14 = (byte)(data[19] >> 5);
data[19] *= 8;
data[19] |= v14;
var v16 = (byte)((data[16] >> 2) & 1);
if (((data[16] >> 7) & 1) != 0)
{
data[16] |= 4;
}
else
{
data[16] &= 0xFB;
}
if (v16 != 0)
{
data[16] |= 0x80;
}
else
{
data[16] &= 0x7F;
}
var v15 = (byte)((data[10] >> 4) & 1);
if (((data[10] >> 4) & 1) != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
if (v15 != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
}
else
{
var v24 = (byte)((data[12] >> 6) & 1);
if (((data[12] >> 1) & 1) != 0)
{
data[12] |= 0x40;
}
else
{
data[12] &= 0xBF;
}
if (v24 != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
var v23 = (byte)((data[4] >> 6) & 1);
if (((data[4] >> 2) & 1) != 0)
{
data[4] |= 0x40;
}
else
{
data[4] &= 0xBF;
}
if (v23 != 0)
{
data[4] |= 4;
}
else
{
data[4] &= 0xFB;
}
var v12 = data[7];
data[7] = data[5];
data[5] = v12;
var v22 = (byte)((data[9] >> 2) & 1);
if (((data[9] >> 1) & 1) != 0)
{
data[9] |= 4;
}
else
{
data[9] &= 0xFB;
}
if (v22 != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
var v21 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 2) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v21 != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
var v20 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 4) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v20 != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
data[0] ^= 0x62;
var v13 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v13;
}
}
else
{
var v27 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v27 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
var v5 = data[3];
data[3] = data[1];
data[1] = v5;
var v6 = data[1];
data[1] = data[6];
data[6] = v6;
var v7 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v7;
var v8 = (byte)(data[5] >> 3);
data[5] *= 32;
data[5] |= v8;
data[0] ^= 0x7C;
var v9 = data[6];
data[6] = data[1];
data[1] = v9;
var v10 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v10;
var v26 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 3) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v26 != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
var v11 = data[3];
data[3] = data[5];
data[5] = v11;
data[4] ^= 0x1D;
var v25 = (byte)((data[5] >> 6) & 1);
if (((data[5] >> 5) & 1) != 0)
{
data[5] |= 0x40;
}
else
{
data[5] &= 0xBF;
}
if (v25 != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
data[4] ^= 0x3B;
}
}
else
{
data[3] ^= 0x3C;
data[2] ^= 0x20;
data[1] ^= 0x1A;
var v3 = (byte)(data[0] >> 5);
data[0] *= 8;
data[0] |= v3;
var v2 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 5) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v2 != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
var v28 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v28 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
data[3] ^= 0xCA;
var v4 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v4;
}
}
}
}

View File

@@ -0,0 +1,285 @@
// <copyright file="PacketTwisterOfCastleSiegeWeapon.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'CastleSiegeWeapon' type.
/// </summary>
internal class PacketTwisterOfCastleSiegeWeapon : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v13 = data[13];
data[13] = data[11];
data[11] = v13;
var v14 = data[18];
data[18] = data[11];
data[11] = v14;
var v15 = (byte)(data[16] >> 5);
data[16] *= 8;
data[16] |= v15;
data[28] ^= 0x11;
var v16 = (byte)(data[6] >> 4);
data[6] *= 16;
data[6] |= v16;
data[5] ^= 0xE7;
data[4] ^= 0x55;
var v17 = (byte)(data[15] >> 6);
data[15] *= 4;
data[15] |= v17;
}
else
{
var v18 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v18 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
var v8 = (byte)(data[5] >> 1);
data[5] <<= 7;
data[5] |= v8;
data[1] ^= 0x4B;
data[2] ^= 0x81;
var v9 = data[4];
data[4] = data[7];
data[7] = v9;
var v10 = (byte)(data[4] >> 7);
data[4] *= 2;
data[4] |= v10;
var v11 = (byte)(data[7] >> 6);
data[7] *= 4;
data[7] |= v11;
var v12 = (byte)(data[13] >> 3);
data[13] *= 32;
data[13] |= v12;
data[11] ^= 0xAC;
}
}
else
{
var v6 = (byte)(data[4] >> 5);
data[4] *= 8;
data[4] |= v6;
var v7 = data[0];
data[0] = data[6];
data[6] = v7;
data[0] ^= 0xEA;
data[6] ^= 2;
}
}
else
{
var v2 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v2 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
data[1] ^= 0xEB;
var v3 = data[3];
data[3] = data[1];
data[1] = v3;
var v4 = (byte)(data[3] >> 1);
data[3] <<= 7;
data[3] |= v4;
var v19 = (byte)((data[3] >> 6) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
if (v19 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
data[3] ^= 0xF6;
var v5 = (byte)(data[0] >> 4);
data[0] *= 16;
data[0] |= v5;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v13 = (byte)(data[15] >> 2);
data[15] <<= 6;
data[15] |= v13;
data[4] ^= 0x55;
data[5] ^= 0xE7;
var v14 = (byte)(data[6] >> 4);
data[6] *= 16;
data[6] |= v14;
data[28] ^= 0x11;
var v15 = (byte)(data[16] >> 3);
data[16] *= 32;
data[16] |= v15;
var v16 = data[18];
data[18] = data[11];
data[11] = v16;
var v17 = data[13];
data[13] = data[11];
data[11] = v17;
}
else
{
data[11] ^= 0xAC;
var v8 = (byte)(data[13] >> 5);
data[13] *= 8;
data[13] |= v8;
var v9 = (byte)(data[7] >> 2);
data[7] <<= 6;
data[7] |= v9;
var v10 = (byte)(data[4] >> 1);
data[4] <<= 7;
data[4] |= v10;
var v11 = data[4];
data[4] = data[7];
data[7] = v11;
data[2] ^= 0x81;
data[1] ^= 0x4B;
var v12 = (byte)(data[5] >> 7);
data[5] *= 2;
data[5] |= v12;
var v18 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v18 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
}
}
else
{
data[6] ^= 2;
data[0] ^= 0xEA;
var v6 = data[0];
data[0] = data[6];
data[6] = v6;
var v7 = (byte)(data[4] >> 3);
data[4] *= 32;
data[4] |= v7;
}
}
else
{
var v3 = (byte)(data[0] >> 4);
data[0] *= 16;
data[0] |= v3;
data[3] ^= 0xF6;
var v2 = (byte)((data[3] >> 6) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
if (v2 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v4 = (byte)(data[3] >> 7);
data[3] *= 2;
data[3] |= v4;
var v5 = data[3];
data[3] = data[1];
data[1] = v5;
data[1] ^= 0xEB;
var v19 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v19 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
}
}
}
}

View File

@@ -0,0 +1,474 @@
// <copyright file="PacketTwisterOfChaosMachineClose.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'ChaosMachineClose' type.
/// </summary>
internal class PacketTwisterOfChaosMachineClose : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v13 = data[13];
data[13] = data[7];
data[7] = v13;
var v14 = data[13];
data[13] = data[23];
data[23] = v14;
var v15 = (byte)(data[15] >> 4);
data[15] *= 16;
data[15] |= v15;
var v16 = data[26];
data[26] = data[6];
data[6] = v16;
var v17 = data[27];
data[27] = data[8];
data[8] = v17;
data[19] ^= 0xF0;
data[28] ^= 0x57;
var v18 = (byte)(data[16] >> 3);
data[16] *= 32;
data[16] |= v18;
data[3] ^= 0x26;
}
else
{
var v22 = (byte)((data[12] >> 5) & 1);
if (((data[12] >> 1) & 1) != 0)
{
data[12] |= 0x20;
}
else
{
data[12] &= 0xDF;
}
if (v22 != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
var v21 = (byte)((data[6] >> 1) & 1);
if (((data[6] >> 5) & 1) != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
if (v21 != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
data[9] ^= 0x6D;
var v20 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 6) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v20 != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
var v19 = (byte)((data[4] >> 3) & 1);
if (((data[4] >> 6) & 1) != 0)
{
data[4] |= 8;
}
else
{
data[4] &= 0xF7;
}
if (v19 != 0)
{
data[4] |= 0x40;
}
else
{
data[4] &= 0xBF;
}
var v10 = (byte)(data[15] >> 5);
data[15] *= 8;
data[15] |= v10;
var v11 = data[7];
data[7] = data[15];
data[15] = v11;
var v12 = (byte)(data[2] >> 5);
data[2] *= 8;
data[2] |= v12;
}
}
else
{
var v6 = (byte)(data[6] >> 7);
data[6] *= 2;
data[6] |= v6;
data[3] ^= 0xED;
var v7 = data[4];
data[4] = data[6];
data[6] = v7;
var v8 = data[5];
data[5] = data[6];
data[6] = v8;
var v9 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v9;
var v23 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 1) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v23 != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
data[1] ^= 0xF3;
}
}
else
{
var v3 = (byte)(data[0] >> 3);
data[0] *= 32;
data[0] |= v3;
var v2 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v2 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
var v25 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v25 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v24 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v24 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v4 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v4;
var v5 = data[2];
data[2] = data[3];
data[3] = v5;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[3] ^= 0x26;
var v13 = (byte)(data[16] >> 5);
data[16] *= 8;
data[16] |= v13;
data[28] ^= 0x57;
data[19] ^= 0xF0;
var v14 = data[27];
data[27] = data[8];
data[8] = v14;
var v15 = data[26];
data[26] = data[6];
data[6] = v15;
var v16 = (byte)(data[15] >> 4);
data[15] *= 16;
data[15] |= v16;
var v17 = data[13];
data[13] = data[23];
data[23] = v17;
var v18 = data[13];
data[13] = data[7];
data[7] = v18;
}
else
{
var v10 = (byte)(data[2] >> 3);
data[2] *= 32;
data[2] |= v10;
var v11 = data[7];
data[7] = data[15];
data[15] = v11;
var v12 = (byte)(data[15] >> 3);
data[15] *= 32;
data[15] |= v12;
var v22 = (byte)((data[4] >> 3) & 1);
if (((data[4] >> 6) & 1) != 0)
{
data[4] |= 8;
}
else
{
data[4] &= 0xF7;
}
if (v22 != 0)
{
data[4] |= 0x40;
}
else
{
data[4] &= 0xBF;
}
var v21 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 6) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v21 != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
data[9] ^= 0x6D;
var v20 = (byte)((data[6] >> 1) & 1);
if (((data[6] >> 5) & 1) != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
if (v20 != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
var v19 = (byte)((data[12] >> 5) & 1);
if (((data[12] >> 1) & 1) != 0)
{
data[12] |= 0x20;
}
else
{
data[12] &= 0xDF;
}
if (v19 != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
}
}
else
{
data[1] ^= 0xF3;
var v23 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 1) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v23 != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
var v6 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v6;
var v7 = data[5];
data[5] = data[6];
data[6] = v7;
var v8 = data[4];
data[4] = data[6];
data[6] = v8;
data[3] ^= 0xED;
var v9 = (byte)(data[6] >> 1);
data[6] <<= 7;
data[6] |= v9;
}
}
else
{
var v3 = data[2];
data[2] = data[3];
data[3] = v3;
var v4 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v4;
var v2 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v2 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v25 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v25 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v24 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v24 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
var v5 = (byte)(data[0] >> 5);
data[0] *= 8;
data[0] |= v5;
}
}
}
}

View File

@@ -0,0 +1,262 @@
// <copyright file="PacketTwisterOfChaosMachineMix.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'ChaosMachineMix' type.
/// </summary>
internal class PacketTwisterOfChaosMachineMix : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v10 = data[12];
data[12] = data[10];
data[10] = v10;
var v15 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v15 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v11 = data[27];
data[27] = data[27];
data[27] = v11;
data[31] ^= 0xB4;
var v12 = data[3];
data[3] = data[2];
data[2] = v12;
var v13 = data[19];
data[19] = data[22];
data[22] = v13;
data[12] ^= 0x8F;
var v14 = data[9];
data[9] = data[7];
data[7] = v14;
data[26] ^= 0xA2;
}
else
{
data[10] ^= 0xD1;
var v8 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v8;
var v9 = data[0];
data[0] = data[6];
data[6] = v9;
}
}
else
{
var v4 = data[2];
data[2] = data[7];
data[7] = v4;
var v5 = data[1];
data[1] = data[2];
data[2] = v5;
var v6 = data[7];
data[7] = data[4];
data[4] = v6;
var v7 = data[3];
data[3] = data[5];
data[5] = v7;
data[2] ^= 0xCB;
}
}
else
{
var v2 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v2 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
var v16 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v16 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
data[3] ^= 0x14;
var v3 = (byte)(data[0] >> 5);
data[0] *= 8;
data[0] |= v3;
data[1] ^= 0xD2;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[26] ^= 0xA2;
var v10 = data[9];
data[9] = data[7];
data[7] = v10;
data[12] ^= 0x8F;
var v11 = data[19];
data[19] = data[22];
data[22] = v11;
var v12 = data[3];
data[3] = data[2];
data[2] = v12;
data[31] ^= 0xB4;
var v13 = data[27];
data[27] = data[27];
data[27] = v13;
var v15 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v15 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v14 = data[12];
data[12] = data[10];
data[10] = v14;
}
else
{
var v8 = data[0];
data[0] = data[6];
data[6] = v8;
var v9 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v9;
data[10] ^= 0xD1;
}
}
else
{
data[2] ^= 0xCB;
var v4 = data[3];
data[3] = data[5];
data[5] = v4;
var v5 = data[7];
data[7] = data[4];
data[4] = v5;
var v6 = data[1];
data[1] = data[2];
data[2] = v6;
var v7 = data[2];
data[2] = data[7];
data[7] = v7;
}
}
else
{
data[1] ^= 0xD2;
var v3 = (byte)(data[0] >> 3);
data[0] *= 32;
data[0] |= v3;
data[3] ^= 0x14;
var v2 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v2 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
var v16 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v16 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
}
}
}
}

View File

@@ -0,0 +1,452 @@
// <copyright file="PacketTwisterOfCharacterManagement.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'CharacterManagement' type.
/// </summary>
internal class PacketTwisterOfCharacterManagement : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[29] ^= 0xC0;
var v14 = (byte)(data[12] >> 4);
data[12] *= 16;
data[12] |= v14;
data[14] ^= 0xAF;
}
else
{
var v16 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v16 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v10 = data[2];
data[2] = data[8];
data[8] = v10;
data[5] ^= 0x99;
data[1] ^= 0x94;
var v11 = data[10];
data[10] = data[7];
data[7] = v11;
var v12 = (byte)(data[7] >> 4);
data[7] *= 16;
data[7] |= v12;
var v15 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v15 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v13 = (byte)(data[13] >> 6);
data[13] *= 4;
data[13] |= v13;
}
}
else
{
var v21 = (byte)((data[5] >> 2) & 1);
if (((data[5] >> 1) & 1) != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
if (v21 != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
var v6 = data[6];
data[6] = data[7];
data[7] = v6;
var v7 = data[0];
data[0] = data[5];
data[5] = v7;
data[3] ^= 0x6E;
var v8 = data[7];
data[7] = data[7];
data[7] = v8;
data[7] ^= 0x2A;
var v20 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v20 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
data[7] ^= 0xE6;
var v19 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 2) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v19 != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
var v18 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v18 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
data[5] ^= 0xC2;
var v17 = (byte)((data[2] >> 3) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
if (v17 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v9 = data[5];
data[5] = data[6];
data[6] = v9;
}
}
else
{
var v3 = data[1];
data[1] = data[0];
data[0] = v3;
var v4 = data[0];
data[0] = data[1];
data[1] = v4;
var v5 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v5;
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[14] ^= 0xAF;
var v14 = (byte)(data[12] >> 4);
data[12] *= 16;
data[12] |= v14;
data[29] ^= 0xC0;
}
else
{
var v10 = (byte)(data[13] >> 2);
data[13] <<= 6;
data[13] |= v10;
var v16 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v16 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v11 = (byte)(data[7] >> 4);
data[7] *= 16;
data[7] |= v11;
var v12 = data[10];
data[10] = data[7];
data[7] = v12;
data[1] ^= 0x94;
data[5] ^= 0x99;
var v13 = data[2];
data[2] = data[8];
data[8] = v13;
var v15 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v15 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
}
}
else
{
var v6 = data[5];
data[5] = data[6];
data[6] = v6;
var v21 = (byte)((data[2] >> 3) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
if (v21 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
data[5] ^= 0xC2;
var v20 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v20 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v19 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 2) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v19 != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
data[7] ^= 0xE6;
var v18 = (byte)((data[3] >> 7) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
if (v18 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
data[7] ^= 0x2A;
var v7 = data[7];
data[7] = data[7];
data[7] = v7;
data[3] ^= 0x6E;
var v8 = data[0];
data[0] = data[5];
data[5] = v8;
var v9 = data[6];
data[6] = data[7];
data[7] = v9;
var v17 = (byte)((data[5] >> 2) & 1);
if (((data[5] >> 1) & 1) != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
if (v17 != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
}
}
else
{
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v3 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v3;
var v4 = data[0];
data[0] = data[1];
data[1] = v4;
var v5 = data[1];
data[1] = data[0];
data[0] = v5;
}
}
}
}

View File

@@ -0,0 +1,711 @@
// <copyright file="PacketTwisterOfChat.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'Chat' type.
/// </summary>
internal class PacketTwisterOfChat : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[13] ^= 0x26;
var v17 = data[5];
data[5] = data[3];
data[3] = v17;
data[5] ^= 0x91;
var v18 = (byte)(data[6] >> 4);
data[6] *= 16;
data[6] |= v18;
data[29] ^= 0x96;
var v19 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v19;
data[15] ^= 0x61;
var v21 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v21 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v20 = (byte)((data[16] >> 3) & 1);
if (((data[16] >> 6) & 1) != 0)
{
data[16] |= 8;
}
else
{
data[16] &= 0xF7;
}
if (v20 != 0)
{
data[16] |= 0x40;
}
else
{
data[16] &= 0xBF;
}
}
else
{
var v12 = (byte)(data[10] >> 4);
data[10] *= 16;
data[10] |= v12;
data[7] ^= 0x5A;
var v23 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 1) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v23 != 0)
{
data[15] |= 2;
}
else
{
data[15] &= 0xFD;
}
var v13 = data[0];
data[0] = data[1];
data[1] = v13;
var v14 = data[7];
data[7] = data[0];
data[0] = v14;
var v15 = data[15];
data[15] = data[4];
data[4] = v15;
data[2] ^= 0x9E;
var v16 = (byte)(data[11] >> 1);
data[11] <<= 7;
data[11] |= v16;
var v22 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v22 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
}
}
else
{
var v28 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v28 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
data[0] ^= 0x14;
var v27 = (byte)((data[4] >> 4) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
if (v27 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v7 = data[2];
data[2] = data[1];
data[1] = v7;
var v26 = (byte)((data[4] >> 4) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
if (v26 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v8 = data[4];
data[4] = data[4];
data[4] = v8;
var v9 = (byte)(data[5] >> 1);
data[5] <<= 7;
data[5] |= v9;
data[3] ^= 0xFC;
var v10 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v10;
var v11 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v11;
var v25 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 3) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v25 != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
var v24 = (byte)((data[3] >> 4) & 1);
if (((data[3] >> 3) & 1) != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
if (v24 != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
data[6] ^= 0x79;
}
}
else
{
var v3 = data[1];
data[1] = data[0];
data[0] = v3;
var v4 = data[2];
data[2] = data[3];
data[3] = v4;
var v5 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v5;
var v2 = (byte)((data[2] >> 3) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
if (v2 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
var v32 = (byte)((data[1] >> 5) & 1);
if (((data[1] >> 7) & 1) != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
if (v32 != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
var v31 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v31 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v6 = data[2];
data[2] = data[0];
data[0] = v6;
var v30 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v30 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
var v29 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 5) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v29 != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v21 = (byte)((data[16] >> 3) & 1);
if (((data[16] >> 6) & 1) != 0)
{
data[16] |= 8;
}
else
{
data[16] &= 0xF7;
}
if (v21 != 0)
{
data[16] |= 0x40;
}
else
{
data[16] &= 0xBF;
}
var v20 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v20 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
data[15] ^= 0x61;
var v17 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v17;
data[29] ^= 0x96;
var v18 = (byte)(data[6] >> 4);
data[6] *= 16;
data[6] |= v18;
data[5] ^= 0x91;
var v19 = data[5];
data[5] = data[3];
data[3] = v19;
data[13] ^= 0x26;
}
else
{
var v23 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v23 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v12 = (byte)(data[11] >> 7);
data[11] *= 2;
data[11] |= v12;
data[2] ^= 0x9E;
var v13 = data[15];
data[15] = data[4];
data[4] = v13;
var v14 = data[7];
data[7] = data[0];
data[0] = v14;
var v15 = data[0];
data[0] = data[1];
data[1] = v15;
var v22 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 1) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v22 != 0)
{
data[15] |= 2;
}
else
{
data[15] &= 0xFD;
}
data[7] ^= 0x5A;
var v16 = (byte)(data[10] >> 4);
data[10] *= 16;
data[10] |= v16;
}
}
else
{
data[6] ^= 0x79;
var v28 = (byte)((data[3] >> 4) & 1);
if (((data[3] >> 3) & 1) != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
if (v28 != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
var v27 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 3) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v27 != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
var v7 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v7;
var v8 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v8;
data[3] ^= 0xFC;
var v9 = (byte)(data[5] >> 7);
data[5] *= 2;
data[5] |= v9;
var v10 = data[4];
data[4] = data[4];
data[4] = v10;
var v26 = (byte)((data[4] >> 4) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
if (v26 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v11 = data[2];
data[2] = data[1];
data[1] = v11;
var v25 = (byte)((data[4] >> 4) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x10;
}
else
{
data[4] &= 0xEF;
}
if (v25 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
data[0] ^= 0x14;
var v24 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v24 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
}
}
else
{
var v2 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 5) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v2 != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
var v32 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v32 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
var v3 = data[2];
data[2] = data[0];
data[0] = v3;
var v31 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 6) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v31 != 0)
{
data[3] |= 0x40;
}
else
{
data[3] &= 0xBF;
}
var v30 = (byte)((data[1] >> 5) & 1);
if (((data[1] >> 7) & 1) != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
if (v30 != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
var v29 = (byte)((data[2] >> 3) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
if (v29 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
var v4 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v4;
var v5 = data[2];
data[2] = data[3];
data[3] = v5;
var v6 = data[1];
data[1] = data[0];
data[0] = v6;
}
}
}
}

View File

@@ -0,0 +1,402 @@
// <copyright file="PacketTwisterOfChatInvitationRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'ChatInvitationRequest' type.
/// </summary>
internal class PacketTwisterOfChatInvitationRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v21 = (byte)((data[25] >> 1) & 1);
if (((data[25] >> 1) & 1) != 0)
{
data[25] |= 2;
}
else
{
data[25] &= 0xFD;
}
if (v21 != 0)
{
data[25] |= 2;
}
else
{
data[25] &= 0xFD;
}
data[7] ^= 0x49;
var v14 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v14;
var v15 = (byte)(data[4] >> 2);
data[4] <<= 6;
data[4] |= v15;
var v16 = (byte)(data[7] >> 6);
data[7] *= 4;
data[7] |= v16;
var v17 = (byte)(data[16] >> 6);
data[16] *= 4;
data[16] |= v17;
var v20 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v20 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v19 = (byte)((data[12] >> 7) & 1);
if (((data[12] >> 3) & 1) != 0)
{
data[12] |= 0x80;
}
else
{
data[12] &= 0x7F;
}
if (v19 != 0)
{
data[12] |= 8;
}
else
{
data[12] &= 0xF7;
}
data[25] ^= 0xB;
var v18 = data[31];
data[31] = data[22];
data[22] = v18;
}
else
{
data[7] ^= 0x79;
data[12] ^= 0x2E;
var v10 = data[3];
data[3] = data[6];
data[6] = v10;
var v11 = data[14];
data[14] = data[13];
data[13] = v11;
var v12 = (byte)(data[14] >> 4);
data[14] *= 16;
data[14] |= v12;
var v22 = (byte)((data[9] >> 6) & 1);
if (((data[9] >> 5) & 1) != 0)
{
data[9] |= 0x40;
}
else
{
data[9] &= 0xBF;
}
if (v22 != 0)
{
data[9] |= 0x20;
}
else
{
data[9] &= 0xDF;
}
var v13 = (byte)(data[8] >> 3);
data[8] *= 32;
data[8] |= v13;
data[11] ^= 0x52;
}
}
else
{
var v23 = (byte)((data[4] >> 3) & 1);
if (((data[4] >> 2) & 1) != 0)
{
data[4] |= 8;
}
else
{
data[4] &= 0xF7;
}
if (v23 != 0)
{
data[4] |= 4;
}
else
{
data[4] &= 0xFB;
}
var v8 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v8;
data[1] ^= 0xC9;
data[7] ^= 0x22;
data[3] ^= 0xE8;
var v9 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v9;
}
}
else
{
var v2 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v2 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
data[3] ^= 0x41;
var v3 = data[0];
data[0] = data[1];
data[1] = v3;
var v4 = data[0];
data[0] = data[1];
data[1] = v4;
var v5 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v5;
var v6 = (byte)(data[0] >> 4);
data[0] *= 16;
data[0] |= v6;
var v7 = data[3];
data[3] = data[0];
data[0] = v7;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v14 = data[31];
data[31] = data[22];
data[22] = v14;
data[25] ^= 0xB;
var v21 = (byte)((data[12] >> 7) & 1);
if (((data[12] >> 3) & 1) != 0)
{
data[12] |= 0x80;
}
else
{
data[12] &= 0x7F;
}
if (v21 != 0)
{
data[12] |= 8;
}
else
{
data[12] &= 0xF7;
}
var v20 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v20 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v15 = (byte)(data[16] >> 2);
data[16] <<= 6;
data[16] |= v15;
var v16 = (byte)(data[7] >> 2);
data[7] <<= 6;
data[7] |= v16;
var v17 = (byte)(data[4] >> 6);
data[4] *= 4;
data[4] |= v17;
var v18 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v18;
data[7] ^= 0x49;
var v19 = (byte)((data[25] >> 1) & 1);
if (((data[25] >> 1) & 1) != 0)
{
data[25] |= 2;
}
else
{
data[25] &= 0xFD;
}
if (v19 != 0)
{
data[25] |= 2;
}
else
{
data[25] &= 0xFD;
}
}
else
{
data[11] ^= 0x52;
var v10 = (byte)(data[8] >> 5);
data[8] *= 8;
data[8] |= v10;
var v22 = (byte)((data[9] >> 6) & 1);
if (((data[9] >> 5) & 1) != 0)
{
data[9] |= 0x40;
}
else
{
data[9] &= 0xBF;
}
if (v22 != 0)
{
data[9] |= 0x20;
}
else
{
data[9] &= 0xDF;
}
var v11 = (byte)(data[14] >> 4);
data[14] *= 16;
data[14] |= v11;
var v12 = data[14];
data[14] = data[13];
data[13] = v12;
var v13 = data[3];
data[3] = data[6];
data[6] = v13;
data[12] ^= 0x2E;
data[7] ^= 0x79;
}
}
else
{
var v8 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v8;
data[3] ^= 0xE8;
data[7] ^= 0x22;
data[1] ^= 0xC9;
var v9 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v9;
var v23 = (byte)((data[4] >> 3) & 1);
if (((data[4] >> 2) & 1) != 0)
{
data[4] |= 8;
}
else
{
data[4] &= 0xF7;
}
if (v23 != 0)
{
data[4] |= 4;
}
else
{
data[4] &= 0xFB;
}
}
}
else
{
var v3 = data[3];
data[3] = data[0];
data[0] = v3;
var v4 = (byte)(data[0] >> 4);
data[0] *= 16;
data[0] |= v4;
var v5 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v5;
var v6 = data[0];
data[0] = data[1];
data[1] = v6;
var v7 = data[0];
data[0] = data[1];
data[1] = v7;
data[3] ^= 0x41;
var v2 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v2 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
}
}
}
}

View File

@@ -0,0 +1,510 @@
// <copyright file="PacketTwisterOfChatRoomCreateRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'ChatRoomCreateRequest' type.
/// </summary>
internal class PacketTwisterOfChatRoomCreateRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v18 = (byte)(data[2] >> 5);
data[2] *= 8;
data[2] |= v18;
data[18] ^= 0xE;
var v24 = (byte)((data[20] >> 2) & 1);
if (((data[20] >> 7) & 1) != 0)
{
data[20] |= 4;
}
else
{
data[20] &= 0xFB;
}
if (v24 != 0)
{
data[20] |= 0x80;
}
else
{
data[20] &= 0x7F;
}
var v23 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 2) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v23 != 0)
{
data[4] |= 4;
}
else
{
data[4] &= 0xFB;
}
data[30] ^= 0x61;
var v19 = (byte)(data[24] >> 7);
data[24] *= 2;
data[24] |= v19;
data[8] ^= 0x68;
var v20 = (byte)(data[17] >> 4);
data[17] *= 16;
data[17] |= v20;
var v21 = data[11];
data[11] = data[24];
data[24] = v21;
var v22 = data[30];
data[30] = data[24];
data[24] = v22;
}
else
{
var v14 = (byte)(data[6] >> 6);
data[6] *= 4;
data[6] |= v14;
data[3] ^= 0xCE;
data[12] ^= 0xFA;
data[6] ^= 0x52;
data[5] ^= 0xF3;
var v15 = (byte)(data[6] >> 5);
data[6] *= 8;
data[6] |= v15;
var v26 = (byte)((data[0] >> 6) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
if (v26 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[10] ^= 0xF0;
var v25 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 3) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v25 != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
var v16 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v16;
var v17 = data[12];
data[12] = data[13];
data[13] = v17;
}
}
else
{
var v8 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v8;
var v27 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 7) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v27 != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
data[6] ^= 0x73;
var v9 = data[4];
data[4] = data[4];
data[4] = v9;
var v10 = data[5];
data[5] = data[0];
data[0] = v10;
var v11 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v11;
data[1] ^= 0x9D;
var v12 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v12;
var v13 = (byte)(data[7] >> 1);
data[7] <<= 7;
data[7] |= v13;
data[3] ^= 0x48;
data[1] ^= 0x60;
}
}
else
{
var v3 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v3;
var v4 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v4;
var v5 = data[0];
data[0] = data[1];
data[1] = v5;
var v6 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v6;
var v2 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 4) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v2 != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
var v7 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v7;
var v29 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 7) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v29 != 0)
{
data[0] |= 0x80;
}
else
{
data[0] &= 0x7F;
}
var v28 = (byte)((data[1] >> 6) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
if (v28 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v18 = data[30];
data[30] = data[24];
data[24] = v18;
var v19 = data[11];
data[11] = data[24];
data[24] = v19;
var v20 = (byte)(data[17] >> 4);
data[17] *= 16;
data[17] |= v20;
data[8] ^= 0x68;
var v21 = (byte)(data[24] >> 1);
data[24] <<= 7;
data[24] |= v21;
data[30] ^= 0x61;
var v24 = (byte)((data[4] >> 7) & 1);
if (((data[4] >> 2) & 1) != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
if (v24 != 0)
{
data[4] |= 4;
}
else
{
data[4] &= 0xFB;
}
var v23 = (byte)((data[20] >> 2) & 1);
if (((data[20] >> 7) & 1) != 0)
{
data[20] |= 4;
}
else
{
data[20] &= 0xFB;
}
if (v23 != 0)
{
data[20] |= 0x80;
}
else
{
data[20] &= 0x7F;
}
data[18] ^= 0xE;
var v22 = (byte)(data[2] >> 3);
data[2] *= 32;
data[2] |= v22;
}
else
{
var v14 = data[12];
data[12] = data[13];
data[13] = v14;
var v15 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v15;
var v26 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 3) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v26 != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
data[10] ^= 0xF0;
var v25 = (byte)((data[0] >> 6) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
if (v25 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v16 = (byte)(data[6] >> 3);
data[6] *= 32;
data[6] |= v16;
data[5] ^= 0xF3;
data[6] ^= 0x52;
data[12] ^= 0xFA;
data[3] ^= 0xCE;
var v17 = (byte)(data[6] >> 2);
data[6] <<= 6;
data[6] |= v17;
}
}
else
{
data[1] ^= 0x60;
data[3] ^= 0x48;
var v8 = (byte)(data[7] >> 7);
data[7] *= 2;
data[7] |= v8;
var v9 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v9;
data[1] ^= 0x9D;
var v10 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v10;
var v11 = data[5];
data[5] = data[0];
data[0] = v11;
var v12 = data[4];
data[4] = data[4];
data[4] = v12;
data[6] ^= 0x73;
var v27 = (byte)((data[7] >> 1) & 1);
if (((data[7] >> 7) & 1) != 0)
{
data[7] |= 2;
}
else
{
data[7] &= 0xFD;
}
if (v27 != 0)
{
data[7] |= 0x80;
}
else
{
data[7] &= 0x7F;
}
var v13 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v13;
}
}
else
{
var v2 = (byte)((data[1] >> 6) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
if (v2 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v29 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 7) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v29 != 0)
{
data[0] |= 0x80;
}
else
{
data[0] &= 0x7F;
}
var v3 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v3;
var v28 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 4) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v28 != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
var v4 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v4;
var v5 = data[0];
data[0] = data[1];
data[1] = v5;
var v6 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v6;
var v7 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v7;
}
}
}
}

View File

@@ -0,0 +1,360 @@
// <copyright file="PacketTwisterOfClientChecksum.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'ClientChecksum' type.
/// </summary>
internal class PacketTwisterOfClientChecksum : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v15 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v15;
var v19 = (byte)((data[23] >> 1) & 1);
if (((data[23] >> 4) & 1) != 0)
{
data[23] |= 2;
}
else
{
data[23] &= 0xFD;
}
if (v19 != 0)
{
data[23] |= 0x10;
}
else
{
data[23] &= 0xEF;
}
var v16 = (byte)(data[29] >> 6);
data[29] *= 4;
data[29] |= v16;
var v17 = data[24];
data[24] = data[2];
data[2] = v17;
var v18 = (byte)(data[28] >> 1);
data[28] <<= 7;
data[28] |= v18;
}
else
{
data[1] ^= 0x53;
var v10 = (byte)(data[11] >> 2);
data[11] <<= 6;
data[11] |= v10;
data[8] ^= 2;
data[7] ^= 0x21;
var v11 = data[15];
data[15] = data[0];
data[0] = v11;
var v12 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v12;
var v13 = (byte)(data[12] >> 7);
data[12] *= 2;
data[12] |= v13;
var v14 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v14;
}
}
else
{
var v7 = data[1];
data[1] = data[2];
data[2] = v7;
var v8 = data[6];
data[6] = data[3];
data[3] = v8;
var v9 = data[4];
data[4] = data[6];
data[6] = v9;
}
}
else
{
var v3 = data[0];
data[0] = data[3];
data[3] = v3;
data[0] ^= 0xD7;
var v2 = (byte)((data[1] >> 5) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
if (v2 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v22 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v22 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v4 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v4;
var v21 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v21 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
data[1] ^= 0x2D;
var v5 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v5;
data[1] ^= 0x3F;
var v6 = data[3];
data[3] = data[0];
data[0] = v6;
var v20 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v20 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v15 = (byte)(data[28] >> 7);
data[28] *= 2;
data[28] |= v15;
var v16 = data[24];
data[24] = data[2];
data[2] = v16;
var v17 = (byte)(data[29] >> 2);
data[29] <<= 6;
data[29] |= v17;
var v19 = (byte)((data[23] >> 1) & 1);
if (((data[23] >> 4) & 1) != 0)
{
data[23] |= 2;
}
else
{
data[23] &= 0xFD;
}
if (v19 != 0)
{
data[23] |= 0x10;
}
else
{
data[23] &= 0xEF;
}
var v18 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v18;
}
else
{
var v10 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v10;
var v11 = (byte)(data[12] >> 1);
data[12] <<= 7;
data[12] |= v11;
var v12 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v12;
var v13 = data[15];
data[15] = data[0];
data[0] = v13;
data[7] ^= 0x21;
data[8] ^= 2;
var v14 = (byte)(data[11] >> 6);
data[11] *= 4;
data[11] |= v14;
data[1] ^= 0x53;
}
}
else
{
var v7 = data[4];
data[4] = data[6];
data[6] = v7;
var v8 = data[6];
data[6] = data[3];
data[3] = v8;
var v9 = data[1];
data[1] = data[2];
data[2] = v9;
}
}
else
{
var v2 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v2 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v3 = data[3];
data[3] = data[0];
data[0] = v3;
data[1] ^= 0x3F;
var v4 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v4;
data[1] ^= 0x2D;
var v22 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v22 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v5 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v5;
var v21 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v21 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v20 = (byte)((data[1] >> 5) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
if (v20 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
data[0] ^= 0xD7;
var v6 = data[0];
data[0] = data[3];
data[3] = v6;
}
}
}
}

View File

@@ -0,0 +1,671 @@
// <copyright file="PacketTwisterOfCrywolf.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'Crywolf' type.
/// </summary>
internal class PacketTwisterOfCrywolf : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[24] ^= 0x16;
data[27] ^= 0x19;
var v16 = (byte)(data[11] >> 4);
data[11] *= 16;
data[11] |= v16;
data[24] ^= 0x4F;
var v17 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v17;
var v21 = (byte)((data[25] >> 4) & 1);
if (((data[25] >> 5) & 1) != 0)
{
data[25] |= 0x10;
}
else
{
data[25] &= 0xEF;
}
if (v21 != 0)
{
data[25] |= 0x20;
}
else
{
data[25] &= 0xDF;
}
var v20 = (byte)((data[30] >> 1) & 1);
if (((data[30] >> 4) & 1) != 0)
{
data[30] |= 2;
}
else
{
data[30] &= 0xFD;
}
if (v20 != 0)
{
data[30] |= 0x10;
}
else
{
data[30] &= 0xEF;
}
data[3] ^= 0x5C;
var v19 = (byte)((data[22] >> 2) & 1);
if (((data[22] >> 5) & 1) != 0)
{
data[22] |= 4;
}
else
{
data[22] &= 0xFB;
}
if (v19 != 0)
{
data[22] |= 0x20;
}
else
{
data[22] &= 0xDF;
}
var v18 = (byte)((data[23] >> 7) & 1);
if (((data[23] >> 6) & 1) != 0)
{
data[23] |= 0x80;
}
else
{
data[23] &= 0x7F;
}
if (v18 != 0)
{
data[23] |= 0x40;
}
else
{
data[23] &= 0xBF;
}
data[13] ^= 0x8C;
}
else
{
var v9 = data[7];
data[7] = data[13];
data[13] = v9;
var v10 = (byte)(data[14] >> 6);
data[14] *= 4;
data[14] |= v10;
var v11 = data[4];
data[4] = data[9];
data[9] = v11;
data[0] ^= 0x9B;
data[11] ^= 0xCA;
data[6] ^= 0x8F;
var v12 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v12;
var v13 = data[11];
data[11] = data[6];
data[6] = v13;
var v14 = (byte)(data[13] >> 4);
data[13] *= 16;
data[13] |= v14;
var v15 = (byte)(data[11] >> 5);
data[11] *= 8;
data[11] |= v15;
}
}
else
{
var v6 = (byte)(data[7] >> 4);
data[7] *= 16;
data[7] |= v6;
data[1] ^= 0x9D;
var v26 = (byte)((data[0] >> 6) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
if (v26 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v25 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v25 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v24 = (byte)((data[1] >> 6) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
if (v24 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v23 = (byte)((data[5] >> 4) & 1);
if (((data[5] >> 4) & 1) != 0)
{
data[5] |= 0x10;
}
else
{
data[5] &= 0xEF;
}
if (v23 != 0)
{
data[5] |= 0x10;
}
else
{
data[5] &= 0xEF;
}
var v7 = (byte)(data[2] >> 4);
data[2] *= 16;
data[2] |= v7;
data[7] ^= 0xD;
var v8 = (byte)(data[2] >> 5);
data[2] *= 8;
data[2] |= v8;
var v22 = (byte)((data[5] >> 3) & 1);
if (((data[5] >> 1) & 1) != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
if (v22 != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
}
}
else
{
var v3 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v3;
data[0] ^= 0xC5;
data[3] ^= 0xFA;
var v2 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v2 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
var v4 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v4;
var v29 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v29 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
data[3] ^= 0xF7;
var v5 = (byte)(data[1] >> 3);
data[1] *= 32;
data[1] |= v5;
var v28 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v28 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
var v27 = (byte)((data[3] >> 3) & 1);
if (((data[3] >> 3) & 1) != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
if (v27 != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[13] ^= 0x8C;
var v21 = (byte)((data[23] >> 7) & 1);
if (((data[23] >> 6) & 1) != 0)
{
data[23] |= 0x80;
}
else
{
data[23] &= 0x7F;
}
if (v21 != 0)
{
data[23] |= 0x40;
}
else
{
data[23] &= 0xBF;
}
var v20 = (byte)((data[22] >> 2) & 1);
if (((data[22] >> 5) & 1) != 0)
{
data[22] |= 4;
}
else
{
data[22] &= 0xFB;
}
if (v20 != 0)
{
data[22] |= 0x20;
}
else
{
data[22] &= 0xDF;
}
data[3] ^= 0x5C;
var v19 = (byte)((data[30] >> 1) & 1);
if (((data[30] >> 4) & 1) != 0)
{
data[30] |= 2;
}
else
{
data[30] &= 0xFD;
}
if (v19 != 0)
{
data[30] |= 0x10;
}
else
{
data[30] &= 0xEF;
}
var v18 = (byte)((data[25] >> 4) & 1);
if (((data[25] >> 5) & 1) != 0)
{
data[25] |= 0x10;
}
else
{
data[25] &= 0xEF;
}
if (v18 != 0)
{
data[25] |= 0x20;
}
else
{
data[25] &= 0xDF;
}
var v16 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v16;
data[24] ^= 0x4F;
var v17 = (byte)(data[11] >> 4);
data[11] *= 16;
data[11] |= v17;
data[27] ^= 0x19;
data[24] ^= 0x16;
}
else
{
var v9 = (byte)(data[11] >> 3);
data[11] *= 32;
data[11] |= v9;
var v10 = (byte)(data[13] >> 4);
data[13] *= 16;
data[13] |= v10;
var v11 = data[11];
data[11] = data[6];
data[6] = v11;
var v12 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v12;
data[6] ^= 0x8F;
data[11] ^= 0xCA;
data[0] ^= 0x9B;
var v13 = data[4];
data[4] = data[9];
data[9] = v13;
var v14 = (byte)(data[14] >> 2);
data[14] <<= 6;
data[14] |= v14;
var v15 = data[7];
data[7] = data[13];
data[13] = v15;
}
}
else
{
var v26 = (byte)((data[5] >> 3) & 1);
if (((data[5] >> 1) & 1) != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
if (v26 != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
var v6 = (byte)(data[2] >> 3);
data[2] *= 32;
data[2] |= v6;
data[7] ^= 0xD;
var v7 = (byte)(data[2] >> 4);
data[2] *= 16;
data[2] |= v7;
var v25 = (byte)((data[5] >> 4) & 1);
if (((data[5] >> 4) & 1) != 0)
{
data[5] |= 0x10;
}
else
{
data[5] &= 0xEF;
}
if (v25 != 0)
{
data[5] |= 0x10;
}
else
{
data[5] &= 0xEF;
}
var v24 = (byte)((data[1] >> 6) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
if (v24 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v23 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v23 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v22 = (byte)((data[0] >> 6) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x40;
}
else
{
data[0] &= 0xBF;
}
if (v22 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[1] ^= 0x9D;
var v8 = (byte)(data[7] >> 4);
data[7] *= 16;
data[7] |= v8;
}
}
else
{
var v2 = (byte)((data[3] >> 3) & 1);
if (((data[3] >> 3) & 1) != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
if (v2 != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
var v29 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 3) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v29 != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
var v3 = (byte)(data[1] >> 5);
data[1] *= 8;
data[1] |= v3;
data[3] ^= 0xF7;
var v28 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v28 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
var v4 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v4;
var v27 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v27 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
data[3] ^= 0xFA;
data[0] ^= 0xC5;
var v5 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v5;
}
}
}
}

View File

@@ -0,0 +1,441 @@
// <copyright file="PacketTwisterOfDevilSquareEnter.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'DevilSquareEnter' type.
/// </summary>
internal class PacketTwisterOfDevilSquareEnter : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v21 = (byte)((data[21] >> 5) & 1);
if (((data[21] >> 1) & 1) != 0)
{
data[21] |= 0x20;
}
else
{
data[21] &= 0xDF;
}
if (v21 != 0)
{
data[21] |= 2;
}
else
{
data[21] &= 0xFD;
}
var v17 = (byte)(data[12] >> 5);
data[12] *= 8;
data[12] |= v17;
data[0] ^= 0x8A;
var v18 = (byte)(data[17] >> 3);
data[17] *= 32;
data[17] |= v18;
var v19 = data[7];
data[7] = data[14];
data[14] = v19;
var v20 = (byte)((data[10] >> 4) & 1);
if (((data[10] >> 4) & 1) != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
if (v20 != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
}
else
{
var v14 = data[0];
data[0] = data[3];
data[3] = v14;
data[0] ^= 0xC7;
var v15 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v15;
var v16 = data[5];
data[5] = data[10];
data[10] = v16;
data[13] ^= 0x34;
}
}
else
{
var v23 = (byte)((data[7] >> 6) & 1);
if (((data[7] >> 4) & 1) != 0)
{
data[7] |= 0x40;
}
else
{
data[7] &= 0xBF;
}
if (v23 != 0)
{
data[7] |= 0x10;
}
else
{
data[7] &= 0xEF;
}
var v22 = (byte)((data[6] >> 4) & 1);
if (((data[6] >> 6) & 1) != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
if (v22 != 0)
{
data[6] |= 0x40;
}
else
{
data[6] &= 0xBF;
}
var v10 = data[2];
data[2] = data[7];
data[7] = v10;
data[1] ^= 0x6A;
var v11 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v11;
var v12 = data[5];
data[5] = data[7];
data[7] = v12;
var v13 = (byte)(data[6] >> 1);
data[6] <<= 7;
data[6] |= v13;
}
}
else
{
var v2 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v2 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v3 = data[3];
data[3] = data[0];
data[0] = v3;
var v4 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v4;
data[2] ^= 0x40;
var v5 = data[1];
data[1] = data[1];
data[1] = v5;
var v25 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v25 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v6 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v6;
data[3] ^= 0x90;
var v7 = data[3];
data[3] = data[0];
data[0] = v7;
var v8 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v8;
var v24 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v24 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
data[0] ^= 0xE4;
var v9 = data[3];
data[3] = data[2];
data[2] = v9;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v21 = (byte)((data[10] >> 4) & 1);
if (((data[10] >> 4) & 1) != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
if (v21 != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
var v17 = data[7];
data[7] = data[14];
data[14] = v17;
var v18 = (byte)(data[17] >> 5);
data[17] *= 8;
data[17] |= v18;
data[0] ^= 0x8A;
var v19 = (byte)(data[12] >> 3);
data[12] *= 32;
data[12] |= v19;
var v20 = (byte)((data[21] >> 5) & 1);
if (((data[21] >> 1) & 1) != 0)
{
data[21] |= 0x20;
}
else
{
data[21] &= 0xDF;
}
if (v20 != 0)
{
data[21] |= 2;
}
else
{
data[21] &= 0xFD;
}
}
else
{
data[13] ^= 0x34;
var v14 = data[5];
data[5] = data[10];
data[10] = v14;
var v15 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v15;
data[0] ^= 0xC7;
var v16 = data[0];
data[0] = data[3];
data[3] = v16;
}
}
else
{
var v10 = (byte)(data[6] >> 7);
data[6] *= 2;
data[6] |= v10;
var v11 = data[5];
data[5] = data[7];
data[7] = v11;
var v12 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v12;
data[1] ^= 0x6A;
var v13 = data[2];
data[2] = data[7];
data[7] = v13;
var v23 = (byte)((data[6] >> 4) & 1);
if (((data[6] >> 6) & 1) != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
if (v23 != 0)
{
data[6] |= 0x40;
}
else
{
data[6] &= 0xBF;
}
var v22 = (byte)((data[7] >> 6) & 1);
if (((data[7] >> 4) & 1) != 0)
{
data[7] |= 0x40;
}
else
{
data[7] &= 0xBF;
}
if (v22 != 0)
{
data[7] |= 0x10;
}
else
{
data[7] &= 0xEF;
}
}
}
else
{
var v3 = data[3];
data[3] = data[2];
data[2] = v3;
data[0] ^= 0xE4;
var v2 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v2 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v4 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v4;
var v5 = data[3];
data[3] = data[0];
data[0] = v5;
data[3] ^= 0x90;
var v6 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v6;
var v25 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v25 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v7 = data[1];
data[1] = data[1];
data[1] = v7;
data[2] ^= 0x40;
var v8 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v8;
var v9 = data[3];
data[3] = data[0];
data[0] = v9;
var v24 = (byte)((data[1] >> 7) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 0x80;
}
else
{
data[1] &= 0x7F;
}
if (v24 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
}
}
}
}

View File

@@ -0,0 +1,785 @@
// <copyright file="PacketTwisterOfEventChipRegistration.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'EventChipRegistration' type.
/// </summary>
internal class PacketTwisterOfEventChipRegistration : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v23 = (byte)((data[15] >> 7) & 1);
if (((data[15] >> 1) & 1) != 0)
{
data[15] |= 0x80;
}
else
{
data[15] &= 0x7F;
}
if (v23 != 0)
{
data[15] |= 2;
}
else
{
data[15] &= 0xFD;
}
var v22 = (byte)((data[20] >> 7) & 1);
if (((data[20] >> 7) & 1) != 0)
{
data[20] |= 0x80;
}
else
{
data[20] &= 0x7F;
}
if (v22 != 0)
{
data[20] |= 0x80;
}
else
{
data[20] &= 0x7F;
}
data[3] ^= 0x7B;
var v14 = data[19];
data[19] = data[19];
data[19] = v14;
var v15 = (byte)(data[28] >> 5);
data[28] *= 8;
data[28] |= v15;
data[14] ^= 0x92;
var v21 = (byte)((data[25] >> 5) & 1);
if (((data[25] >> 2) & 1) != 0)
{
data[25] |= 0x20;
}
else
{
data[25] &= 0xDF;
}
if (v21 != 0)
{
data[25] |= 4;
}
else
{
data[25] &= 0xFB;
}
var v16 = (byte)(data[7] >> 6);
data[7] *= 4;
data[7] |= v16;
data[31] ^= 0xA3;
var v20 = (byte)((data[26] >> 6) & 1);
if (((data[26] >> 1) & 1) != 0)
{
data[26] |= 0x40;
}
else
{
data[26] &= 0xBF;
}
if (v20 != 0)
{
data[26] |= 2;
}
else
{
data[26] &= 0xFD;
}
var v17 = data[31];
data[31] = data[18];
data[18] = v17;
var v18 = data[4];
data[4] = data[17];
data[17] = v18;
var v19 = (byte)((data[26] >> 5) & 1);
if (((data[26] >> 5) & 1) != 0)
{
data[26] |= 0x20;
}
else
{
data[26] &= 0xDF;
}
if (v19 != 0)
{
data[26] |= 0x20;
}
else
{
data[26] &= 0xDF;
}
}
else
{
var v9 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v9;
var v29 = (byte)((data[4] >> 3) & 1);
if (((data[4] >> 7) & 1) != 0)
{
data[4] |= 8;
}
else
{
data[4] &= 0xF7;
}
if (v29 != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
var v10 = data[3];
data[3] = data[12];
data[12] = v10;
var v28 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v28 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v27 = (byte)((data[9] >> 1) & 1);
if (((data[9] >> 1) & 1) != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
if (v27 != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
var v11 = data[6];
data[6] = data[13];
data[13] = v11;
var v26 = (byte)((data[6] >> 4) & 1);
if (((data[6] >> 1) & 1) != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
if (v26 != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
data[6] ^= 0x6A;
var v12 = (byte)(data[8] >> 7);
data[8] *= 2;
data[8] |= v12;
var v25 = (byte)((data[5] >> 1) & 1);
if (((data[5] >> 7) & 1) != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
if (v25 != 0)
{
data[5] |= 0x80;
}
else
{
data[5] &= 0x7F;
}
var v24 = (byte)((data[8] >> 2) & 1);
if (((data[8] >> 4) & 1) != 0)
{
data[8] |= 4;
}
else
{
data[8] &= 0xFB;
}
if (v24 != 0)
{
data[8] |= 0x10;
}
else
{
data[8] &= 0xEF;
}
var v13 = data[15];
data[15] = data[1];
data[1] = v13;
data[12] ^= 0x51;
}
}
else
{
data[3] ^= 0x6B;
var v30 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v30 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
var v7 = data[5];
data[5] = data[3];
data[3] = v7;
data[2] ^= 0xD6;
data[4] ^= 0x97;
var v8 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v8;
}
}
else
{
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 3) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
data[2] ^= 0x24;
var v3 = data[0];
data[0] = data[3];
data[3] = v3;
var v4 = data[1];
data[1] = data[3];
data[3] = v4;
var v5 = data[1];
data[1] = data[0];
data[0] = v5;
var v33 = (byte)((data[3] >> 3) & 1);
if (((data[3] >> 2) & 1) != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
if (v33 != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
var v32 = (byte)((data[0] >> 4) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
if (v32 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v6 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v6;
data[1] ^= 0x94;
data[1] ^= 0x45;
var v31 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 7) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v31 != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v23 = (byte)((data[26] >> 5) & 1);
if (((data[26] >> 5) & 1) != 0)
{
data[26] |= 0x20;
}
else
{
data[26] &= 0xDF;
}
if (v23 != 0)
{
data[26] |= 0x20;
}
else
{
data[26] &= 0xDF;
}
var v14 = data[4];
data[4] = data[17];
data[17] = v14;
var v15 = data[31];
data[31] = data[18];
data[18] = v15;
var v22 = (byte)((data[26] >> 6) & 1);
if (((data[26] >> 1) & 1) != 0)
{
data[26] |= 0x40;
}
else
{
data[26] &= 0xBF;
}
if (v22 != 0)
{
data[26] |= 2;
}
else
{
data[26] &= 0xFD;
}
data[31] ^= 0xA3;
var v16 = (byte)(data[7] >> 2);
data[7] <<= 6;
data[7] |= v16;
var v21 = (byte)((data[25] >> 5) & 1);
if (((data[25] >> 2) & 1) != 0)
{
data[25] |= 0x20;
}
else
{
data[25] &= 0xDF;
}
if (v21 != 0)
{
data[25] |= 4;
}
else
{
data[25] &= 0xFB;
}
data[14] ^= 0x92;
var v17 = (byte)(data[28] >> 3);
data[28] *= 32;
data[28] |= v17;
var v18 = data[19];
data[19] = data[19];
data[19] = v18;
data[3] ^= 0x7B;
var v20 = (byte)((data[20] >> 7) & 1);
if (((data[20] >> 7) & 1) != 0)
{
data[20] |= 0x80;
}
else
{
data[20] &= 0x7F;
}
if (v20 != 0)
{
data[20] |= 0x80;
}
else
{
data[20] &= 0x7F;
}
var v19 = (byte)((data[15] >> 7) & 1);
if (((data[15] >> 1) & 1) != 0)
{
data[15] |= 0x80;
}
else
{
data[15] &= 0x7F;
}
if (v19 != 0)
{
data[15] |= 2;
}
else
{
data[15] &= 0xFD;
}
}
else
{
data[12] ^= 0x51;
var v9 = data[15];
data[15] = data[1];
data[1] = v9;
var v29 = (byte)((data[8] >> 2) & 1);
if (((data[8] >> 4) & 1) != 0)
{
data[8] |= 4;
}
else
{
data[8] &= 0xFB;
}
if (v29 != 0)
{
data[8] |= 0x10;
}
else
{
data[8] &= 0xEF;
}
var v28 = (byte)((data[5] >> 1) & 1);
if (((data[5] >> 7) & 1) != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
if (v28 != 0)
{
data[5] |= 0x80;
}
else
{
data[5] &= 0x7F;
}
var v10 = (byte)(data[8] >> 1);
data[8] <<= 7;
data[8] |= v10;
data[6] ^= 0x6A;
var v27 = (byte)((data[6] >> 4) & 1);
if (((data[6] >> 1) & 1) != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
if (v27 != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
var v11 = data[6];
data[6] = data[13];
data[13] = v11;
var v26 = (byte)((data[9] >> 1) & 1);
if (((data[9] >> 1) & 1) != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
if (v26 != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
var v25 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 7) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v25 != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
var v12 = data[3];
data[3] = data[12];
data[12] = v12;
var v24 = (byte)((data[4] >> 3) & 1);
if (((data[4] >> 7) & 1) != 0)
{
data[4] |= 8;
}
else
{
data[4] &= 0xF7;
}
if (v24 != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
var v13 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v13;
}
}
else
{
var v7 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v7;
data[4] ^= 0x97;
data[2] ^= 0xD6;
var v8 = data[5];
data[5] = data[3];
data[3] = v8;
var v30 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 6) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v30 != 0)
{
data[1] |= 0x40;
}
else
{
data[1] &= 0xBF;
}
data[3] ^= 0x6B;
}
}
else
{
var v2 = (byte)((data[3] >> 5) & 1);
if (((data[3] >> 7) & 1) != 0)
{
data[3] |= 0x20;
}
else
{
data[3] &= 0xDF;
}
if (v2 != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
data[1] ^= 0x45;
data[1] ^= 0x94;
var v3 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v3;
var v33 = (byte)((data[0] >> 4) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
if (v33 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v32 = (byte)((data[3] >> 3) & 1);
if (((data[3] >> 2) & 1) != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
if (v32 != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
var v4 = data[1];
data[1] = data[0];
data[0] = v4;
var v5 = data[1];
data[1] = data[3];
data[3] = v5;
var v6 = data[0];
data[0] = data[3];
data[3] = v6;
data[2] ^= 0x24;
var v31 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 3) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v31 != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
}
}
}
}

View File

@@ -0,0 +1,511 @@
// <copyright file="PacketTwisterOfFriendAddRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'FriendAddRequest' type.
/// </summary>
internal class PacketTwisterOfFriendAddRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v15 = (byte)(data[23] >> 1);
data[23] <<= 7;
data[23] |= v15;
var v16 = data[1];
data[1] = data[17];
data[17] = v16;
var v17 = data[4];
data[4] = data[21];
data[21] = v17;
data[15] ^= 0x82;
var v21 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v21 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
var v20 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 1) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v20 != 0)
{
data[15] |= 2;
}
else
{
data[15] &= 0xFD;
}
var v18 = (byte)(data[26] >> 4);
data[26] *= 16;
data[26] |= v18;
var v19 = (byte)((data[17] >> 5) & 1);
if (((data[17] >> 4) & 1) != 0)
{
data[17] |= 0x20;
}
else
{
data[17] &= 0xDF;
}
if (v19 != 0)
{
data[17] |= 0x10;
}
else
{
data[17] &= 0xEF;
}
data[25] ^= 0x9F;
data[1] ^= 0x14;
}
else
{
var v13 = data[15];
data[15] = data[14];
data[14] = v13;
var v22 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v22 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v14 = data[12];
data[12] = data[8];
data[8] = v14;
}
}
else
{
var v9 = data[2];
data[2] = data[6];
data[6] = v9;
var v10 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v10;
var v11 = data[6];
data[6] = data[6];
data[6] = v11;
data[1] ^= 0x5C;
var v12 = data[2];
data[2] = data[1];
data[1] = v12;
var v23 = (byte)((data[6] >> 7) & 1);
if (((data[6] >> 5) & 1) != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
if (v23 != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
}
}
else
{
var v2 = (byte)((data[0] >> 5) & 1);
if (((data[0] >> 2) & 1) != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
if (v2 != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
var v3 = data[2];
data[2] = data[2];
data[2] = v3;
var v4 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v4;
var v26 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v26 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
var v5 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v5;
var v6 = data[1];
data[1] = data[0];
data[0] = v6;
var v7 = (byte)(data[2] >> 3);
data[2] *= 32;
data[2] |= v7;
var v25 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v25 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
data[1] ^= 0x9A;
data[1] ^= 0x51;
var v24 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 7) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v24 != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
var v8 = data[0];
data[0] = data[1];
data[1] = v8;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[1] ^= 0x14;
data[25] ^= 0x9F;
var v21 = (byte)((data[17] >> 5) & 1);
if (((data[17] >> 4) & 1) != 0)
{
data[17] |= 0x20;
}
else
{
data[17] &= 0xDF;
}
if (v21 != 0)
{
data[17] |= 0x10;
}
else
{
data[17] &= 0xEF;
}
var v15 = (byte)(data[26] >> 4);
data[26] *= 16;
data[26] |= v15;
var v20 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 1) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v20 != 0)
{
data[15] |= 2;
}
else
{
data[15] &= 0xFD;
}
var v19 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v19 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
data[15] ^= 0x82;
var v16 = data[4];
data[4] = data[21];
data[21] = v16;
var v17 = data[1];
data[1] = data[17];
data[17] = v17;
var v18 = (byte)(data[23] >> 7);
data[23] *= 2;
data[23] |= v18;
}
else
{
var v13 = data[12];
data[12] = data[8];
data[8] = v13;
var v22 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v22 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v14 = data[15];
data[15] = data[14];
data[14] = v14;
}
}
else
{
var v23 = (byte)((data[6] >> 7) & 1);
if (((data[6] >> 5) & 1) != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
if (v23 != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
var v9 = data[2];
data[2] = data[1];
data[1] = v9;
data[1] ^= 0x5C;
var v10 = data[6];
data[6] = data[6];
data[6] = v10;
var v11 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v11;
var v12 = data[2];
data[2] = data[6];
data[6] = v12;
}
}
else
{
var v3 = data[0];
data[0] = data[1];
data[1] = v3;
var v2 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 7) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v2 != 0)
{
data[3] |= 0x80;
}
else
{
data[3] &= 0x7F;
}
data[1] ^= 0x51;
data[1] ^= 0x9A;
var v26 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v26 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v4 = (byte)(data[2] >> 5);
data[2] *= 8;
data[2] |= v4;
var v5 = data[1];
data[1] = data[0];
data[0] = v5;
var v6 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v6;
var v25 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v25 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
var v7 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v7;
var v8 = data[2];
data[2] = data[2];
data[2] = v8;
var v24 = (byte)((data[0] >> 5) & 1);
if (((data[0] >> 2) & 1) != 0)
{
data[0] |= 0x20;
}
else
{
data[0] &= 0xDF;
}
if (v24 != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
}
}
}
}

View File

@@ -0,0 +1,343 @@
// <copyright file="PacketTwisterOfFriendAddResponse.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'FriendAddResponse' type.
/// </summary>
internal class PacketTwisterOfFriendAddResponse : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v15 = (byte)((data[11] >> 6) & 1);
if (((data[11] >> 3) & 1) != 0)
{
data[11] |= 0x40;
}
else
{
data[11] &= 0xBF;
}
if (v15 != 0)
{
data[11] |= 8;
}
else
{
data[11] &= 0xF7;
}
var v11 = (byte)(data[17] >> 2);
data[17] <<= 6;
data[17] |= v11;
data[2] ^= 0x73;
var v12 = (byte)(data[6] >> 6);
data[6] *= 4;
data[6] |= v12;
data[29] ^= 0xCE;
var v13 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v13;
var v14 = data[27];
data[27] = data[30];
data[30] = v14;
data[5] ^= 0xE9;
}
else
{
var v9 = data[3];
data[3] = data[2];
data[2] = v9;
var v17 = (byte)((data[13] >> 6) & 1);
if (((data[13] >> 6) & 1) != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
if (v17 != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
var v10 = data[15];
data[15] = data[8];
data[8] = v10;
var v16 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v16 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
}
}
else
{
var v8 = data[3];
data[3] = data[6];
data[6] = v8;
data[3] ^= 0xC1;
data[5] ^= 0x29;
data[7] ^= 0xA9;
}
}
else
{
data[1] ^= 0x48;
var v2 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v2 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
data[0] ^= 0xF5;
var v3 = data[1];
data[1] = data[1];
data[1] = v3;
var v4 = data[1];
data[1] = data[1];
data[1] = v4;
data[2] ^= 0x32;
data[0] ^= 0x51;
var v5 = data[0];
data[0] = data[2];
data[2] = v5;
var v18 = (byte)((data[1] >> 4) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
if (v18 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v6 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v6;
var v7 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v7;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[5] ^= 0xE9;
var v11 = data[27];
data[27] = data[30];
data[30] = v11;
var v12 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v12;
data[29] ^= 0xCE;
var v13 = (byte)(data[6] >> 2);
data[6] <<= 6;
data[6] |= v13;
data[2] ^= 0x73;
var v14 = (byte)(data[17] >> 6);
data[17] *= 4;
data[17] |= v14;
var v15 = (byte)((data[11] >> 6) & 1);
if (((data[11] >> 3) & 1) != 0)
{
data[11] |= 0x40;
}
else
{
data[11] &= 0xBF;
}
if (v15 != 0)
{
data[11] |= 8;
}
else
{
data[11] &= 0xF7;
}
}
else
{
var v17 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v17 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v9 = data[15];
data[15] = data[8];
data[8] = v9;
var v16 = (byte)((data[13] >> 6) & 1);
if (((data[13] >> 6) & 1) != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
if (v16 != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
var v10 = data[3];
data[3] = data[2];
data[2] = v10;
}
}
else
{
data[7] ^= 0xA9;
data[5] ^= 0x29;
data[3] ^= 0xC1;
var v8 = data[3];
data[3] = data[6];
data[6] = v8;
}
}
else
{
var v3 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v3;
var v4 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v4;
var v2 = (byte)((data[1] >> 4) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
if (v2 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v5 = data[0];
data[0] = data[2];
data[2] = v5;
data[0] ^= 0x51;
data[2] ^= 0x32;
var v6 = data[1];
data[1] = data[1];
data[1] = v6;
var v7 = data[1];
data[1] = data[1];
data[1] = v7;
data[0] ^= 0xF5;
var v18 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v18 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
data[1] ^= 0x48;
}
}
}
}

View File

@@ -0,0 +1,528 @@
// <copyright file="PacketTwisterOfFriendDeleteRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'FriendDeleteRequest' type.
/// </summary>
internal class PacketTwisterOfFriendDeleteRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v16 = data[27];
data[27] = data[1];
data[1] = v16;
var v17 = (byte)(data[28] >> 1);
data[28] <<= 7;
data[28] |= v17;
var v20 = (byte)((data[23] >> 6) & 1);
if (((data[23] >> 6) & 1) != 0)
{
data[23] |= 0x40;
}
else
{
data[23] &= 0xBF;
}
if (v20 != 0)
{
data[23] |= 0x40;
}
else
{
data[23] &= 0xBF;
}
var v18 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v18;
var v19 = (byte)(data[4] >> 5);
data[4] *= 8;
data[4] |= v19;
}
else
{
var v12 = data[6];
data[6] = data[7];
data[7] = v12;
data[12] ^= 0x36;
data[1] ^= 0x86;
var v26 = (byte)((data[5] >> 1) & 1);
if (((data[5] >> 5) & 1) != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
if (v26 != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
var v13 = (byte)(data[6] >> 6);
data[6] *= 4;
data[6] |= v13;
data[9] ^= 0x95;
var v25 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v25 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
var v24 = (byte)((data[6] >> 7) & 1);
if (((data[6] >> 2) & 1) != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
if (v24 != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
var v23 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v23 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v14 = (byte)(data[13] >> 7);
data[13] *= 2;
data[13] |= v14;
var v22 = (byte)((data[6] >> 7) & 1);
if (((data[6] >> 3) & 1) != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
if (v22 != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
var v21 = (byte)((data[11] >> 5) & 1);
if (((data[11] >> 2) & 1) != 0)
{
data[11] |= 0x20;
}
else
{
data[11] &= 0xDF;
}
if (v21 != 0)
{
data[11] |= 4;
}
else
{
data[11] &= 0xFB;
}
var v15 = (byte)(data[1] >> 3);
data[1] *= 32;
data[1] |= v15;
}
}
else
{
data[3] ^= 0x45;
data[3] ^= 0x4A;
var v11 = data[6];
data[6] = data[5];
data[5] = v11;
data[4] ^= 0xB2;
data[0] ^= 0x19;
data[0] ^= 0x23;
data[2] ^= 0xB7;
}
}
else
{
var v3 = data[3];
data[3] = data[1];
data[1] = v3;
var v4 = data[0];
data[0] = data[0];
data[0] = v4;
data[2] ^= 0xE6;
var v5 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v5;
var v2 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 3) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v2 != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
var v6 = data[2];
data[2] = data[1];
data[1] = v6;
var v7 = data[0];
data[0] = data[2];
data[2] = v7;
data[0] ^= 0x6D;
var v8 = data[0];
data[0] = data[1];
data[1] = v8;
var v9 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v9;
var v10 = data[0];
data[0] = data[1];
data[1] = v10;
var v27 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v27 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v16 = (byte)(data[4] >> 3);
data[4] *= 32;
data[4] |= v16;
var v17 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v17;
var v20 = (byte)((data[23] >> 6) & 1);
if (((data[23] >> 6) & 1) != 0)
{
data[23] |= 0x40;
}
else
{
data[23] &= 0xBF;
}
if (v20 != 0)
{
data[23] |= 0x40;
}
else
{
data[23] &= 0xBF;
}
var v18 = (byte)(data[28] >> 7);
data[28] *= 2;
data[28] |= v18;
var v19 = data[27];
data[27] = data[1];
data[1] = v19;
}
else
{
var v12 = (byte)(data[1] >> 5);
data[1] *= 8;
data[1] |= v12;
var v26 = (byte)((data[11] >> 5) & 1);
if (((data[11] >> 2) & 1) != 0)
{
data[11] |= 0x20;
}
else
{
data[11] &= 0xDF;
}
if (v26 != 0)
{
data[11] |= 4;
}
else
{
data[11] &= 0xFB;
}
var v25 = (byte)((data[6] >> 7) & 1);
if (((data[6] >> 3) & 1) != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
if (v25 != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
var v13 = (byte)(data[13] >> 1);
data[13] <<= 7;
data[13] |= v13;
var v24 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v24 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v23 = (byte)((data[6] >> 7) & 1);
if (((data[6] >> 2) & 1) != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
if (v23 != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
var v22 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v22 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
data[9] ^= 0x95;
var v14 = (byte)(data[6] >> 2);
data[6] <<= 6;
data[6] |= v14;
var v21 = (byte)((data[5] >> 1) & 1);
if (((data[5] >> 5) & 1) != 0)
{
data[5] |= 2;
}
else
{
data[5] &= 0xFD;
}
if (v21 != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
data[1] ^= 0x86;
data[12] ^= 0x36;
var v15 = data[6];
data[6] = data[7];
data[7] = v15;
}
}
else
{
data[2] ^= 0xB7;
data[0] ^= 0x23;
data[0] ^= 0x19;
data[4] ^= 0xB2;
var v11 = data[6];
data[6] = data[5];
data[5] = v11;
data[3] ^= 0x4A;
data[3] ^= 0x45;
}
}
else
{
var v2 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v2 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v3 = data[0];
data[0] = data[1];
data[1] = v3;
var v4 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v4;
var v5 = data[0];
data[0] = data[1];
data[1] = v5;
data[0] ^= 0x6D;
var v6 = data[0];
data[0] = data[2];
data[2] = v6;
var v7 = data[2];
data[2] = data[1];
data[1] = v7;
var v27 = (byte)((data[2] >> 7) & 1);
if (((data[2] >> 3) & 1) != 0)
{
data[2] |= 0x80;
}
else
{
data[2] &= 0x7F;
}
if (v27 != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
var v8 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v8;
data[2] ^= 0xE6;
var v9 = data[0];
data[0] = data[0];
data[0] = v9;
var v10 = data[3];
data[3] = data[1];
data[1] = v10;
}
}
}
}

View File

@@ -0,0 +1,472 @@
// <copyright file="PacketTwisterOfFriendList.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'FriendList' type.
/// </summary>
internal class PacketTwisterOfFriendList : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v13 = data[27];
data[27] = data[18];
data[18] = v13;
data[30] ^= 0x33;
var v14 = data[3];
data[3] = data[15];
data[15] = v14;
var v15 = data[3];
data[3] = data[3];
data[3] = v15;
var v16 = data[16];
data[16] = data[16];
data[16] = v16;
var v17 = (byte)((data[25] >> 3) & 1);
if (((data[25] >> 4) & 1) != 0)
{
data[25] |= 8;
}
else
{
data[25] &= 0xF7;
}
if (v17 != 0)
{
data[25] |= 0x10;
}
else
{
data[25] &= 0xEF;
}
}
else
{
var v9 = (byte)(data[9] >> 7);
data[9] *= 2;
data[9] |= v9;
data[7] ^= 0x88;
var v10 = data[15];
data[15] = data[11];
data[11] = v10;
data[4] ^= 0x3B;
var v11 = (byte)(data[4] >> 1);
data[4] <<= 7;
data[4] |= v11;
var v18 = (byte)((data[15] >> 4) & 1);
if (((data[15] >> 2) & 1) != 0)
{
data[15] |= 0x10;
}
else
{
data[15] &= 0xEF;
}
if (v18 != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
var v12 = (byte)(data[9] >> 5);
data[9] *= 8;
data[9] |= v12;
data[11] ^= 0x18;
data[6] ^= 0x26;
data[14] ^= 0x20;
}
}
else
{
data[0] ^= 0xCC;
var v6 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v6;
data[2] ^= 0x8D;
var v22 = (byte)((data[6] >> 3) & 1);
if (((data[6] >> 3) & 1) != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
if (v22 != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
data[0] ^= 0x10;
var v21 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 3) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v21 != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
var v7 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v7;
var v8 = data[6];
data[6] = data[1];
data[1] = v8;
var v20 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v20 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
var v19 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v19 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
}
}
else
{
var v3 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v3;
data[0] ^= 0x39;
data[3] ^= 0x63;
var v2 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v2 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
data[1] ^= 0x41;
var v4 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v4;
var v5 = data[0];
data[0] = data[3];
data[3] = v5;
var v23 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v23 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v17 = (byte)((data[25] >> 3) & 1);
if (((data[25] >> 4) & 1) != 0)
{
data[25] |= 8;
}
else
{
data[25] &= 0xF7;
}
if (v17 != 0)
{
data[25] |= 0x10;
}
else
{
data[25] &= 0xEF;
}
var v13 = data[16];
data[16] = data[16];
data[16] = v13;
var v14 = data[3];
data[3] = data[3];
data[3] = v14;
var v15 = data[3];
data[3] = data[15];
data[15] = v15;
data[30] ^= 0x33;
var v16 = data[27];
data[27] = data[18];
data[18] = v16;
}
else
{
data[14] ^= 0x20;
data[6] ^= 0x26;
data[11] ^= 0x18;
var v9 = (byte)(data[9] >> 3);
data[9] *= 32;
data[9] |= v9;
var v18 = (byte)((data[15] >> 4) & 1);
if (((data[15] >> 2) & 1) != 0)
{
data[15] |= 0x10;
}
else
{
data[15] &= 0xEF;
}
if (v18 != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
var v10 = (byte)(data[4] >> 7);
data[4] *= 2;
data[4] |= v10;
data[4] ^= 0x3B;
var v11 = data[15];
data[15] = data[11];
data[11] = v11;
data[7] ^= 0x88;
var v12 = (byte)(data[9] >> 1);
data[9] <<= 7;
data[9] |= v12;
}
}
else
{
var v22 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v22 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v21 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v21 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
var v6 = data[6];
data[6] = data[1];
data[1] = v6;
var v7 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v7;
var v20 = (byte)((data[1] >> 3) & 1);
if (((data[1] >> 3) & 1) != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
if (v20 != 0)
{
data[1] |= 8;
}
else
{
data[1] &= 0xF7;
}
data[0] ^= 0x10;
var v19 = (byte)((data[6] >> 3) & 1);
if (((data[6] >> 3) & 1) != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
if (v19 != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
data[2] ^= 0x8D;
var v8 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v8;
data[0] ^= 0xCC;
}
}
else
{
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v3 = data[0];
data[0] = data[3];
data[3] = v3;
var v4 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v4;
data[1] ^= 0x41;
var v23 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v23 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
data[3] ^= 0x63;
data[0] ^= 0x39;
var v5 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v5;
}
}
}
}

View File

@@ -0,0 +1,432 @@
// <copyright file="PacketTwisterOfFriendStateChange.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'FriendStateChange' type.
/// </summary>
internal class PacketTwisterOfFriendStateChange : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v20 = data[6];
data[6] = data[17];
data[17] = v20;
data[12] ^= 0x39;
var v24 = (byte)((data[26] >> 6) & 1);
if (((data[26] >> 4) & 1) != 0)
{
data[26] |= 0x40;
}
else
{
data[26] &= 0xBF;
}
if (v24 != 0)
{
data[26] |= 0x10;
}
else
{
data[26] &= 0xEF;
}
var v21 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v21;
var v22 = data[16];
data[16] = data[10];
data[10] = v22;
var v23 = (byte)((data[13] >> 2) & 1);
if (((data[13] >> 1) & 1) != 0)
{
data[13] |= 4;
}
else
{
data[13] &= 0xFB;
}
if (v23 != 0)
{
data[13] |= 2;
}
else
{
data[13] &= 0xFD;
}
}
else
{
data[12] ^= 0xEA;
var v15 = (byte)(data[8] >> 3);
data[8] *= 32;
data[8] |= v15;
var v26 = (byte)((data[8] >> 2) & 1);
if (((data[8] >> 2) & 1) != 0)
{
data[8] |= 4;
}
else
{
data[8] &= 0xFB;
}
if (v26 != 0)
{
data[8] |= 4;
}
else
{
data[8] &= 0xFB;
}
data[7] ^= 0x8D;
var v25 = (byte)((data[12] >> 1) & 1);
if (((data[12] >> 1) & 1) != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
if (v25 != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
var v16 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v16;
var v17 = data[14];
data[14] = data[13];
data[13] = v17;
var v18 = data[4];
data[4] = data[8];
data[8] = v18;
var v19 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v19;
}
}
else
{
var v10 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v10;
var v11 = data[2];
data[2] = data[2];
data[2] = v11;
data[2] ^= 0x74;
data[4] ^= 0x44;
var v12 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v12;
var v13 = data[3];
data[3] = data[6];
data[6] = v13;
data[3] ^= 0x3F;
var v14 = data[6];
data[6] = data[4];
data[4] = v14;
data[7] ^= 0xF8;
var v27 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v27 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
data[1] ^= 0x17;
}
}
else
{
var v3 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v3;
var v4 = data[1];
data[1] = data[3];
data[3] = v4;
var v5 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v5;
var v6 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v6;
data[3] ^= 0xC2;
var v7 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v7;
var v2 = (byte)((data[1] >> 4) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
if (v2 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
var v8 = data[0];
data[0] = data[1];
data[1] = v8;
data[3] ^= 0x8C;
var v9 = data[3];
data[3] = data[2];
data[2] = v9;
data[0] ^= 0xB6;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v24 = (byte)((data[13] >> 2) & 1);
if (((data[13] >> 1) & 1) != 0)
{
data[13] |= 4;
}
else
{
data[13] &= 0xFB;
}
if (v24 != 0)
{
data[13] |= 2;
}
else
{
data[13] &= 0xFD;
}
var v20 = data[16];
data[16] = data[10];
data[10] = v20;
var v21 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v21;
var v23 = (byte)((data[26] >> 6) & 1);
if (((data[26] >> 4) & 1) != 0)
{
data[26] |= 0x40;
}
else
{
data[26] &= 0xBF;
}
if (v23 != 0)
{
data[26] |= 0x10;
}
else
{
data[26] &= 0xEF;
}
data[12] ^= 0x39;
var v22 = data[6];
data[6] = data[17];
data[17] = v22;
}
else
{
var v15 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v15;
var v16 = data[4];
data[4] = data[8];
data[8] = v16;
var v17 = data[14];
data[14] = data[13];
data[13] = v17;
var v18 = (byte)(data[0] >> 7);
data[0] *= 2;
data[0] |= v18;
var v26 = (byte)((data[12] >> 1) & 1);
if (((data[12] >> 1) & 1) != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
if (v26 != 0)
{
data[12] |= 2;
}
else
{
data[12] &= 0xFD;
}
data[7] ^= 0x8D;
var v25 = (byte)((data[8] >> 2) & 1);
if (((data[8] >> 2) & 1) != 0)
{
data[8] |= 4;
}
else
{
data[8] &= 0xFB;
}
if (v25 != 0)
{
data[8] |= 4;
}
else
{
data[8] &= 0xFB;
}
var v19 = (byte)(data[8] >> 5);
data[8] *= 8;
data[8] |= v19;
data[12] ^= 0xEA;
}
}
else
{
data[1] ^= 0x17;
var v27 = (byte)((data[2] >> 6) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
if (v27 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
data[7] ^= 0xF8;
var v10 = data[6];
data[6] = data[4];
data[4] = v10;
data[3] ^= 0x3F;
var v11 = data[3];
data[3] = data[6];
data[6] = v11;
var v12 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v12;
data[4] ^= 0x44;
data[2] ^= 0x74;
var v13 = data[2];
data[2] = data[2];
data[2] = v13;
var v14 = (byte)(data[3] >> 4);
data[3] *= 16;
data[3] |= v14;
}
}
else
{
data[0] ^= 0xB6;
var v3 = data[3];
data[3] = data[2];
data[2] = v3;
data[3] ^= 0x8C;
var v4 = data[0];
data[0] = data[1];
data[1] = v4;
var v2 = (byte)((data[1] >> 4) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
if (v2 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
var v5 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v5;
data[3] ^= 0xC2;
var v6 = (byte)(data[0] >> 1);
data[0] <<= 7;
data[0] |= v6;
var v7 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v7;
var v8 = data[1];
data[1] = data[3];
data[3] = v8;
var v9 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v9;
}
}
}
}

View File

@@ -0,0 +1,361 @@
// <copyright file="PacketTwisterOfGameGuardAuth.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GameGuardAuth' type.
/// </summary>
internal class PacketTwisterOfGameGuardAuth : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v16 = data[1];
data[1] = data[4];
data[4] = v16;
data[1] ^= 0xA3;
var v17 = data[4];
data[4] = data[28];
data[28] = v17;
var v20 = (byte)((data[13] >> 2) & 1);
if (((data[13] >> 3) & 1) != 0)
{
data[13] |= 4;
}
else
{
data[13] &= 0xFB;
}
if (v20 != 0)
{
data[13] |= 8;
}
else
{
data[13] &= 0xF7;
}
data[17] ^= 0xB5;
var v18 = (byte)(data[18] >> 2);
data[18] <<= 6;
data[18] |= v18;
var v19 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v19 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
}
else
{
var v21 = (byte)((data[8] >> 1) & 1);
if (((data[8] >> 1) & 1) != 0)
{
data[8] |= 2;
}
else
{
data[8] &= 0xFD;
}
if (v21 != 0)
{
data[8] |= 2;
}
else
{
data[8] &= 0xFD;
}
var v14 = data[11];
data[11] = data[6];
data[6] = v14;
var v15 = data[1];
data[1] = data[3];
data[3] = v15;
}
}
else
{
var v8 = data[7];
data[7] = data[4];
data[4] = v8;
var v22 = (byte)((data[6] >> 3) & 1);
if (((data[6] >> 5) & 1) != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
if (v22 != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
var v9 = (byte)(data[5] >> 2);
data[5] <<= 6;
data[5] |= v9;
data[2] ^= 0xC;
var v10 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v10;
var v11 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v11;
var v12 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v12;
var v13 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v13;
data[6] ^= 6;
data[0] ^= 0x70;
}
}
else
{
var v3 = data[2];
data[2] = data[0];
data[0] = v3;
var v4 = data[1];
data[1] = data[1];
data[1] = v4;
var v5 = data[0];
data[0] = data[2];
data[2] = v5;
var v6 = data[0];
data[0] = data[1];
data[1] = v6;
data[2] ^= 0x9E;
var v7 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v7;
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
data[3] ^= 0xFD;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v20 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v20 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
var v16 = (byte)(data[18] >> 6);
data[18] *= 4;
data[18] |= v16;
data[17] ^= 0xB5;
var v19 = (byte)((data[13] >> 2) & 1);
if (((data[13] >> 3) & 1) != 0)
{
data[13] |= 4;
}
else
{
data[13] &= 0xFB;
}
if (v19 != 0)
{
data[13] |= 8;
}
else
{
data[13] &= 0xF7;
}
var v17 = data[4];
data[4] = data[28];
data[28] = v17;
data[1] ^= 0xA3;
var v18 = data[1];
data[1] = data[4];
data[4] = v18;
}
else
{
var v14 = data[1];
data[1] = data[3];
data[3] = v14;
var v15 = data[11];
data[11] = data[6];
data[6] = v15;
var v21 = (byte)((data[8] >> 1) & 1);
if (((data[8] >> 1) & 1) != 0)
{
data[8] |= 2;
}
else
{
data[8] &= 0xFD;
}
if (v21 != 0)
{
data[8] |= 2;
}
else
{
data[8] &= 0xFD;
}
}
}
else
{
data[0] ^= 0x70;
data[6] ^= 6;
var v8 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v8;
var v9 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v9;
var v10 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v10;
var v11 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v11;
data[2] ^= 0xC;
var v12 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v12;
var v22 = (byte)((data[6] >> 3) & 1);
if (((data[6] >> 5) & 1) != 0)
{
data[6] |= 8;
}
else
{
data[6] &= 0xF7;
}
if (v22 != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
var v13 = data[7];
data[7] = data[4];
data[4] = v13;
}
}
else
{
data[3] ^= 0xFD;
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 2) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
var v3 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v3;
data[2] ^= 0x9E;
var v4 = data[0];
data[0] = data[1];
data[1] = v4;
var v5 = data[0];
data[0] = data[2];
data[2] = v5;
var v6 = data[1];
data[1] = data[1];
data[1] = v6;
var v7 = data[2];
data[2] = data[0];
data[0] = v7;
}
}
}
}

View File

@@ -0,0 +1,442 @@
// <copyright file="PacketTwisterOfGuildAssign.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildAssign' type.
/// </summary>
internal class PacketTwisterOfGuildAssign : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v19 = data[27];
data[27] = data[12];
data[12] = v19;
data[5] ^= 0x75;
data[9] ^= 0xEB;
var v20 = (byte)(data[26] >> 4);
data[26] *= 16;
data[26] |= v20;
var v21 = (byte)(data[17] >> 3);
data[17] *= 32;
data[17] |= v21;
var v22 = (byte)(data[27] >> 5);
data[27] *= 8;
data[27] |= v22;
data[3] ^= 0xE;
var v23 = (byte)(data[15] >> 3);
data[15] *= 32;
data[15] |= v23;
var v24 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v24;
var v25 = data[30];
data[30] = data[7];
data[7] = v25;
var v26 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 2) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v26 != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
}
else
{
data[12] ^= 0x31;
var v14 = data[2];
data[2] = data[10];
data[10] = v14;
var v15 = (byte)(data[15] >> 7);
data[15] *= 2;
data[15] |= v15;
var v16 = data[15];
data[15] = data[5];
data[5] = v16;
var v28 = (byte)((data[12] >> 2) & 1);
if (((data[12] >> 3) & 1) != 0)
{
data[12] |= 4;
}
else
{
data[12] &= 0xFB;
}
if (v28 != 0)
{
data[12] |= 8;
}
else
{
data[12] &= 0xF7;
}
var v17 = (byte)(data[2] >> 5);
data[2] *= 8;
data[2] |= v17;
var v18 = data[3];
data[3] = data[0];
data[0] = v18;
var v27 = (byte)((data[14] >> 4) & 1);
if (((data[14] >> 7) & 1) != 0)
{
data[14] |= 0x10;
}
else
{
data[14] &= 0xEF;
}
if (v27 != 0)
{
data[14] |= 0x80;
}
else
{
data[14] &= 0x7F;
}
}
}
else
{
var v30 = (byte)((data[4] >> 6) & 1);
if (((data[4] >> 7) & 1) != 0)
{
data[4] |= 0x40;
}
else
{
data[4] &= 0xBF;
}
if (v30 != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
var v10 = data[2];
data[2] = data[3];
data[3] = v10;
var v11 = data[0];
data[0] = data[1];
data[1] = v11;
var v12 = (byte)(data[7] >> 7);
data[7] *= 2;
data[7] |= v12;
data[7] ^= 0x42;
data[1] ^= 0xEF;
data[6] ^= 0x54;
var v29 = (byte)((data[5] >> 4) & 1);
if (((data[5] >> 4) & 1) != 0)
{
data[5] |= 0x10;
}
else
{
data[5] &= 0xEF;
}
if (v29 != 0)
{
data[5] |= 0x10;
}
else
{
data[5] &= 0xEF;
}
var v13 = data[1];
data[1] = data[3];
data[3] = v13;
}
}
else
{
var v3 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v3;
var v4 = data[2];
data[2] = data[2];
data[2] = v4;
data[3] ^= 8;
var v5 = data[1];
data[1] = data[0];
data[0] = v5;
var v6 = data[3];
data[3] = data[2];
data[2] = v6;
var v7 = data[2];
data[2] = data[3];
data[3] = v7;
var v2 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v2 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
var v8 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v8;
var v9 = data[1];
data[1] = data[3];
data[3] = v9;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v26 = (byte)((data[5] >> 5) & 1);
if (((data[5] >> 2) & 1) != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
if (v26 != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
var v19 = data[30];
data[30] = data[7];
data[7] = v19;
var v20 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v20;
var v21 = (byte)(data[15] >> 5);
data[15] *= 8;
data[15] |= v21;
data[3] ^= 0xE;
var v22 = (byte)(data[27] >> 3);
data[27] *= 32;
data[27] |= v22;
var v23 = (byte)(data[17] >> 5);
data[17] *= 8;
data[17] |= v23;
var v24 = (byte)(data[26] >> 4);
data[26] *= 16;
data[26] |= v24;
data[9] ^= 0xEB;
data[5] ^= 0x75;
var v25 = data[27];
data[27] = data[12];
data[12] = v25;
}
else
{
var v28 = (byte)((data[14] >> 4) & 1);
if (((data[14] >> 7) & 1) != 0)
{
data[14] |= 0x10;
}
else
{
data[14] &= 0xEF;
}
if (v28 != 0)
{
data[14] |= 0x80;
}
else
{
data[14] &= 0x7F;
}
var v14 = data[3];
data[3] = data[0];
data[0] = v14;
var v15 = (byte)(data[2] >> 3);
data[2] *= 32;
data[2] |= v15;
var v27 = (byte)((data[12] >> 2) & 1);
if (((data[12] >> 3) & 1) != 0)
{
data[12] |= 4;
}
else
{
data[12] &= 0xFB;
}
if (v27 != 0)
{
data[12] |= 8;
}
else
{
data[12] &= 0xF7;
}
var v16 = data[15];
data[15] = data[5];
data[5] = v16;
var v17 = (byte)(data[15] >> 1);
data[15] <<= 7;
data[15] |= v17;
var v18 = data[2];
data[2] = data[10];
data[10] = v18;
data[12] ^= 0x31;
}
}
else
{
var v10 = data[1];
data[1] = data[3];
data[3] = v10;
var v30 = (byte)((data[5] >> 4) & 1);
if (((data[5] >> 4) & 1) != 0)
{
data[5] |= 0x10;
}
else
{
data[5] &= 0xEF;
}
if (v30 != 0)
{
data[5] |= 0x10;
}
else
{
data[5] &= 0xEF;
}
data[6] ^= 0x54;
data[1] ^= 0xEF;
data[7] ^= 0x42;
var v11 = (byte)(data[7] >> 1);
data[7] <<= 7;
data[7] |= v11;
var v12 = data[0];
data[0] = data[1];
data[1] = v12;
var v13 = data[2];
data[2] = data[3];
data[3] = v13;
var v29 = (byte)((data[4] >> 6) & 1);
if (((data[4] >> 7) & 1) != 0)
{
data[4] |= 0x40;
}
else
{
data[4] &= 0xBF;
}
if (v29 != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
}
}
else
{
var v3 = data[1];
data[1] = data[3];
data[3] = v3;
var v4 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v4;
var v2 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 2) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v2 != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
var v5 = data[2];
data[2] = data[3];
data[3] = v5;
var v6 = data[3];
data[3] = data[2];
data[2] = v6;
var v7 = data[1];
data[1] = data[0];
data[0] = v7;
data[3] ^= 8;
var v8 = data[2];
data[2] = data[2];
data[2] = v8;
var v9 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v9;
}
}
}
}

View File

@@ -0,0 +1,451 @@
// <copyright file="PacketTwisterOfGuildInfo.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildInfo' type.
/// </summary>
internal class PacketTwisterOfGuildInfo : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v10 = data[27];
data[27] = data[7];
data[7] = v10;
var v11 = (byte)(data[31] >> 6);
data[31] *= 4;
data[31] |= v11;
var v12 = (byte)(data[0] >> 4);
data[0] *= 16;
data[0] |= v12;
data[29] ^= 0x39;
data[13] ^= 0xCA;
var v13 = data[9];
data[9] = data[17];
data[17] = v13;
data[10] ^= 0xC2;
var v14 = data[6];
data[6] = data[11];
data[11] = v14;
}
else
{
var v17 = (byte)((data[2] >> 3) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
if (v17 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v16 = (byte)((data[11] >> 2) & 1);
if (((data[11] >> 7) & 1) != 0)
{
data[11] |= 4;
}
else
{
data[11] &= 0xFB;
}
if (v16 != 0)
{
data[11] |= 0x80;
}
else
{
data[11] &= 0x7F;
}
data[12] ^= 0x2A;
var v6 = data[6];
data[6] = data[3];
data[3] = v6;
var v7 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v7;
var v8 = data[9];
data[9] = data[10];
data[10] = v8;
var v15 = (byte)((data[10] >> 3) & 1);
if (((data[10] >> 4) & 1) != 0)
{
data[10] |= 8;
}
else
{
data[10] &= 0xF7;
}
if (v15 != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
var v9 = (byte)(data[9] >> 5);
data[9] *= 8;
data[9] |= v9;
data[11] ^= 0xA0;
}
}
else
{
data[5] ^= 0x35;
var v20 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v20 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v19 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v19 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v3 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v3;
data[7] ^= 0x95;
var v4 = (byte)(data[6] >> 1);
data[6] <<= 7;
data[6] |= v4;
var v5 = data[1];
data[1] = data[6];
data[6] = v5;
var v18 = (byte)((data[3] >> 4) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
if (v18 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
}
}
else
{
var v2 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 2) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v2 != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
data[3] ^= 0x7F;
var v21 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v21 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v10 = data[6];
data[6] = data[11];
data[11] = v10;
data[10] ^= 0xC2;
var v11 = data[9];
data[9] = data[17];
data[17] = v11;
data[13] ^= 0xCA;
data[29] ^= 0x39;
var v12 = (byte)(data[0] >> 4);
data[0] *= 16;
data[0] |= v12;
var v13 = (byte)(data[31] >> 2);
data[31] <<= 6;
data[31] |= v13;
var v14 = data[27];
data[27] = data[7];
data[7] = v14;
}
else
{
data[11] ^= 0xA0;
var v6 = (byte)(data[9] >> 3);
data[9] *= 32;
data[9] |= v6;
var v17 = (byte)((data[10] >> 3) & 1);
if (((data[10] >> 4) & 1) != 0)
{
data[10] |= 8;
}
else
{
data[10] &= 0xF7;
}
if (v17 != 0)
{
data[10] |= 0x10;
}
else
{
data[10] &= 0xEF;
}
var v7 = data[9];
data[9] = data[10];
data[10] = v7;
var v8 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v8;
var v9 = data[6];
data[6] = data[3];
data[3] = v9;
data[12] ^= 0x2A;
var v16 = (byte)((data[11] >> 2) & 1);
if (((data[11] >> 7) & 1) != 0)
{
data[11] |= 4;
}
else
{
data[11] &= 0xFB;
}
if (v16 != 0)
{
data[11] |= 0x80;
}
else
{
data[11] &= 0x7F;
}
var v15 = (byte)((data[2] >> 3) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 8;
}
else
{
data[2] &= 0xF7;
}
if (v15 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
}
}
else
{
var v20 = (byte)((data[3] >> 4) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
if (v20 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v3 = data[1];
data[1] = data[6];
data[6] = v3;
var v4 = (byte)(data[6] >> 7);
data[6] *= 2;
data[6] |= v4;
data[7] ^= 0x95;
var v5 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v5;
var v19 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 1) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v19 != 0)
{
data[3] |= 2;
}
else
{
data[3] &= 0xFD;
}
var v18 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v18 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
data[5] ^= 0x35;
}
}
else
{
var v2 = (byte)((data[2] >> 5) & 1);
if (((data[2] >> 4) & 1) != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
if (v2 != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
data[3] ^= 0x7F;
var v21 = (byte)((data[3] >> 2) & 1);
if (((data[3] >> 2) & 1) != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
if (v21 != 0)
{
data[3] |= 4;
}
else
{
data[3] &= 0xFB;
}
}
}
}
}

View File

@@ -0,0 +1,379 @@
// <copyright file="PacketTwisterOfGuildJoinRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildJoinRequest' type.
/// </summary>
internal class PacketTwisterOfGuildJoinRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v14 = data[26];
data[26] = data[22];
data[22] = v14;
var v15 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 4) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v15 != 0)
{
data[15] |= 0x10;
}
else
{
data[15] &= 0xEF;
}
data[11] ^= 0x6A;
}
else
{
var v13 = data[10];
data[10] = data[12];
data[12] = v13;
data[9] ^= 0x46;
data[10] ^= 0xC3;
}
}
else
{
var v6 = data[3];
data[3] = data[5];
data[5] = v6;
data[0] ^= 0x2B;
var v18 = (byte)((data[6] >> 1) & 1);
if (((data[6] >> 6) & 1) != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
if (v18 != 0)
{
data[6] |= 0x40;
}
else
{
data[6] &= 0xBF;
}
var v17 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 2) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v17 != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
var v7 = (byte)(data[6] >> 6);
data[6] *= 4;
data[6] |= v7;
var v8 = data[5];
data[5] = data[0];
data[0] = v8;
var v9 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v9;
var v10 = data[3];
data[3] = data[4];
data[4] = v10;
var v11 = (byte)(data[7] >> 1);
data[7] <<= 7;
data[7] |= v11;
var v16 = (byte)((data[7] >> 4) & 1);
if (((data[7] >> 4) & 1) != 0)
{
data[7] |= 0x10;
}
else
{
data[7] &= 0xEF;
}
if (v16 != 0)
{
data[7] |= 0x10;
}
else
{
data[7] &= 0xEF;
}
var v12 = (byte)(data[2] >> 2);
data[2] <<= 6;
data[2] |= v12;
}
}
else
{
data[3] ^= 0x15;
data[0] ^= 0xDB;
var v2 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v2 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v19 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v19 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v3 = data[3];
data[3] = data[1];
data[1] = v3;
data[0] ^= 0x6A;
var v4 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v4;
data[2] ^= 0xC1;
var v5 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v5;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[11] ^= 0x6A;
var v15 = (byte)((data[15] >> 2) & 1);
if (((data[15] >> 4) & 1) != 0)
{
data[15] |= 4;
}
else
{
data[15] &= 0xFB;
}
if (v15 != 0)
{
data[15] |= 0x10;
}
else
{
data[15] &= 0xEF;
}
var v14 = data[26];
data[26] = data[22];
data[22] = v14;
}
else
{
data[10] ^= 0xC3;
data[9] ^= 0x46;
var v13 = data[10];
data[10] = data[12];
data[12] = v13;
}
}
else
{
var v6 = (byte)(data[2] >> 6);
data[2] *= 4;
data[2] |= v6;
var v18 = (byte)((data[7] >> 4) & 1);
if (((data[7] >> 4) & 1) != 0)
{
data[7] |= 0x10;
}
else
{
data[7] &= 0xEF;
}
if (v18 != 0)
{
data[7] |= 0x10;
}
else
{
data[7] &= 0xEF;
}
var v7 = (byte)(data[7] >> 7);
data[7] *= 2;
data[7] |= v7;
var v8 = data[3];
data[3] = data[4];
data[4] = v8;
var v9 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v9;
var v10 = data[5];
data[5] = data[0];
data[0] = v10;
var v11 = (byte)(data[6] >> 2);
data[6] <<= 6;
data[6] |= v11;
var v17 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 2) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v17 != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
var v16 = (byte)((data[6] >> 1) & 1);
if (((data[6] >> 6) & 1) != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
if (v16 != 0)
{
data[6] |= 0x40;
}
else
{
data[6] &= 0xBF;
}
data[0] ^= 0x2B;
var v12 = data[3];
data[3] = data[5];
data[5] = v12;
}
}
else
{
var v3 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v3;
data[2] ^= 0xC1;
var v4 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v4;
data[0] ^= 0x6A;
var v5 = data[3];
data[3] = data[1];
data[1] = v5;
var v2 = (byte)((data[0] >> 1) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
if (v2 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v19 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v19 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[0] ^= 0xDB;
data[3] ^= 0x15;
}
}
}
}

View File

@@ -0,0 +1,202 @@
// <copyright file="PacketTwisterOfGuildJoinResponse.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildJoinResponse' type.
/// </summary>
internal class PacketTwisterOfGuildJoinResponse : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[20] ^= 0x29;
var v10 = (byte)(data[13] >> 4);
data[13] *= 16;
data[13] |= v10;
var v11 = (byte)(data[25] >> 3);
data[25] *= 32;
data[25] |= v11;
var v12 = (byte)(data[15] >> 6);
data[15] *= 4;
data[15] |= v12;
var v13 = data[13];
data[13] = data[29];
data[29] = v13;
var v14 = data[23];
data[23] = data[23];
data[23] = v14;
var v15 = (byte)(data[25] >> 5);
data[25] *= 8;
data[25] |= v15;
var v16 = (byte)(data[18] >> 6);
data[18] *= 4;
data[18] |= v16;
var v17 = (byte)(data[7] >> 5);
data[7] *= 8;
data[7] |= v17;
data[10] ^= 0x75;
data[15] ^= 0xEA;
}
else
{
var v6 = data[5];
data[5] = data[9];
data[9] = v6;
var v7 = (byte)(data[13] >> 1);
data[13] <<= 7;
data[13] |= v7;
var v8 = data[10];
data[10] = data[0];
data[0] = v8;
var v9 = data[3];
data[3] = data[11];
data[11] = v9;
}
}
else
{
var v4 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v4;
data[4] ^= 0xEB;
var v5 = data[3];
data[3] = data[2];
data[2] = v5;
var v2 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v2 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
}
}
else
{
data[3] ^= 0xDE;
data[3] ^= 0x9A;
var v3 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v3;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[15] ^= 0xEA;
data[10] ^= 0x75;
var v10 = (byte)(data[7] >> 3);
data[7] *= 32;
data[7] |= v10;
var v11 = (byte)(data[18] >> 2);
data[18] <<= 6;
data[18] |= v11;
var v12 = (byte)(data[25] >> 3);
data[25] *= 32;
data[25] |= v12;
var v13 = data[23];
data[23] = data[23];
data[23] = v13;
var v14 = data[13];
data[13] = data[29];
data[29] = v14;
var v15 = (byte)(data[15] >> 2);
data[15] <<= 6;
data[15] |= v15;
var v16 = (byte)(data[25] >> 5);
data[25] *= 8;
data[25] |= v16;
var v17 = (byte)(data[13] >> 4);
data[13] *= 16;
data[13] |= v17;
data[20] ^= 0x29;
}
else
{
var v6 = data[3];
data[3] = data[11];
data[11] = v6;
var v7 = data[10];
data[10] = data[0];
data[0] = v7;
var v8 = (byte)(data[13] >> 7);
data[13] *= 2;
data[13] |= v8;
var v9 = data[5];
data[5] = data[9];
data[9] = v9;
}
}
else
{
var v2 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v2 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v4 = data[3];
data[3] = data[2];
data[2] = v4;
data[4] ^= 0xEB;
var v5 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v5;
}
}
else
{
var v3 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v3;
data[3] ^= 0x9A;
data[3] ^= 0xDE;
}
}
}
}

View File

@@ -0,0 +1,499 @@
// <copyright file="PacketTwisterOfGuildKick.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildKick' type.
/// </summary>
internal class PacketTwisterOfGuildKick : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[16] ^= 0xD9;
var v24 = (byte)((data[28] >> 7) & 1);
if (((data[28] >> 1) & 1) != 0)
{
data[28] |= 0x80;
}
else
{
data[28] &= 0x7F;
}
if (v24 != 0)
{
data[28] |= 2;
}
else
{
data[28] &= 0xFD;
}
var v18 = data[2];
data[2] = data[4];
data[4] = v18;
var v23 = (byte)((data[5] >> 3) & 1);
if (((data[5] >> 6) & 1) != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
if (v23 != 0)
{
data[5] |= 0x40;
}
else
{
data[5] &= 0xBF;
}
var v19 = (byte)(data[18] >> 6);
data[18] *= 4;
data[18] |= v19;
var v20 = data[16];
data[16] = data[0];
data[0] = v20;
data[10] ^= 0x2B;
var v22 = (byte)((data[24] >> 2) & 1);
if (((data[24] >> 2) & 1) != 0)
{
data[24] |= 4;
}
else
{
data[24] &= 0xFB;
}
if (v22 != 0)
{
data[24] |= 4;
}
else
{
data[24] &= 0xFB;
}
var v21 = (byte)(data[27] >> 1);
data[27] <<= 7;
data[27] |= v21;
}
else
{
var v12 = (byte)(data[9] >> 7);
data[9] *= 2;
data[9] |= v12;
var v13 = data[6];
data[6] = data[7];
data[7] = v13;
var v14 = data[9];
data[9] = data[14];
data[14] = v14;
var v15 = data[1];
data[1] = data[12];
data[12] = v15;
var v25 = (byte)((data[0] >> 7) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x80;
}
else
{
data[0] &= 0x7F;
}
if (v25 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[6] ^= 0x8D;
data[12] ^= 0x85;
data[11] ^= 0xCC;
var v16 = (byte)(data[9] >> 4);
data[9] *= 16;
data[9] |= v16;
var v17 = data[5];
data[5] = data[3];
data[3] = v17;
}
}
else
{
var v6 = data[6];
data[6] = data[6];
data[6] = v6;
var v7 = data[0];
data[0] = data[4];
data[4] = v7;
data[5] ^= 0xAC;
var v2 = (byte)((data[5] >> 2) & 1);
if (((data[5] >> 5) & 1) != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
if (v2 != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
var v8 = data[7];
data[7] = data[0];
data[0] = v8;
data[4] ^= 0xE5;
var v9 = data[6];
data[6] = data[0];
data[0] = v9;
data[5] ^= 0xD9;
var v28 = (byte)((data[6] >> 4) & 1);
if (((data[6] >> 4) & 1) != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
if (v28 != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
var v27 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v27 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v26 = (byte)((data[4] >> 5) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x20;
}
else
{
data[4] &= 0xDF;
}
if (v26 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v10 = (byte)(data[4] >> 6);
data[4] *= 4;
data[4] |= v10;
var v11 = data[7];
data[7] = data[2];
data[2] = v11;
}
}
else
{
var v3 = (byte)(data[2] >> 1);
data[2] <<= 7;
data[2] |= v3;
data[2] ^= 0x71;
var v4 = (byte)(data[0] >> 6);
data[0] *= 4;
data[0] |= v4;
var v5 = data[1];
data[1] = data[3];
data[3] = v5;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v18 = (byte)(data[27] >> 7);
data[27] *= 2;
data[27] |= v18;
var v24 = (byte)((data[24] >> 2) & 1);
if (((data[24] >> 2) & 1) != 0)
{
data[24] |= 4;
}
else
{
data[24] &= 0xFB;
}
if (v24 != 0)
{
data[24] |= 4;
}
else
{
data[24] &= 0xFB;
}
data[10] ^= 0x2B;
var v19 = data[16];
data[16] = data[0];
data[0] = v19;
var v20 = (byte)(data[18] >> 2);
data[18] <<= 6;
data[18] |= v20;
var v23 = (byte)((data[5] >> 3) & 1);
if (((data[5] >> 6) & 1) != 0)
{
data[5] |= 8;
}
else
{
data[5] &= 0xF7;
}
if (v23 != 0)
{
data[5] |= 0x40;
}
else
{
data[5] &= 0xBF;
}
var v21 = data[2];
data[2] = data[4];
data[4] = v21;
var v22 = (byte)((data[28] >> 7) & 1);
if (((data[28] >> 1) & 1) != 0)
{
data[28] |= 0x80;
}
else
{
data[28] &= 0x7F;
}
if (v22 != 0)
{
data[28] |= 2;
}
else
{
data[28] &= 0xFD;
}
data[16] ^= 0xD9;
}
else
{
var v12 = data[5];
data[5] = data[3];
data[3] = v12;
var v13 = (byte)(data[9] >> 4);
data[9] *= 16;
data[9] |= v13;
data[11] ^= 0xCC;
data[12] ^= 0x85;
data[6] ^= 0x8D;
var v25 = (byte)((data[0] >> 7) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 0x80;
}
else
{
data[0] &= 0x7F;
}
if (v25 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
var v14 = data[1];
data[1] = data[12];
data[12] = v14;
var v15 = data[9];
data[9] = data[14];
data[14] = v15;
var v16 = data[6];
data[6] = data[7];
data[7] = v16;
var v17 = (byte)(data[9] >> 1);
data[9] <<= 7;
data[9] |= v17;
}
}
else
{
var v6 = data[7];
data[7] = data[2];
data[2] = v6;
var v7 = (byte)(data[4] >> 2);
data[4] <<= 6;
data[4] |= v7;
var v2 = (byte)((data[4] >> 5) & 1);
if (((data[4] >> 1) & 1) != 0)
{
data[4] |= 0x20;
}
else
{
data[4] &= 0xDF;
}
if (v2 != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
var v28 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 4) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v28 != 0)
{
data[1] |= 0x10;
}
else
{
data[1] &= 0xEF;
}
var v27 = (byte)((data[6] >> 4) & 1);
if (((data[6] >> 4) & 1) != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
if (v27 != 0)
{
data[6] |= 0x10;
}
else
{
data[6] &= 0xEF;
}
data[5] ^= 0xD9;
var v8 = data[6];
data[6] = data[0];
data[0] = v8;
data[4] ^= 0xE5;
var v9 = data[7];
data[7] = data[0];
data[0] = v9;
var v26 = (byte)((data[5] >> 2) & 1);
if (((data[5] >> 5) & 1) != 0)
{
data[5] |= 4;
}
else
{
data[5] &= 0xFB;
}
if (v26 != 0)
{
data[5] |= 0x20;
}
else
{
data[5] &= 0xDF;
}
data[5] ^= 0xAC;
var v10 = data[0];
data[0] = data[4];
data[4] = v10;
var v11 = data[6];
data[6] = data[6];
data[6] = v11;
}
}
else
{
var v3 = data[1];
data[1] = data[3];
data[3] = v3;
var v4 = (byte)(data[0] >> 2);
data[0] <<= 6;
data[0] |= v4;
data[2] ^= 0x71;
var v5 = (byte)(data[2] >> 7);
data[2] *= 2;
data[2] |= v5;
}
}
}
}

View File

@@ -0,0 +1,370 @@
// <copyright file="PacketTwisterOfGuildList.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildList' type.
/// </summary>
internal class PacketTwisterOfGuildList : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v12 = (byte)(data[9] >> 5);
data[9] *= 8;
data[9] |= v12;
var v13 = (byte)(data[22] >> 3);
data[22] *= 32;
data[22] |= v13;
data[25] ^= 0xC3;
var v14 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v14;
var v15 = data[17];
data[17] = data[26];
data[26] = v15;
data[20] ^= 0xD9;
var v16 = data[7];
data[7] = data[3];
data[3] = v16;
var v17 = (byte)(data[11] >> 1);
data[11] <<= 7;
data[11] |= v17;
}
else
{
var v19 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 6) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v19 != 0)
{
data[6] |= 0x40;
}
else
{
data[6] &= 0xBF;
}
var v10 = (byte)(data[12] >> 5);
data[12] *= 8;
data[12] |= v10;
var v18 = (byte)((data[6] >> 5) & 1);
if (((data[6] >> 1) & 1) != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
if (v18 != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
var v11 = (byte)(data[10] >> 7);
data[10] *= 2;
data[10] |= v11;
data[3] ^= 0xF4;
}
}
else
{
data[1] ^= 0xD8;
var v21 = (byte)((data[4] >> 1) & 1);
if (((data[4] >> 7) & 1) != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
if (v21 != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
var v8 = data[6];
data[6] = data[5];
data[5] = v8;
data[5] ^= 0x19;
data[6] ^= 0x51;
data[0] ^= 0x5B;
data[0] ^= 0x65;
var v9 = data[1];
data[1] = data[2];
data[2] = v9;
var v20 = (byte)((data[6] >> 6) & 1);
if (((data[6] >> 1) & 1) != 0)
{
data[6] |= 0x40;
}
else
{
data[6] &= 0xBF;
}
if (v20 != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
data[6] ^= 0xB4;
}
}
else
{
data[0] ^= 0xA9;
var v3 = (byte)(data[3] >> 2);
data[3] <<= 6;
data[3] |= v3;
data[1] ^= 0x4D;
var v4 = data[1];
data[1] = data[1];
data[1] = v4;
data[0] ^= 0x48;
data[0] ^= 0x50;
data[3] ^= 0x32;
var v5 = (byte)(data[1] >> 1);
data[1] <<= 7;
data[1] |= v5;
var v6 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v6;
var v2 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v2 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v7 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v7;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v12 = (byte)(data[11] >> 7);
data[11] *= 2;
data[11] |= v12;
var v13 = data[7];
data[7] = data[3];
data[3] = v13;
data[20] ^= 0xD9;
var v14 = data[17];
data[17] = data[26];
data[26] = v14;
var v15 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v15;
data[25] ^= 0xC3;
var v16 = (byte)(data[22] >> 5);
data[22] *= 8;
data[22] |= v16;
var v17 = (byte)(data[9] >> 3);
data[9] *= 32;
data[9] |= v17;
}
else
{
data[3] ^= 0xF4;
var v10 = (byte)(data[10] >> 1);
data[10] <<= 7;
data[10] |= v10;
var v19 = (byte)((data[6] >> 5) & 1);
if (((data[6] >> 1) & 1) != 0)
{
data[6] |= 0x20;
}
else
{
data[6] &= 0xDF;
}
if (v19 != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
var v11 = (byte)(data[12] >> 3);
data[12] *= 32;
data[12] |= v11;
var v18 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 6) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v18 != 0)
{
data[6] |= 0x40;
}
else
{
data[6] &= 0xBF;
}
}
}
else
{
data[6] ^= 0xB4;
var v21 = (byte)((data[6] >> 6) & 1);
if (((data[6] >> 1) & 1) != 0)
{
data[6] |= 0x40;
}
else
{
data[6] &= 0xBF;
}
if (v21 != 0)
{
data[6] |= 2;
}
else
{
data[6] &= 0xFD;
}
var v8 = data[1];
data[1] = data[2];
data[2] = v8;
data[0] ^= 0x65;
data[0] ^= 0x5B;
data[6] ^= 0x51;
data[5] ^= 0x19;
var v9 = data[6];
data[6] = data[5];
data[5] = v9;
var v20 = (byte)((data[4] >> 1) & 1);
if (((data[4] >> 7) & 1) != 0)
{
data[4] |= 2;
}
else
{
data[4] &= 0xFD;
}
if (v20 != 0)
{
data[4] |= 0x80;
}
else
{
data[4] &= 0x7F;
}
data[1] ^= 0xD8;
}
}
else
{
var v3 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v3;
var v2 = (byte)((data[2] >> 1) & 1);
if (((data[2] >> 6) & 1) != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
if (v2 != 0)
{
data[2] |= 0x40;
}
else
{
data[2] &= 0xBF;
}
var v4 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v4;
var v5 = (byte)(data[1] >> 7);
data[1] *= 2;
data[1] |= v5;
data[3] ^= 0x32;
data[0] ^= 0x50;
data[0] ^= 0x48;
var v6 = data[1];
data[1] = data[1];
data[1] = v6;
data[1] ^= 0x4D;
var v7 = (byte)(data[3] >> 6);
data[3] *= 4;
data[3] |= v7;
data[0] ^= 0xA9;
}
}
}
}

View File

@@ -0,0 +1,422 @@
// <copyright file="PacketTwisterOfGuildMasterInfo.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildMasterInfo' type.
/// </summary>
internal class PacketTwisterOfGuildMasterInfo : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v13 = (byte)(data[15] >> 2);
data[15] <<= 6;
data[15] |= v13;
var v16 = (byte)((data[9] >> 2) & 1);
if (((data[9] >> 1) & 1) != 0)
{
data[9] |= 4;
}
else
{
data[9] &= 0xFB;
}
if (v16 != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
var v14 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v14;
var v15 = (byte)(data[26] >> 3);
data[26] *= 32;
data[26] |= v15;
}
else
{
var v10 = data[9];
data[9] = data[0];
data[0] = v10;
var v17 = (byte)((data[14] >> 3) & 1);
if (((data[14] >> 6) & 1) != 0)
{
data[14] |= 8;
}
else
{
data[14] &= 0xF7;
}
if (v17 != 0)
{
data[14] |= 0x40;
}
else
{
data[14] &= 0xBF;
}
var v11 = data[11];
data[11] = data[14];
data[14] = v11;
var v12 = data[13];
data[13] = data[11];
data[11] = v12;
data[6] ^= 0xDC;
data[12] ^= 0x59;
}
}
else
{
var v20 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v20 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
data[3] ^= 0xFB;
var v19 = (byte)((data[7] >> 2) & 1);
if (((data[7] >> 3) & 1) != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
if (v19 != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
data[7] ^= 0xAB;
var v8 = data[1];
data[1] = data[6];
data[6] = v8;
var v18 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v18 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
var v9 = data[4];
data[4] = data[3];
data[3] = v9;
}
}
else
{
var v3 = data[1];
data[1] = data[1];
data[1] = v3;
var v4 = data[3];
data[3] = data[0];
data[0] = v4;
var v5 = (byte)(data[1] >> 6);
data[1] *= 4;
data[1] |= v5;
data[0] ^= 0xD6;
var v2 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v2 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
var v6 = (byte)(data[0] >> 3);
data[0] *= 32;
data[0] |= v6;
var v7 = data[2];
data[2] = data[0];
data[0] = v7;
data[2] ^= 0x63;
data[1] ^= 0x9A;
var v21 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 4) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v21 != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
data[2] = data[2];
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v13 = (byte)(data[26] >> 5);
data[26] *= 8;
data[26] |= v13;
var v14 = (byte)(data[5] >> 4);
data[5] *= 16;
data[5] |= v14;
var v16 = (byte)((data[9] >> 2) & 1);
if (((data[9] >> 1) & 1) != 0)
{
data[9] |= 4;
}
else
{
data[9] &= 0xFB;
}
if (v16 != 0)
{
data[9] |= 2;
}
else
{
data[9] &= 0xFD;
}
var v15 = (byte)(data[15] >> 6);
data[15] *= 4;
data[15] |= v15;
}
else
{
data[12] ^= 0x59;
data[6] ^= 0xDC;
var v10 = data[13];
data[13] = data[11];
data[11] = v10;
var v11 = data[11];
data[11] = data[14];
data[14] = v11;
var v17 = (byte)((data[14] >> 3) & 1);
if (((data[14] >> 6) & 1) != 0)
{
data[14] |= 8;
}
else
{
data[14] &= 0xF7;
}
if (v17 != 0)
{
data[14] |= 0x40;
}
else
{
data[14] &= 0xBF;
}
var v12 = data[9];
data[9] = data[0];
data[0] = v12;
}
}
else
{
var v8 = data[4];
data[4] = data[3];
data[3] = v8;
var v20 = (byte)((data[2] >> 4) & 1);
if (((data[2] >> 1) & 1) != 0)
{
data[2] |= 0x10;
}
else
{
data[2] &= 0xEF;
}
if (v20 != 0)
{
data[2] |= 2;
}
else
{
data[2] &= 0xFD;
}
var v9 = data[1];
data[1] = data[6];
data[6] = v9;
data[7] ^= 0xAB;
var v19 = (byte)((data[7] >> 2) & 1);
if (((data[7] >> 3) & 1) != 0)
{
data[7] |= 4;
}
else
{
data[7] &= 0xFB;
}
if (v19 != 0)
{
data[7] |= 8;
}
else
{
data[7] &= 0xF7;
}
data[3] ^= 0xFB;
var v18 = (byte)((data[0] >> 3) & 1);
if (((data[0] >> 1) & 1) != 0)
{
data[0] |= 8;
}
else
{
data[0] &= 0xF7;
}
if (v18 != 0)
{
data[0] |= 2;
}
else
{
data[0] &= 0xFD;
}
}
}
else
{
data[2] = data[2];
var v2 = (byte)((data[0] >> 2) & 1);
if (((data[0] >> 4) & 1) != 0)
{
data[0] |= 4;
}
else
{
data[0] &= 0xFB;
}
if (v2 != 0)
{
data[0] |= 0x10;
}
else
{
data[0] &= 0xEF;
}
data[1] ^= 0x9A;
data[2] ^= 0x63;
var v3 = data[2];
data[2] = data[0];
data[0] = v3;
var v4 = (byte)(data[0] >> 5);
data[0] *= 8;
data[0] |= v4;
var v21 = (byte)((data[1] >> 1) & 1);
if (((data[1] >> 1) & 1) != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
if (v21 != 0)
{
data[1] |= 2;
}
else
{
data[1] &= 0xFD;
}
data[0] ^= 0xD6;
var v5 = (byte)(data[1] >> 2);
data[1] <<= 6;
data[1] |= v5;
var v6 = data[3];
data[3] = data[0];
data[0] = v6;
var v7 = data[1];
data[1] = data[1];
data[1] = v7;
}
}
}
}

View File

@@ -0,0 +1,434 @@
// <copyright file="PacketTwisterOfGuildMasterResponse.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildMasterResponse' type.
/// </summary>
/// <remarks>This implementation seems to be wrong - Twist and Correct is the same code!.</remarks>
internal class PacketTwisterOfGuildMasterResponse : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v11 = (byte)(data[17] >> 6);
data[17] *= 4;
data[17] |= v11;
var v12 = data[6];
data[6] = data[4];
data[4] = v12;
var v18 = (byte)((data[21] >> 2) & 1);
if (((data[21] >> 4) & 1) != 0)
{
data[21] |= 4;
}
else
{
data[21] &= 0xFB;
}
if (v18 != 0)
{
data[21] |= 0x10;
}
else
{
data[21] &= 0xEF;
}
var v13 = data[22];
data[22] = data[17];
data[17] = v13;
data[23] ^= 0xB4;
var v17 = (byte)((data[19] >> 7) & 1);
if (((data[19] >> 7) & 1) != 0)
{
data[19] |= 0x80;
}
else
{
data[19] &= 0x7F;
}
if (v17 != 0)
{
data[19] |= 0x80;
}
else
{
data[19] &= 0x7F;
}
var v16 = (byte)((data[17] >> 7) & 1);
if (((data[17] >> 5) & 1) != 0)
{
data[17] |= 0x80;
}
else
{
data[17] &= 0x7F;
}
if (v16 != 0)
{
data[17] |= 0x20;
}
else
{
data[17] &= 0xDF;
}
data[5] ^= 0x40;
var v14 = data[23];
data[23] = data[12];
data[12] = v14;
var v15 = (byte)((data[27] >> 1) & 1);
if (((data[27] >> 2) & 1) != 0)
{
data[27] |= 2;
}
else
{
data[27] &= 0xFD;
}
if (v15 != 0)
{
data[27] |= 4;
}
else
{
data[27] &= 0xFB;
}
}
else
{
data[3] ^= 0x2F;
data[4] ^= 0x17;
data[15] ^= 0x5B;
data[7] ^= 0x53;
var v19 = (byte)((data[11] >> 7) & 1);
if (((data[11] >> 3) & 1) != 0)
{
data[11] |= 0x80;
}
else
{
data[11] &= 0x7F;
}
if (v19 != 0)
{
data[11] |= 8;
}
else
{
data[11] &= 0xF7;
}
data[3] ^= 0x89;
data[14] ^= 0x6D;
var v9 = data[13];
data[13] = data[9];
data[9] = v9;
data[12] ^= 0xFC;
data[4] ^= 0xF7;
var v10 = data[5];
data[5] = data[4];
data[4] = v10;
}
}
else
{
var v7 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v7;
var v8 = (byte)(data[7] >> 7);
data[7] *= 2;
data[7] |= v8;
data[1] ^= 0x98;
var v20 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v20 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
data[3] ^= 0xDD;
data[1] ^= 6;
data[4] ^= 0x7E;
}
}
else
{
data[2] ^= 0xCF;
data[0] ^= 0xD6;
var v3 = data[3];
data[3] = data[2];
data[2] = v3;
data[2] ^= 0x72;
data[0] ^= 0xE2;
var v4 = data[2];
data[2] = data[3];
data[3] = v4;
var v5 = data[0];
data[0] = data[3];
data[3] = v5;
var v6 = (byte)(data[3] >> 1);
data[3] <<= 7;
data[3] |= v6;
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v11 = (byte)(data[17] >> 6);
data[17] *= 4;
data[17] |= v11;
var v12 = data[6];
data[6] = data[4];
data[4] = v12;
var v18 = (byte)((data[21] >> 2) & 1);
if (((data[21] >> 4) & 1) != 0)
{
data[21] |= 4;
}
else
{
data[21] &= 0xFB;
}
if (v18 != 0)
{
data[21] |= 0x10;
}
else
{
data[21] &= 0xEF;
}
var v13 = data[22];
data[22] = data[17];
data[17] = v13;
data[23] ^= 0xB4;
var v17 = (byte)((data[19] >> 7) & 1);
if (((data[19] >> 7) & 1) != 0)
{
data[19] |= 0x80;
}
else
{
data[19] &= 0x7F;
}
if (v17 != 0)
{
data[19] |= 0x80;
}
else
{
data[19] &= 0x7F;
}
var v16 = (byte)((data[17] >> 7) & 1);
if (((data[17] >> 5) & 1) != 0)
{
data[17] |= 0x80;
}
else
{
data[17] &= 0x7F;
}
if (v16 != 0)
{
data[17] |= 0x20;
}
else
{
data[17] &= 0xDF;
}
data[5] ^= 0x40;
var v14 = data[23];
data[23] = data[12];
data[12] = v14;
var v15 = (byte)((data[27] >> 1) & 1);
if (((data[27] >> 2) & 1) != 0)
{
data[27] |= 2;
}
else
{
data[27] &= 0xFD;
}
if (v15 != 0)
{
data[27] |= 4;
}
else
{
data[27] &= 0xFB;
}
}
else
{
data[3] ^= 0x2F;
data[4] ^= 0x17;
data[15] ^= 0x5B;
data[7] ^= 0x53;
var v19 = (byte)((data[11] >> 7) & 1);
if (((data[11] >> 3) & 1) != 0)
{
data[11] |= 0x80;
}
else
{
data[11] &= 0x7F;
}
if (v19 != 0)
{
data[11] |= 8;
}
else
{
data[11] &= 0xF7;
}
data[3] ^= 0x89;
data[14] ^= 0x6D;
var v9 = data[13];
data[13] = data[9];
data[9] = v9;
data[12] ^= 0xFC;
data[4] ^= 0xF7;
var v10 = data[5];
data[5] = data[4];
data[4] = v10;
}
}
else
{
var v7 = (byte)(data[5] >> 6);
data[5] *= 4;
data[5] |= v7;
var v8 = (byte)(data[7] >> 7);
data[7] *= 2;
data[7] |= v8;
data[1] ^= 0x98;
var v20 = (byte)((data[6] >> 2) & 1);
if (((data[6] >> 7) & 1) != 0)
{
data[6] |= 4;
}
else
{
data[6] &= 0xFB;
}
if (v20 != 0)
{
data[6] |= 0x80;
}
else
{
data[6] &= 0x7F;
}
data[3] ^= 0xDD;
data[1] ^= 6;
data[4] ^= 0x7E;
}
}
else
{
data[2] ^= 0xCF;
data[0] ^= 0xD6;
var v3 = data[3];
data[3] = data[2];
data[2] = v3;
data[2] ^= 0x72;
data[0] ^= 0xE2;
var v4 = data[2];
data[2] = data[3];
data[3] = v4;
var v5 = data[0];
data[0] = data[3];
data[3] = v5;
var v6 = (byte)(data[3] >> 1);
data[3] <<= 7;
data[3] |= v6;
var v2 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v2 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
}
}
}
}

View File

@@ -0,0 +1,401 @@
// <copyright file="PacketTwisterOfGuildWarRequest.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Network.PacketTwister;
/// <summary>
/// PacketTwister implementation for packets of 'GuildWarRequest' type.
/// </summary>
internal class PacketTwisterOfGuildWarRequest : IPacketTwister
{
/// <inheritdoc/>
public void Twist(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
var v21 = (byte)(data[7] >> 1);
data[7] <<= 7;
data[7] |= v21;
var v22 = (byte)(data[30] >> 6);
data[30] *= 4;
data[30] |= v22;
var v23 = data[18];
data[18] = data[5];
data[5] = v23;
var v24 = data[20];
data[20] = data[13];
data[13] = v24;
var v25 = (byte)(data[4] >> 1);
data[4] <<= 7;
data[4] |= v25;
data[18] ^= 0x91;
}
else
{
var v28 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v28 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
var v16 = data[5];
data[5] = data[6];
data[6] = v16;
data[11] ^= 0xBC;
var v17 = data[0];
data[0] = data[0];
data[0] = v17;
var v18 = data[0];
data[0] = data[6];
data[6] = v18;
var v19 = data[0];
data[0] = data[12];
data[12] = v19;
var v20 = (byte)(data[15] >> 7);
data[15] *= 2;
data[15] |= v20;
var v27 = (byte)((data[15] >> 3) & 1);
if (((data[15] >> 5) & 1) != 0)
{
data[15] |= 8;
}
else
{
data[15] &= 0xF7;
}
if (v27 != 0)
{
data[15] |= 0x20;
}
else
{
data[15] &= 0xDF;
}
var v26 = (byte)((data[13] >> 3) & 1);
if (((data[13] >> 6) & 1) != 0)
{
data[13] |= 8;
}
else
{
data[13] &= 0xF7;
}
if (v26 != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
}
}
else
{
var v8 = (byte)(data[5] >> 7);
data[5] *= 2;
data[5] |= v8;
var v9 = data[5];
data[5] = data[0];
data[0] = v9;
var v10 = (byte)(data[0] >> 5);
data[0] *= 8;
data[0] |= v10;
var v11 = data[3];
data[3] = data[4];
data[4] = v11;
var v12 = data[7];
data[7] = data[1];
data[1] = v12;
var v13 = data[0];
data[0] = data[1];
data[1] = v13;
data[3] ^= 0x47;
data[0] ^= 0xAF;
var v29 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v29 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
data[1] ^= 0x18;
var v14 = data[3];
data[3] = data[6];
data[6] = v14;
var v15 = (byte)(data[5] >> 5);
data[5] *= 8;
data[5] |= v15;
}
}
else
{
var v3 = data[3];
data[3] = data[3];
data[3] = v3;
var v4 = (byte)(data[1] >> 4);
data[1] *= 16;
data[1] |= v4;
var v5 = (byte)(data[3] >> 3);
data[3] *= 32;
data[3] |= v5;
var v6 = data[3];
data[3] = data[2];
data[2] = v6;
data[1] ^= 0xD8;
var v2 = (byte)((data[3] >> 4) & 1);
if (((data[3] >> 3) & 1) != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
if (v2 != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
var v7 = data[1];
data[1] = data[2];
data[2] = v7;
}
}
}
/// <inheritdoc/>
public void Correct(Span<byte> data)
{
if (data.Length >= 4)
{
if (data.Length >= 8)
{
if (data.Length >= 16)
{
if (data.Length >= 32)
{
data[18] ^= 0x91;
var v21 = (byte)(data[4] >> 7);
data[4] *= 2;
data[4] |= v21;
var v22 = data[20];
data[20] = data[13];
data[13] = v22;
var v23 = data[18];
data[18] = data[5];
data[5] = v23;
var v24 = (byte)(data[30] >> 2);
data[30] <<= 6;
data[30] |= v24;
var v25 = (byte)(data[7] >> 7);
data[7] *= 2;
data[7] |= v25;
}
else
{
var v28 = (byte)((data[13] >> 3) & 1);
if (((data[13] >> 6) & 1) != 0)
{
data[13] |= 8;
}
else
{
data[13] &= 0xF7;
}
if (v28 != 0)
{
data[13] |= 0x40;
}
else
{
data[13] &= 0xBF;
}
var v27 = (byte)((data[15] >> 3) & 1);
if (((data[15] >> 5) & 1) != 0)
{
data[15] |= 8;
}
else
{
data[15] &= 0xF7;
}
if (v27 != 0)
{
data[15] |= 0x20;
}
else
{
data[15] &= 0xDF;
}
var v16 = (byte)(data[15] >> 1);
data[15] <<= 7;
data[15] |= v16;
var v17 = data[0];
data[0] = data[12];
data[12] = v17;
var v18 = data[0];
data[0] = data[6];
data[6] = v18;
var v19 = data[0];
data[0] = data[0];
data[0] = v19;
data[11] ^= 0xBC;
var v20 = data[5];
data[5] = data[6];
data[6] = v20;
var v26 = (byte)((data[1] >> 2) & 1);
if (((data[1] >> 5) & 1) != 0)
{
data[1] |= 4;
}
else
{
data[1] &= 0xFB;
}
if (v26 != 0)
{
data[1] |= 0x20;
}
else
{
data[1] &= 0xDF;
}
}
}
else
{
var v8 = (byte)(data[5] >> 3);
data[5] *= 32;
data[5] |= v8;
var v9 = data[3];
data[3] = data[6];
data[6] = v9;
data[1] ^= 0x18;
var v29 = (byte)((data[2] >> 2) & 1);
if (((data[2] >> 5) & 1) != 0)
{
data[2] |= 4;
}
else
{
data[2] &= 0xFB;
}
if (v29 != 0)
{
data[2] |= 0x20;
}
else
{
data[2] &= 0xDF;
}
data[0] ^= 0xAF;
data[3] ^= 0x47;
var v10 = data[0];
data[0] = data[1];
data[1] = v10;
var v11 = data[7];
data[7] = data[1];
data[1] = v11;
var v12 = data[3];
data[3] = data[4];
data[4] = v12;
var v13 = (byte)(data[0] >> 3);
data[0] *= 32;
data[0] |= v13;
var v14 = data[5];
data[5] = data[0];
data[0] = v14;
var v15 = (byte)(data[5] >> 1);
data[5] <<= 7;
data[5] |= v15;
}
}
else
{
var v3 = data[1];
data[1] = data[2];
data[2] = v3;
var v2 = (byte)((data[3] >> 4) & 1);
if (((data[3] >> 3) & 1) != 0)
{
data[3] |= 0x10;
}
else
{
data[3] &= 0xEF;
}
if (v2 != 0)
{
data[3] |= 8;
}
else
{
data[3] &= 0xF7;
}
data[1] ^= 0xD8;
var v4 = data[3];
data[3] = data[2];
data[2] = v4;
var v5 = (byte)(data[3] >> 5);
data[3] *= 8;
data[3] |= v5;
var v6 = (byte)(data[1] >> 4);
data[1] *= 16;
data[1] |= v6;
var v7 = data[3];
data[3] = data[3];
data[3] = v7;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More