Script protection is an optional feature for pack authors who want to hide their script implementation details. By default, scripts are stored as plain text and compiled only when needed.
Alpha testing is still in progress, so access is currently limited. To get access to this functionality, contact me.
EyeAuras lets users write custom C# scripts. By default, those scripts are stored as plain text as part of the user config and compiled only when necessary. That is convenient during development, but it also creates risks: someone may inspect your code or even modify it without your knowledge.
When using Packing, you can enable script precompilation. This compiles your scripts into binary format ahead of time and includes them in the finished pack together with the app. In that form, the script text is no longer present — only executable modules remain. This improves performance, so it is worth enabling even if protection is not your main concern.
For an experienced programmer, compilation is not a real barrier to understanding code.
There are plenty of tools that can reverse the process (decompilation) and recover source code in an almost identical form. That is why EyeAuras also provides protection mechanisms for already compiled code.
Important! After changing Packing settings, do not forget to click
Upload— your changes only affect the NEXT pack revision.

EyeAuras offers three levels of protection for your code:
EyeAuras uses several powerful techniques to protect scripts:
Choose the protection level based on your priorities: if maximum speed matters most, use ** Performance First**; if security matters more, use ** Security First**. This may still be adjusted further as early feedback comes in.
public class, then all public methods, properties, and fields in that class will keep their names. If you want the highest possible level of protection, declare classes as internal whenever you can — that tells the obfuscator it is free to transform them aggressively.Q: What happens if I forget to enable protection during packing?
Q: If my pack has no scripts, will protection help?
Q: Does protection affect performance?
Q: Does protection guarantee complete security?
Q: Do I need to think about security myself, or will EyeAuras handle everything for me?
Q: What should I do if my protected pack suddenly stops working?
Q: Can I test how well my pack is protected?
Q: Can I enable protection only for some scripts?
Q: Can I specify which methods or classes should be protected?
https://eyeauras.net/share/S20241213181401RaWLZLE430e6
Let’s take the same method, EnsureWindowIsInsideScreenBounds. It is fairly simple: if the bot window ends up outside the screen for some reason, the method moves it back to the center.
Here is the original plain-text version:
private void EnsureWindowIsInsideScreenBounds()
{
var windowRect = new Rectangle(Window.Left, Window.Top, Window.Width, Window.Height);
var screenSize = System.Windows.Forms.Screen.PrimaryScreen!.WorkingArea;
// Calculate the minimum visible area required (50% of window size)
var minVisibleWidth = Window.Width / 2;
var minVisibleHeight = Window.Height / 2;
// Check if the visible portion of the window is less than 50%
var isOutOfBounds =
(windowRect.Left + minVisibleWidth < 0) || // Too far left
(windowRect.Top + minVisibleHeight < 0) || // Too far up
(windowRect.Right - minVisibleWidth > screenSize.Width) || // Too far right
(windowRect.Bottom - minVisibleHeight > screenSize.Height); // Too far down
if (isOutOfBounds)
{
Log.Warn($"Window is considered out of screen bounds, window position: {windowRect}, screen: {screenSize}");
}
var positionNotSet = Window.Left == 0 && Window.Top == 0;
if (isOutOfBounds)
{
Log.Warn($"Window position is not set, resetting, screen: {screenSize}");
}
if (positionNotSet || isOutOfBounds)
{
var centered = windowRect.Size.CenterInsideBounds(screenSize);
Log.Info($"Setting window position to {centered}");
Window.SetWindowRect(centered);
}
}
Here is the decompiled version (Script Protection = None) — slightly less readable, but not by much:
// Token: 0x06000084 RID: 132 RVA: 0x00005C68 File Offset: 0x00003E68
private void EnsureWindowIsInsideScreenBounds()
{
Rectangle rectangle;
rectangle..ctor(this.Window.Left, this.Window.Top, this.Window.Width, this.Window.Height);
Rectangle workingArea = Screen.PrimaryScreen.WorkingArea;
int num = this.Window.Width / 2;
int num2 = this.Window.Height / 2;
bool flag = rectangle.Left + num < 0 || rectangle.Top + num2 < 0 || rectangle.Right - num > workingArea.Width || rectangle.Bottom - num2 > workingArea.Height;
bool flag2 = flag;
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler;
if (flag2)
{
IFluentLog log = this.Log;
defaultInterpolatedStringHandler..ctor(70, 2);
defaultInterpolatedStringHandler.AppendLiteral("Window is considered out of screen bounds, window position: ");
defaultInterpolatedStringHandler.AppendFormatted<Rectangle>(rectangle);
defaultInterpolatedStringHandler.AppendLiteral(", screen: ");
defaultInterpolatedStringHandler.AppendFormatted<Rectangle>(workingArea);
log.Warn(defaultInterpolatedStringHandler.ToStringAndClear());
}
bool flag3 = this.Window.Left == 0 && this.Window.Top == 0;
bool flag4 = flag;
if (flag4)
{
IFluentLog log2 = this.Log;
defaultInterpolatedStringHandler..ctor(47, 1);
defaultInterpolatedStringHandler.AppendLiteral("Window position is not set, resetting, screen: ");
defaultInterpolatedStringHandler.AppendFormatted<Rectangle>(workingArea);
log2.Warn(defaultInterpolatedStringHandler.ToStringAndClear());
}
bool flag5 = flag3 || flag;
if (flag5)
{
Rectangle rectangle2 = GeometryExtensions.CenterInsideBounds(rectangle.Size, workingArea);
IFluentLog log3 = this.Log;
defaultInterpolatedStringHandler..ctor(27, 1);
defaultInterpolatedStringHandler.AppendLiteral("Setting window position to ");
defaultInterpolatedStringHandler.AppendFormatted<Rectangle>(rectangle2);
log3.Info(defaultInterpolatedStringHandler.ToStringAndClear());
this.Window.SetWindowRect(rectangle2);
}
}
Now let’s apply obfuscation (Performance First):
// Token: 0x06000086 RID: 134 RVA: 0x00008424 File Offset: 0x00006624
private void \uF71C\uE8CB\uF729\uF528\uF733\uECFF\uED61\uE8DD\uE3B9\uEBEC\uEF0D\uEF13()
{
Rectangle rectangle;
int num3;
Rectangle workingArea;
for (;;)
{
int num = GameStates.\uED1A\uF315\uE180\uEF00\uE442\uF137\uE320\uE6DD\uE44A\uE69E\uE6E6\uF02B(21);
for (;;)
{
num ^= \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(132);
if (-21 <= -45)
{
goto Block_13;
}
switch (num + 60)
{
case 0:
{
int num2;
if (rectangle.Left + num2 < \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(0))
{
goto IL_149;
}
if (-6 >= 122)
{
goto IL_36D;
}
num = -2;
continue;
}
case 1:
if (rectangle.Top + num3 >= \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(0))
{
num = PoeHelperConfig.\uE49B\uE532\uE4AA\uE8C7\uF28E\uF11C\uF019\uF17B\uF13E\uECC2\uF3DC\uF21A(30);
continue;
}
goto IL_149;
case 2:
num3 = this.Window.Height / \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(4);
num = -1;
continue;
case 3:
workingArea = Screen.PrimaryScreen.WorkingArea;
num = -13;
continue;
case 4:
{
int num2 = this.Window.Width / \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(4);
num = -3;
continue;
}
case 5:
{
int num2;
if (rectangle.Right - num2 <= workingArea.Width)
{
num = -16;
continue;
}
goto IL_149;
}
case 6:
rectangle..ctor(this.Window.Left, this.Window.Top, this.Window.Width, this.Window.Height);
num = -4;
continue;
case 7:
goto IL_135;
}
break;
}
if (-44 <= -49)
{
goto Block_14;
}
}
int num4;
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler;
Rectangle rectangle2;
for (;;)
{
IL_2A3:
num4 ^= \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(51);
switch (num4 + 59)
{
case 0:
{
IFluentLog log = this.Log;
defaultInterpolatedStringHandler..ctor(\uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(30), \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(1));
defaultInterpolatedStringHandler.AppendLiteral(\uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDC.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BA(10217));
defaultInterpolatedStringHandler.AppendFormatted<Rectangle>(rectangle2);
log.Info(defaultInterpolatedStringHandler.ToStringAndClear());
num4 = -6;
continue;
}
case 1:
this.Window.SetWindowRect(rectangle2);
num4 = -5;
continue;
case 2:
goto IL_33D;
case 3:
num4 = -7;
continue;
case 4:
num4 = -11;
continue;
case 5:
goto IL_38F;
}
goto IL_2D1;
}
IL_33D:
rectangle2 = GeometryExtensions.CenterInsideBounds(rectangle.Size, workingArea);
goto IL_36D;
IL_38F:
return;
IL_135:
bool flag = rectangle.Bottom - num3 > workingArea.Height;
goto IL_14F;
IL_149:
flag = (\uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(1) != 0);
IL_14F:
bool flag2 = flag;
bool flag3 = flag2;
if (flag3)
{
for (;;)
{
int num5 = GameStates.\uED1A\uF315\uE180\uEF00\uE442\uF137\uE320\uE6DD\uE44A\uE69E\uE6E6\uF02B(28);
for (;;)
{
num5 ^= \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(48);
switch (num5 + 53)
{
case 0:
{
IFluentLog log2 = this.Log;
defaultInterpolatedStringHandler..ctor(\uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(60), \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(4));
defaultInterpolatedStringHandler.AppendLiteral(\uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDC.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BA(10065));
defaultInterpolatedStringHandler.AppendFormatted<Rectangle>(rectangle);
defaultInterpolatedStringHandler.AppendLiteral(\uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDC.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BA(10006));
defaultInterpolatedStringHandler.AppendFormatted<Rectangle>(workingArea);
log2.Warn(defaultInterpolatedStringHandler.ToStringAndClear());
num5 = -4;
continue;
}
case 1:
num5 = -3;
continue;
case 2:
goto IL_203;
}
break;
}
}
IL_203:;
}
bool flag4 = ((this.Window.Left != 0) ? \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(0) : ((this.Window.Top == \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(0)) ? 1 : 0)) != 0;
bool flag5 = flag2;
if (flag5)
{
IFluentLog log3 = this.Log;
defaultInterpolatedStringHandler..ctor(\uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(47), \uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDD.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BE(1));
defaultInterpolatedStringHandler.AppendLiteral(\uF744\uE158\uE9D5\uF663\uE9B4\uE5B0\uE89D\uE381\uF018\uE2BD\uEB29\uEEDC.\uE057\uED84\uE170\uF871\uEA8E\uE42A\uECDD\uF1D7\uF489\uEC92\uE642\uF2BA(10009));
defaultInterpolatedStringHandler.AppendFormatted<Rectangle>(workingArea);
log3.Warn(defaultInterpolatedStringHandler.ToStringAndClear());
}
bool flag6 = flag4 || flag2;
if (!flag6)
{
return;
}
IL_2D1:
num4 = PoeEyeComponent.\uE237\uF4ED\uF88E\uED18\uECFD\uE0BD\uF228\uF776\uE7C2\uF10D\uF78D\uF79B(42);
goto IL_2A3;
Block_13:
Block_14:
IL_36D:
num4 = PoeHelperConfig.\uE49B\uE532\uE4AA\uE8C7\uF28E\uF11C\uF019\uF17B\uF13E\uECC2\uF3DC\uF21A(27);
goto IL_2A3;
}
And here is the same method (presumably...) in Security First mode. In this case, the code is not only obfuscated as in the previous example, but also encrypted.
// Token: 0x06000086 RID: 134 RVA: 0x000049C4 File Offset: 0x00002BC4
private void \uF5D1\uF8EB\uF0A0\uF126\uE1AD\uE6ED\uE599\uE94C\uE27D\uF25B\uE418\uECFF()
{
\uE536\uEA7D\uE611\uEE66\uF5F5\uEDF9\uF549\uE4FC\uF1E9\uEEBD\uEC8C\uF5EE.\uF3ED\uE329\uF180\uF009\uF045\uEFE8\uF38D\uF0F9\uF700\uE210\uE95F\uE40E(1833101, null, this, null);
}