Skip to content

Commit

Permalink
Merge pull request #544 from Xian55/refactor/iwowscreen
Browse files Browse the repository at this point in the history
Refactor: Abstraction layer for `IWoWScreen`
  • Loading branch information
Xian55 authored Oct 19, 2023
2 parents 20d977f + f704c81 commit ba069d5
Show file tree
Hide file tree
Showing 36 changed files with 572 additions and 185 deletions.
6 changes: 3 additions & 3 deletions BlazorServer/BlazorServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="6.0.1" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.2.0" />
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.3.0" />
<PackageReference Include="Serilog.Enrichers.Process" Version="2.0.2" />
<PackageReference Include="Serilog.Expressions" Version="3.4.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
</ItemGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
Expand Down
4 changes: 2 additions & 2 deletions Core/AddonDataProvider/AddonDataProviderBitBlt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ public sealed class AddonDataProviderBitBlt : IAddonDataProvider
private readonly Bitmap bitmap;
private readonly Graphics graphics;

private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;

private IntPtr hWnd = IntPtr.Zero;
private IntPtr windowDC = IntPtr.Zero;

private readonly bool windowedMode;
private Point p;

public AddonDataProviderBitBlt(WowScreen wowScreen, DataFrame[] frames)
public AddonDataProviderBitBlt(IWowScreen wowScreen, DataFrame[] frames)
{
this.wowScreen = wowScreen;
this.frames = frames;
Expand Down
19 changes: 7 additions & 12 deletions Core/AddonDataProvider/AddonDataProviderDXGI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public sealed class AddonDataProviderDXGI : IAddonDataProvider
public int[] Data { get; private init; }
public StringBuilder TextBuilder { get; } = new(3);

private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;
private readonly DataFrame[] frames;

private static readonly FeatureLevel[] s_featureLevels =
Expand All @@ -31,8 +31,6 @@ public sealed class AddonDataProviderDXGI : IAddonDataProvider
FeatureLevel.Level_11_0,
};

private readonly Vortice.RawRect bounds;

private readonly IDXGIAdapter adapter;
private readonly IDXGIOutput output;
private readonly IDXGIOutput1 output1;
Expand All @@ -47,7 +45,7 @@ public sealed class AddonDataProviderDXGI : IAddonDataProvider
private readonly bool windowedMode;
private Point p;

public AddonDataProviderDXGI(WowScreen wowScreen, DataFrame[] frames)
public AddonDataProviderDXGI(IWowScreen wowScreen, DataFrame[] frames)
{
this.wowScreen = wowScreen;

Expand All @@ -66,9 +64,7 @@ public AddonDataProviderDXGI(WowScreen wowScreen, DataFrame[] frames)
bitmap = new(rect.Right, rect.Bottom, PixelFormat.Format32bppRgb);

IntPtr hMonitor = MonitorFromWindow(wowScreen.ProcessHwnd, MONITOR_DEFAULT_TO_NULL);

Result result;

IDXGIFactory1 factory = DXGI.CreateDXGIFactory1<IDXGIFactory1>();
result = factory.EnumAdapters(0, out adapter);
if (result == Result.Fail)
Expand All @@ -86,13 +82,11 @@ public AddonDataProviderDXGI(WowScreen wowScreen, DataFrame[] frames)
} while (result != Result.Fail);

output1 = output.QueryInterface<IDXGIOutput1>();
result = D3D11.D3D11CreateDevice(adapter, DriverType.Unknown, DeviceCreationFlags.None, s_featureLevels, out device!);
result = D3D11.D3D11CreateDevice(adapter, DriverType.Unknown, DeviceCreationFlags.Singlethreaded, s_featureLevels, out device!);

if (result == Result.Fail)
throw new Exception($"device is null {result.Description}");

bounds = output1.Description.DesktopCoordinates;

duplication = output1.DuplicateOutput(device);

Texture2DDescription textureDesc = new()
Expand Down Expand Up @@ -120,13 +114,13 @@ public void Dispose()
{
duplication.ReleaseFrame();
duplication.Dispose();

addonTexture.Dispose();
device.Dispose();

adapter.Dispose();
output1.Dispose();
output.Dispose();

addonTexture.Dispose();
bitmap.Dispose();
}

