mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Cleaned up resources
Fixed pipe server keeping Artemis from shutting down Pipe server no longer quietly fails (should hopefully give some insight on Overwatch issues) Added UT folder selection and auto-detection
This commit is contained in:
parent
63b0b1d8e5
commit
aa10b20759
@ -629,10 +629,12 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Modules\Games\UnrealTournament\Resources\ut-plugin.zip" />
|
||||
<None Include="Modules\Games\UnrealTournament\UnrealTournament.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>UnrealTournament.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<EmbeddedResource Include="Modules\Games\Witcher3\Resources\witcher3-mod.zip" />
|
||||
<None Include="Modules\Games\WorldofWarcraft\WoW.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>WoW.Designer.cs</LastGenOutput>
|
||||
@ -716,7 +718,6 @@
|
||||
<Resource Include="Resources\Keyboards\blackwidow.png" />
|
||||
<None Include="Resources\Keyboards\none.png" />
|
||||
<None Include="Resources\Keyboards\demo-gif.gif" />
|
||||
<EmbeddedResource Include="Resources\Witcher3\Witcher3Artemis.zip" />
|
||||
<None Include="Settings\Offsets.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Offsets.Designer.cs</LastGenOutput>
|
||||
|
||||
@ -25,8 +25,8 @@ namespace Artemis.Managers
|
||||
private readonly IEventAggregator _events;
|
||||
private readonly Timer _processTimer;
|
||||
|
||||
public MainManager(IEventAggregator events, ILogger logger, LoopManager loopManager,
|
||||
DeviceManager deviceManager, EffectManager effectManager, ProfileManager profileManager)
|
||||
public MainManager(IEventAggregator events, ILogger logger, LoopManager loopManager, DeviceManager deviceManager,
|
||||
EffectManager effectManager, ProfileManager profileManager, PipeServer pipeServer)
|
||||
{
|
||||
_events = events;
|
||||
|
||||
@ -35,6 +35,7 @@ namespace Artemis.Managers
|
||||
DeviceManager = deviceManager;
|
||||
EffectManager = effectManager;
|
||||
ProfileManager = profileManager;
|
||||
PipeServer = pipeServer;
|
||||
|
||||
_processTimer = new Timer(1000);
|
||||
_processTimer.Elapsed += ScanProcesses;
|
||||
@ -48,7 +49,6 @@ namespace Artemis.Managers
|
||||
GameStateWebServer.Start();
|
||||
|
||||
// Start the named pipe
|
||||
PipeServer = new PipeServer();
|
||||
PipeServer.Start("artemis");
|
||||
|
||||
Logger.Info("Intialized MainManager");
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition />
|
||||
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||
<Label FontSize="20" HorizontalAlignment="Left">
|
||||
<Label.Content>
|
||||
@ -35,6 +35,7 @@
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Game directory -->
|
||||
<StackPanel Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||
|
||||
Binary file not shown.
@ -9,16 +9,20 @@ namespace Artemis.Modules.Games.UnrealTournament
|
||||
Load();
|
||||
}
|
||||
|
||||
public string GameDirectory { get; set; }
|
||||
|
||||
public sealed override void Load()
|
||||
{
|
||||
Enabled = UnrealTournament.Default.Enabled;
|
||||
LastProfile = UnrealTournament.Default.LastProfile;
|
||||
GameDirectory = UnrealTournament.Default.GameDirectory;
|
||||
}
|
||||
|
||||
public sealed override void Save()
|
||||
{
|
||||
UnrealTournament.Default.Enabled = Enabled;
|
||||
UnrealTournament.Default.LastProfile = LastProfile;
|
||||
UnrealTournament.Default.GameDirectory = GameDirectory;
|
||||
|
||||
UnrealTournament.Default.Save();
|
||||
}
|
||||
@ -26,6 +30,7 @@ namespace Artemis.Modules.Games.UnrealTournament
|
||||
public sealed override void ToDefault()
|
||||
{
|
||||
Enabled = true;
|
||||
GameDirectory = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,15 +15,12 @@
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||
<Label FontSize="20" HorizontalAlignment="Left">
|
||||
<Label.Content>
|
||||
@ -40,11 +37,27 @@
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Game directory -->
|
||||
<StackPanel Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||
|
||||
<Label FontSize="20" HorizontalAlignment="Left" Content="Unreal Tournament Directory" />
|
||||
<Grid>
|
||||
<TextBox x:Name="GameDirectory" Height="23" TextWrapping="Wrap" Margin="5,0,30,0"
|
||||
Text="{Binding Path=GameSettings.GameDirectory, Mode=TwoWay}"
|
||||
cal:Message.Attach="[Event LostFocus] = [Action PlaceFiles]" />
|
||||
<Button x:Name="BrowseDirectory" Content="..." RenderTransformOrigin="-0.039,-0.944"
|
||||
HorizontalAlignment="Right" Width="25"
|
||||
Style="{DynamicResource SquareButtonStyle}" Height="26" Margin="0,-2,0,0" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
|
||||
<!-- Profile editor -->
|
||||
<ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-30,0" />
|
||||
<ContentControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-30,0" />
|
||||
|
||||
<!-- Buttons -->
|
||||
<StackPanel Grid.Column="0" Grid.Row="9" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<StackPanel Grid.Column="0" Grid.Row="3" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100"
|
||||
Style="{DynamicResource SquareButtonStyle}" />
|
||||
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100"
|
||||
|
||||
@ -1,33 +1,116 @@
|
||||
using Artemis.InjectionFactories;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using Artemis.InjectionFactories;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.ViewModels.Abstract;
|
||||
using Caliburn.Micro;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Artemis.Modules.Games.UnrealTournament
|
||||
{
|
||||
public sealed class UnrealTournamentViewModel : GameViewModel
|
||||
{
|
||||
private string _versionText;
|
||||
|
||||
public UnrealTournamentViewModel(MainManager main, IEventAggregator events, IProfileEditorVmFactory pFactory)
|
||||
: base(main, new UnrealTournamentModel(main, new UnrealTournamentSettings()), events, pFactory)
|
||||
{
|
||||
DisplayName = "Unreal Tournament";
|
||||
|
||||
MainManager.EffectManager.EffectModels.Add(GameModel);
|
||||
}
|
||||
|
||||
public string VersionText
|
||||
{
|
||||
get { return _versionText; }
|
||||
set
|
||||
{
|
||||
if (value == _versionText) return;
|
||||
_versionText = value;
|
||||
NotifyOfPropertyChange(() => VersionText);
|
||||
}
|
||||
FindGame();
|
||||
}
|
||||
|
||||
public UnrealTournamentModel UnrealTournamentModel { get; set; }
|
||||
|
||||
public void FindGame()
|
||||
{
|
||||
var gameSettings = (UnrealTournamentSettings) GameSettings;
|
||||
// If already propertly set up, don't do anything
|
||||
if (gameSettings.GameDirectory != null && File.Exists(gameSettings.GameDirectory + "UE4-Win64-Shipping.exe"))
|
||||
return;
|
||||
|
||||
// Attempt to read the file
|
||||
if (!File.Exists(@"C:\ProgramData\Epic\UnrealEngineLauncher\LauncherInstalled.dat"))
|
||||
return;
|
||||
|
||||
var json =
|
||||
JsonConvert.DeserializeObject<JObject>(
|
||||
File.ReadAllText(@"C:\ProgramData\Epic\UnrealEngineLauncher\LauncherInstalled.dat"));
|
||||
var utEntry =
|
||||
json["InstallationList"].Children()
|
||||
.FirstOrDefault(c => c["AppName"].Value<string>() == "UnrealTournamentDev");
|
||||
if (utEntry == null)
|
||||
return;
|
||||
|
||||
var utDir = utEntry["InstallLocation"].Value<string>();
|
||||
// Use backslash in path for consistency
|
||||
utDir = utDir.Replace('/', '\\');
|
||||
|
||||
if (!File.Exists(utDir + @"\UE4-Win64-Shipping.exe"))
|
||||
return;
|
||||
|
||||
gameSettings.GameDirectory = utDir;
|
||||
gameSettings.Save();
|
||||
PlaceFiles();
|
||||
}
|
||||
|
||||
public void BrowseDirectory()
|
||||
{
|
||||
var dialog = new FolderBrowserDialog
|
||||
{
|
||||
SelectedPath = ((UnrealTournamentSettings) GameSettings).GameDirectory
|
||||
};
|
||||
var result = dialog.ShowDialog();
|
||||
if (result != DialogResult.OK)
|
||||
return;
|
||||
|
||||
((UnrealTournamentSettings) GameSettings).GameDirectory = dialog.SelectedPath;
|
||||
NotifyOfPropertyChange(() => GameSettings);
|
||||
GameSettings.Save();
|
||||
|
||||
PlaceFiles();
|
||||
}
|
||||
|
||||
public void PlaceFiles()
|
||||
{
|
||||
var path = ((UnrealTournamentSettings) GameSettings).GameDirectory;
|
||||
|
||||
if (!File.Exists(path + @"\UE4-Win64-Shipping.exe"))
|
||||
{
|
||||
DialogService.ShowErrorMessageBox("Please select a valid Unreal Tournament directory\n\n" +
|
||||
@"By default Unreal Tournament is in C:\Program Files\Epic Games\UnrealTournament");
|
||||
|
||||
((UnrealTournamentSettings) GameSettings).GameDirectory = string.Empty;
|
||||
NotifyOfPropertyChange(() => GameSettings);
|
||||
GameSettings.Save();
|
||||
|
||||
MainManager.Logger.Warn("Failed to install Unreal Tournament plugin in '{0}' (path not found)", path);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the ZIP from resources
|
||||
var stream = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream("Artemis.Modules.Games.UnrealTournament.Resources.ut-plugin.zip");
|
||||
if (stream == null)
|
||||
throw new FileNotFoundException("Couldn't load the UT plugin files from resources.");
|
||||
|
||||
var archive = new ZipArchive(stream);
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(path + @"\UnrealTournament\Plugins\Artemis");
|
||||
archive.ExtractToDirectory(path + @"\UnrealTournament\Plugins\Artemis", true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MainManager.Logger.Error(e, "Failed to install Unreal Tournament plugin in '{0}'", path);
|
||||
return;
|
||||
}
|
||||
|
||||
MainManager.Logger.Info("Installed Unreal Tournament plugin in '{0}'", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -50,7 +50,7 @@ namespace Artemis.Modules.Games.Witcher3
|
||||
|
||||
// Load the ZIP from resources
|
||||
var stream = Assembly.GetExecutingAssembly()
|
||||
.GetManifestResourceStream("Artemis.Resources.Witcher3.Witcher3Artemis.zip");
|
||||
.GetManifestResourceStream("Artemis.Modules.Games.Witcher3.Resources.witcher3-mod.zip");
|
||||
if (stream == null)
|
||||
throw new FileNotFoundException("Couldn't load the Witcher 3 mod files from resources.");
|
||||
var archive = new ZipArchive(stream);
|
||||
|
||||
14
Artemis/Artemis/Properties/Resources.Designer.cs
generated
14
Artemis/Artemis/Properties/Resources.Designer.cs
generated
@ -311,9 +311,19 @@ namespace Artemis.Properties {
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] Witcher3Artemis {
|
||||
internal static byte[] ut_plugin {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Witcher3Artemis", resourceCulture);
|
||||
object obj = ResourceManager.GetObject("ut_plugin", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] witcher3_mod {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("witcher3_mod", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,13 +178,16 @@
|
||||
<data name="demo_gif" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Keyboards\demo-gif.gif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Witcher3Artemis" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Witcher3\Witcher3Artemis.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="g810" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Keyboards\g810.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="generic" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\generic.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="ut_plugin" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Modules\Games\UnrealTournament\Resources\ut-plugin.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="witcher3_mod" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Modules\Games\Witcher3\Resources\witcher3-mod.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
||||
@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipes;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Ninject.Extensions.Logging;
|
||||
|
||||
namespace Artemis.Utilities.DataReaders
|
||||
{
|
||||
@ -13,80 +13,34 @@ namespace Artemis.Utilities.DataReaders
|
||||
|
||||
public class PipeServer
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private string _pipeName;
|
||||
|
||||
public bool Running { get; set; }
|
||||
private NamedPipeServerStream _pipeServer;
|
||||
public event DelegateMessage PipeMessage;
|
||||
|
||||
public PipeServer(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Start(string pipeName)
|
||||
{
|
||||
Running = true;
|
||||
_pipeName = pipeName;
|
||||
var task = new Task(PipeLoop);
|
||||
task.Start();
|
||||
|
||||
var security = new PipeSecurity();
|
||||
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
|
||||
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow));
|
||||
_pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254,
|
||||
PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 4096, 4096, security);
|
||||
_pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, _pipeServer);
|
||||
_logger.Info("Opened named pipe '{0}'", _pipeName);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Running = false;
|
||||
}
|
||||
|
||||
private void PipeLoop()
|
||||
{
|
||||
try
|
||||
{
|
||||
var security = new PipeSecurity();
|
||||
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
|
||||
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl,
|
||||
AccessControlType.Allow));
|
||||
|
||||
while (Running)
|
||||
{
|
||||
var namedPipeServerStream = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254,
|
||||
PipeTransmissionMode.Byte, PipeOptions.None, 4096, 4096, security);
|
||||
|
||||
namedPipeServerStream.WaitForConnection();
|
||||
var buffer = new byte[4096];
|
||||
namedPipeServerStream.Read(buffer, 0, 4096);
|
||||
namedPipeServerStream.Close();
|
||||
|
||||
var task = new Task(() => HandleMessage(buffer));
|
||||
task.Start();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMessage(byte[] buffer)
|
||||
{
|
||||
var request = Encoding.ASCII.GetString(buffer);
|
||||
PipeMessage?.Invoke(request);
|
||||
}
|
||||
|
||||
public void Listen(string pipeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var security = new PipeSecurity();
|
||||
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
|
||||
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow));
|
||||
|
||||
// Set to class level var so we can re-use in the async callback method
|
||||
_pipeName = pipeName;
|
||||
// Create the new async pipe
|
||||
var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte,
|
||||
PipeOptions.Asynchronous, 254, 254, security);
|
||||
|
||||
// Wait for a connection
|
||||
pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer);
|
||||
}
|
||||
catch (Exception oEx)
|
||||
{
|
||||
Debug.WriteLine(oEx.Message);
|
||||
}
|
||||
_pipeServer.Close();
|
||||
_pipeServer.Dispose();
|
||||
_logger.Info("Closed named pipe '{0}'", _pipeName);
|
||||
}
|
||||
|
||||
private void WaitForConnectionCallBack(IAsyncResult iar)
|
||||
@ -98,34 +52,39 @@ namespace Artemis.Utilities.DataReaders
|
||||
// End waiting for the connection
|
||||
pipeServer.EndWaitForConnection(iar);
|
||||
|
||||
var buffer = new byte[255];
|
||||
var buffer = new byte[4096];
|
||||
|
||||
// Read the incoming message
|
||||
pipeServer.Read(buffer, 0, 255);
|
||||
|
||||
// Convert byte buffer to string
|
||||
var stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
|
||||
var stringData = Encoding.ASCII.GetString(buffer, 0, buffer.Length);
|
||||
|
||||
// Pass message back to calling form
|
||||
PipeMessage?.Invoke(stringData);
|
||||
|
||||
// Kill original sever and create new wait server
|
||||
pipeServer.Close();
|
||||
|
||||
var security = new PipeSecurity();
|
||||
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
|
||||
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow));
|
||||
|
||||
pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte,
|
||||
PipeOptions.Asynchronous, 254, 254, security);
|
||||
pipeServer = GetPipeServer(_pipeName);
|
||||
|
||||
// Recursively wait for the connection again and again....
|
||||
_pipeServer = pipeServer;
|
||||
pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer);
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e, "Exception in named pipe '{0}'", _pipeName);
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private static NamedPipeServerStream GetPipeServer(string name)
|
||||
{
|
||||
var security = new PipeSecurity();
|
||||
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
|
||||
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow));
|
||||
return new NamedPipeServerStream(name, PipeDirection.In, 254, PipeTransmissionMode.Byte,
|
||||
PipeOptions.Asynchronous, 4096, 4096, security);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,12 +33,11 @@ namespace Artemis.Utilities
|
||||
foreach (var file in archive.Entries)
|
||||
{
|
||||
var completeFileName = Path.Combine(destinationDirectoryName, file.FullName);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(completeFileName));
|
||||
|
||||
if (file.Name == "")
|
||||
{
|
||||
// Assuming Empty for Directory
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(completeFileName));
|
||||
continue;
|
||||
}
|
||||
|
||||
file.ExtractToFile(completeFileName, true);
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Artemis/UnrealTournament2Artemis/ut-plugin.zip
Normal file
BIN
Artemis/UnrealTournament2Artemis/ut-plugin.zip
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user