Expand Down Expand Up @@ -154,12 +148,13 @@ public void Update()
ID3D11Texture2D texture = desktopResource.QueryInterface<ID3D11Texture2D>();

Box box = new(p.X, p.Y, 0, p.X + rect.Right, p.Y + rect.Bottom, 1);

device.ImmediateContext.CopySubresourceRegion(addonTexture, 0, 0, 0, 0, texture, 0, box);

MappedSubresource dataBox = device.ImmediateContext.Map(addonTexture, 0, MapMode.Read, Vortice.Direct3D11.MapFlags.None);
int sizeInBytesToCopy = (rect.Right - rect.Left) * AddonDataProviderConfig.BYTES_PER_PIXEL;

BitmapData bd = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
BitmapData bd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
for (int y = 0; y < rect.Bottom; y++)
{
MemoryHelpers.CopyMemory(bd.Scan0 + y * bd.Stride, dataBox.DataPointer + y * dataBox.RowPitch, sizeInBytesToCopy);
Expand Down
4 changes: 2 additions & 2 deletions Core/AddonDataProvider/AddonDataProviderGDI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ public sealed class AddonDataProviderGDI : IAddonDataProvider
private readonly Bitmap bitmap;
private readonly Graphics graphics;

private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;

private readonly bool windowedMode;
private Point p;

public AddonDataProviderGDI(WowScreen wowScreen, DataFrame[] frames)
public AddonDataProviderGDI(IWowScreen wowScreen, DataFrame[] frames)
{
this.wowScreen = wowScreen;
this.frames = frames;
Expand Down
4 changes: 2 additions & 2 deletions Core/AddonDataProvider/AddonDataProviderGDIConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public sealed class AddonDataProviderGDIConfig : IAddonDataProvider

private readonly CancellationToken ct;
private readonly ManualResetEventSlim manualReset = new(true);
private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;

private DataFrame[] frames = Array.Empty<DataFrame>();

Expand All @@ -25,7 +25,7 @@ public sealed class AddonDataProviderGDIConfig : IAddonDataProvider

private bool disposing;

public AddonDataProviderGDIConfig(CancellationTokenSource cts, WowScreen wowScreen, DataFrame[] frames)
public AddonDataProviderGDIConfig(CancellationTokenSource cts, IWowScreen wowScreen, DataFrame[] frames)
{
ct = cts.Token;
this.wowScreen = wowScreen;
Expand Down
4 changes: 2 additions & 2 deletions Core/BotController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public sealed partial class BotController : IBotController, IDisposable
private readonly AddonReader addonReader;
private readonly AddonBits bits;
private readonly PlayerReader playerReader;
private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;

public bool IsBotActive => GoapAgent != null && GoapAgent.Active;

Expand Down Expand Up @@ -61,7 +61,7 @@ public BotController(
ILogger<BotController> logger,
CancellationTokenSource cts,
IPPather pather, DataConfig dataConfig,
WowScreen wowScreen,
IWowScreen wowScreen,
NpcNameFinder npcNameFinder,
INpcResetEvent npcResetEvent,
PlayerReader playerReader, AddonReader addonReader,
Expand Down
4 changes: 2 additions & 2 deletions Core/Configurator/FrameConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private enum Stage

private readonly ILogger<FrameConfigurator> logger;
private readonly WowProcess wowProcess;
private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;
private readonly WowProcessInput wowProcessInput;
private readonly ExecGameCommand execGameCommand;
private readonly AddonConfigurator addonConfigurator;
Expand All @@ -61,7 +61,7 @@ private enum Stage

public FrameConfigurator(ILogger<FrameConfigurator> logger, Wait wait,
WowProcess wowProcess, IAddonDataProvider reader,
WowScreen wowScreen, WowProcessInput wowProcessInput,
IWowScreen wowScreen, WowProcessInput wowProcessInput,
ExecGameCommand execGameCommand, AddonConfigurator addonConfigurator)
{
this.logger = logger;
Expand Down
3 changes: 1 addition & 2 deletions Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="Vortice.Direct3D11" Version="2.1.41" />
</ItemGroup>

<ItemGroup>
Expand Down
29 changes: 24 additions & 5 deletions Core/DependencyInjection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ public static IServiceCollection AddStartupIoC(

s.ForwardSingleton<NpcNameFinder>(sp);
s.ForwardSingleton<IWowScreen>(sp);
s.ForwardSingleton<WowScreen>(sp);

s.ForwardSingleton<IPPather>(sp);
s.ForwardSingleton<ExecGameCommand>(sp);
Expand Down Expand Up @@ -202,8 +201,8 @@ public static IServiceCollection AddCoreBase(this IServiceCollection s)
s.AddSingleton<DataConfig>(x => DataConfig.Load(
x.GetRequiredService<StartupClientVersion>().Path));

s.ForwardSingleton<WowScreen, IBitmapProvider>();
s.ForwardSingleton<WowScreen, IWowScreen>();
s.ForwardSingleton<IWowScreen, IBitmapProvider>(
x => GetWoWScreen(x.GetRequiredService<IServiceProvider>()));

s.ForwardSingleton<WowProcessInput, IMouseInput>();

Expand Down Expand Up @@ -271,7 +270,7 @@ private static IScreenCapture GetScreenCapture(
var logger = sp.GetRequiredService<ILogger<ScreenCapture>>();
var dataConfig = sp.GetRequiredService<DataConfig>();
var cts = sp.GetRequiredService<CancellationTokenSource>();
var wowScreen = sp.GetRequiredService<WowScreen>();
var wowScreen = sp.GetRequiredService<IWowScreen>();

IScreenCapture value = spd.Value.Enabled
? new ScreenCapture(logger, dataConfig, cts, wowScreen)
Expand All @@ -286,7 +285,7 @@ private static IAddonDataProvider GetAddonDataProvider(
IServiceProvider sp, ILogger log)
{
var scr = sp.GetRequiredService<IOptions<StartupConfigReader>>();
var wowScreen = sp.GetRequiredService<WowScreen>();
var wowScreen = sp.GetRequiredService<IWowScreen>();
var frames = sp.GetRequiredService<DataFrame[]>();

IAddonDataProvider value = scr.Value.ReaderType switch
Expand Down Expand Up @@ -367,4 +366,24 @@ private static IPPather GetPather(IServiceProvider sp, ILogger logger)
return localApi;
}

private static IWowScreen GetWoWScreen(IServiceProvider sp)
{
var scr = sp.GetRequiredService<IOptions<StartupConfigReader>>();
var wowProcess = sp.GetRequiredService<WowProcess>();
var factory = sp.GetRequiredService<ILoggerFactory>();

IWowScreen value = scr.Value.ReaderType switch
{
AddonDataProviderType.GDIConfig or
AddonDataProviderType.GDI or
AddonDataProviderType.GDIBlit or
AddonDataProviderType.DXGI =>
new WowScreenGDI(factory.CreateLogger<WowScreenGDI>(), wowProcess),
//AddonDataProviderType.DXGI =>
// new WowScreenDXGI(factory.CreateLogger<WowScreenDXGI>(), wowProcess),
_ => throw new NotImplementedException(),
};

return value;
}
}
4 changes: 2 additions & 2 deletions Core/Minimap/MinimapNodeFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ public PixelPoint(int x, int y)
private const bool DEBUG_MASK = false;

private readonly ILogger logger;
private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;
public event EventHandler<MinimapNodeEventArgs>? NodeEvent;

private const int minScore = 2;
private const byte maxBlue = 34;
private const byte minRedGreen = 176;

public MinimapNodeFinder(ILogger logger, WowScreen wowScreen)
public MinimapNodeFinder(ILogger logger, IWowScreen wowScreen)
{
this.logger = logger;
this.wowScreen = wowScreen;
Expand Down
4 changes: 2 additions & 2 deletions Core/ScreenCapture/ScreenCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public sealed partial class ScreenCapture : ScreenCaptureCleaner, IDisposable
{
private readonly ILogger<ScreenCapture> logger;
private readonly DataConfig dataConfig;
private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;
private readonly CancellationToken token;

private readonly ManualResetEventSlim manualReset;
Expand All @@ -24,7 +24,7 @@ public sealed partial class ScreenCapture : ScreenCaptureCleaner, IDisposable
private readonly Graphics graphics;

public ScreenCapture(ILogger<ScreenCapture> logger, DataConfig dataConfig,
CancellationTokenSource cts, WowScreen wowScreen)
CancellationTokenSource cts, IWowScreen wowScreen)
: base(logger, dataConfig)
{
this.logger = logger;
Expand Down
4 changes: 2 additions & 2 deletions CoreTests/Input/Test_Input.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Test_Input : IDisposable

private readonly ILogger logger;
private readonly WowProcess wowProcess;
private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;
private readonly WowProcessInput wowProcessInput;

public Test_Input(ILogger logger, ILoggerFactory loggerFactory)
Expand All @@ -23,7 +23,7 @@ public Test_Input(ILogger logger, ILoggerFactory loggerFactory)
this.cts = new();

wowProcess = new WowProcess();
wowScreen = new(loggerFactory.CreateLogger<WowScreen>(), wowProcess);
wowScreen = new WowScreenGDI(loggerFactory.CreateLogger<WowScreenGDI>(), wowProcess);
wowProcessInput = new(loggerFactory.CreateLogger<WowProcessInput>(), cts, wowProcess);
}

Expand Down
4 changes: 2 additions & 2 deletions CoreTests/MinimapNodeFinder/Test_MinimapNodeFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal sealed class Test_MinimapNodeFinder : IDisposable
private readonly ILogger logger;

private readonly WowProcess wowProcess;
private readonly WowScreen wowScreen;
private readonly IWowScreen wowScreen;

private readonly MinimapNodeFinder minimapNodeFinder;

Expand All @@ -33,7 +33,7 @@ public Test_MinimapNodeFinder(ILogger logger, ILoggerFactory loggerFactory)
this.logger = logger;

wowProcess = new();
wowScreen = new(loggerFactory.CreateLogger<WowScreen>(), wowProcess);
wowScreen = new WowScreenGDI(loggerFactory.CreateLogger<WowScreenGDI>(), wowProcess);

minimapNodeFinder = new(logger, wowScreen);
}
Expand Down
2 changes: 1 addition & 1 deletion CoreTests/NpcNameFinder/MockMouseOverReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace CoreTests;

public class MockMouseOverReader : IMouseOverReader
internal sealed class MockMouseOverReader : IMouseOverReader
{
public int MouseOverLevel => throw new System.NotImplementedException();

Expand Down
2 changes: 1 addition & 1 deletion CoreTests/NpcNameFinder/MockWoWProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace CoreTests;

public class MockWoWProcess : IMouseInput
internal sealed class MockWoWProcess : IMouseInput
{
public void RightClick(Point p)
{
Expand Down
34 changes: 33 additions & 1 deletion CoreTests/NpcNameFinder/MockWoWScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,28 @@

namespace CoreTests;

public class MockWoWScreen : IWowScreen
internal sealed class MockWoWScreen : IWowScreen
{
public bool Enabled { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

public Bitmap Bitmap => throw new NotImplementedException();

public Rectangle Rect => throw new NotImplementedException();

public nint ProcessHwnd => throw new NotImplementedException();

public Bitmap MiniMapBitmap => throw new NotImplementedException();

public Rectangle MiniMapRect => throw new NotImplementedException();

public bool EnablePostProcess { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

#pragma warning disable CS0414 // The field 'MockWoWScreen.OnScreenChanged' is assigned but its value is never used
#pragma warning disable CS8632 // The field 'MockWoWScreen.OnScreenChanged' is assigned but its value is never used
public event Action OnScreenChanged;
#pragma warning restore CS8632 // The field 'MockWoWScreen.OnScreenChanged' is assigned but its value is never used
#pragma warning restore CS0414 // The field 'MockWoWScreen.OnScreenChanged' is assigned but its value is never used

public void AddDrawAction(Action<Graphics> g)
{
throw new NotImplementedException();
Expand All @@ -36,4 +50,22 @@ public void GetRectangle(out Rectangle rect)
{
throw new NotImplementedException();
}

public void Update() { }

public void UpdateMinimapBitmap() { }

public void Dispose()
{
}

public void DrawBitmapTo(Graphics g)
{
throw new NotImplementedException();
}

public void PostProcess()
{
throw new NotImplementedException();
}
}
Loading

0 comments on commit ba069d5

Please sign in to comment.