Refactor and Optimize Client
This commit is contained in:
parent
23876dfdea
commit
33995fb87a
|
@ -1,17 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using SCHALE.GameServer.Services;
|
|
||||||
|
|
||||||
namespace SCHALE.GameClient.Controllers
|
|
||||||
{
|
|
||||||
public class ClientController : Controller
|
|
||||||
{
|
|
||||||
private readonly ILogger<ClientController> _logger;
|
|
||||||
private readonly PrivateClientService _privateClientService;
|
|
||||||
|
|
||||||
public ClientController(ILogger<ClientController> logger, PrivateClientService privateClientService)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_privateClientService = privateClientService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +1,156 @@
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
||||||
using Newtonsoft.Json;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using MX.Core.Crypto;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using SCHALE.Common.Crypto;
|
||||||
|
using SCHALE.Common.Crypto.XXHash;
|
||||||
|
using SCHALE.Common.FlatData;
|
||||||
using SCHALE.Common.NetworkProtocol;
|
using SCHALE.Common.NetworkProtocol;
|
||||||
using SCHALE.GameServer.Services;
|
using SCHALE.GameServer.Utils;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace SCHALE.GameServer
|
namespace SCHALE.GameServer.Services
|
||||||
{
|
{
|
||||||
public class GameServer
|
public class GameClient
|
||||||
{
|
{
|
||||||
public static async Task Main(string[] args)
|
private readonly HttpClient httpClient;
|
||||||
|
|
||||||
|
public static readonly string PS_URL = "http://10.0.0.149/api/gateway";
|
||||||
|
public static readonly string MITM_URL = "http://10.0.0.149:8080";
|
||||||
|
public static readonly string OFFICIAL_API_URL = "https://prod-game.bluearchiveyostar.com:5000/api/gateway";
|
||||||
|
|
||||||
|
private long AccountServerId = -1;
|
||||||
|
private string MxToken = "";
|
||||||
|
private long Hash = 0;
|
||||||
|
|
||||||
|
public GameClient()
|
||||||
{
|
{
|
||||||
var config = new ConfigurationBuilder()
|
|
||||||
.SetBasePath(Path.GetDirectoryName(AppContext.BaseDirectory)!)
|
|
||||||
.AddJsonFile("appsettings.json")
|
|
||||||
.AddJsonFile(
|
|
||||||
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json",
|
|
||||||
true
|
|
||||||
)
|
|
||||||
.AddJsonFile("appsettings.Local.json", true)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
{
|
|
||||||
var logFilePath = Path.Combine(
|
|
||||||
Path.GetDirectoryName(AppContext.BaseDirectory)!,
|
|
||||||
"logs",
|
|
||||||
"log.txt"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (File.Exists(logFilePath))
|
|
||||||
{
|
|
||||||
var prevLogFilePath = Path.Combine(
|
|
||||||
Path.GetDirectoryName(logFilePath)!,
|
|
||||||
"log-prev.txt"
|
|
||||||
);
|
|
||||||
if (File.Exists(prevLogFilePath))
|
|
||||||
File.Delete(prevLogFilePath);
|
|
||||||
|
|
||||||
File.Move(logFilePath, prevLogFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
Log.Logger = new LoggerConfiguration()
|
||||||
.WriteTo.Console()
|
.WriteTo.Console()
|
||||||
.WriteTo.File(
|
.WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
|
||||||
logFilePath,
|
.CreateLogger();
|
||||||
restrictedToMinimumLevel: LogEventLevel.Verbose,
|
|
||||||
shared: true
|
Log.Information("Application starting up...");
|
||||||
)
|
|
||||||
.ReadFrom.Configuration(config)
|
httpClient = new HttpClient();
|
||||||
.CreateBootstrapLogger();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Information("Starting...");
|
public static async Task Main(string[] args)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
GameClient gameClient = new GameClient();
|
||||||
|
|
||||||
builder.Services.Configure<KestrelServerOptions>(op =>
|
if (args.Length < 2 && (gameClient.AccountServerId == -1 || gameClient.MxToken == ""))
|
||||||
op.AllowSynchronousIO = true
|
|
||||||
);
|
|
||||||
builder.Host.UseSerilog();
|
|
||||||
|
|
||||||
// Add services to the container.
|
|
||||||
builder.Services.AddControllers();
|
|
||||||
|
|
||||||
builder.Services.AddHttpClient<PrivateClientService>();
|
|
||||||
builder.Services.AddSingleton<PrivateClientService>();
|
|
||||||
builder.Services.AddPrivateClientService();
|
|
||||||
|
|
||||||
var app = builder.Build();
|
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
|
||||||
app.UseAuthorization();
|
|
||||||
app.UseSerilogRequestLogging();
|
|
||||||
|
|
||||||
app.MapControllers();
|
|
||||||
|
|
||||||
app.Run();
|
|
||||||
} catch (Exception ex)
|
|
||||||
{
|
{
|
||||||
Log.Fatal(ex, "An unhandled exception occurred during runtime");
|
Log.Information("Please input the nessary data.");
|
||||||
} finally
|
return;
|
||||||
{
|
|
||||||
Log.CloseAndFlush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gameClient.AccountServerId == -1)
|
||||||
|
{
|
||||||
|
gameClient.AccountServerId = int.Parse(args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameClient.MxToken.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
gameClient.MxToken = args[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
await gameClient.SendPostRequestAsync(OFFICIAL_API_URL, new AcademyGetInfoRequest(){ });
|
||||||
|
/*
|
||||||
|
await gameClient.SendPostRequestAsync(OFFICIAL_API_URL, new ShopBuyGacha3Request()
|
||||||
|
{
|
||||||
|
FreeRecruitId = 0,
|
||||||
|
Cost = new()
|
||||||
|
{
|
||||||
|
ParcelInfos = [
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Key = new()
|
||||||
|
{
|
||||||
|
Type = ParcelType.Currency,
|
||||||
|
Id = 4,
|
||||||
|
},
|
||||||
|
Amount = 120,
|
||||||
|
Multiplier = new(10000),
|
||||||
|
Probability = new(10000)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
Currency = new()
|
||||||
|
{
|
||||||
|
currencyValue = new()
|
||||||
|
{
|
||||||
|
Values = new()
|
||||||
|
{
|
||||||
|
{ CurrencyTypes.Gem, 120 }
|
||||||
|
},
|
||||||
|
Tickets = new() { },
|
||||||
|
Property = new() { },
|
||||||
|
Gem = 120,
|
||||||
|
IsEmpty = false
|
||||||
|
},
|
||||||
|
|
||||||
|
Gold = 0,
|
||||||
|
Gem = 120,
|
||||||
|
|
||||||
|
},
|
||||||
|
EquipmentDBs = [],
|
||||||
|
ItemDBs = [],
|
||||||
|
FurnitureDBs = [],
|
||||||
|
ConsumeCondition = 0,
|
||||||
|
},
|
||||||
|
GoodsId = 35840,
|
||||||
|
ShopUniqueId = 50668,
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SendPostRequestAsync<T>(string url, T requestPacket) where T : RequestPacket
|
||||||
|
{
|
||||||
|
requestPacket.SessionKey = new()
|
||||||
|
{
|
||||||
|
MxToken = this.MxToken,
|
||||||
|
AccountServerId = this.AccountServerId,
|
||||||
|
};
|
||||||
|
|
||||||
|
requestPacket.Hash = this.Hash;
|
||||||
|
requestPacket.Resendable = true;
|
||||||
|
requestPacket.ClientUpTime = 0;
|
||||||
|
requestPacket.IsTest = false;
|
||||||
|
|
||||||
|
string packetJsonStr = JsonSerializer.Serialize((T)requestPacket);
|
||||||
|
|
||||||
|
Log.Information("Sending Post Request to " + url);
|
||||||
|
Log.Information($"Payload: {packetJsonStr}");
|
||||||
|
|
||||||
|
byte[] payload = PacketCryptManager.Instance.RequestToBinary(requestPacket.Protocol, packetJsonStr);
|
||||||
|
|
||||||
|
//File.WriteAllBytes("./mx.dat", payload);
|
||||||
|
Log.Information("Written All Bytes");
|
||||||
|
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
||||||
|
request.Headers.Add("mx", "1");
|
||||||
|
request.Headers.Add("Bundle-Version", "li3pmyogha");
|
||||||
|
|
||||||
|
var content = new MultipartFormDataContent();
|
||||||
|
content.Add(new StreamContent(new MemoryStream(payload)), "mx", ".mx.dat");
|
||||||
|
request.Content = content;
|
||||||
|
|
||||||
|
Log.Information("Sending POST Request!");
|
||||||
|
var response = await httpClient.SendAsync(request);
|
||||||
|
|
||||||
|
// Response
|
||||||
|
Log.Information("Response Details:");
|
||||||
|
Log.Information($"Status Code: {response.StatusCode}");
|
||||||
|
string responseBody = await response.Content.ReadAsStringAsync();
|
||||||
|
Log.Information("Response Body:");
|
||||||
|
Log.Information(responseBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:22994",
|
|
||||||
"sslPort": 44306
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"http": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": true,
|
|
||||||
"applicationUrl": "http://localhost:5141",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"https": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": true,
|
|
||||||
"applicationUrl": "https://localhost:7267;http://localhost:5141",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,10 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1,161 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
|
|
||||||
using MX.Core.Crypto;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using SCHALE.Common.Crypto;
|
|
||||||
using SCHALE.Common.Crypto.XXHash;
|
|
||||||
using SCHALE.Common.FlatData;
|
|
||||||
using SCHALE.Common.NetworkProtocol;
|
|
||||||
using SCHALE.GameServer.Utils;
|
|
||||||
using Serilog;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace SCHALE.GameServer.Services
|
|
||||||
{
|
|
||||||
public class PrivateClientService : BackgroundService
|
|
||||||
{
|
|
||||||
private readonly HttpClient _httpClient;
|
|
||||||
|
|
||||||
public static readonly string PS_URL = "http://10.0.0.149/api/gateway";
|
|
||||||
public static readonly string MITM_URL = "http://10.0.0.149:8080";
|
|
||||||
public static readonly string OFFICIAL_API_URL = "http://prod-gateway.bluearchiveyostar.com:5100/api/";
|
|
||||||
|
|
||||||
private readonly long AccountServerId = -1;
|
|
||||||
private readonly string MxToken = "";
|
|
||||||
private readonly long Hash = 0;
|
|
||||||
|
|
||||||
public PrivateClientService(HttpClient httpClient)
|
|
||||||
{
|
|
||||||
_httpClient = httpClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
||||||
{
|
|
||||||
//await SendPostRequestAsync(OFFICIAL_API_URL, new AcademyGetInfoRequest(){ });
|
|
||||||
|
|
||||||
await SendPostRequestAsync(OFFICIAL_API_URL, new ShopBuyGacha3Request()
|
|
||||||
{
|
|
||||||
FreeRecruitId = 0,
|
|
||||||
Cost = new()
|
|
||||||
{
|
|
||||||
ParcelInfos = [
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Key = new()
|
|
||||||
{
|
|
||||||
Type = ParcelType.Currency,
|
|
||||||
Id = 4,
|
|
||||||
},
|
|
||||||
Amount = 120,
|
|
||||||
Multiplier = new(10000),
|
|
||||||
Probability = new(10000)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
Currency = new()
|
|
||||||
{
|
|
||||||
currencyValue = new()
|
|
||||||
{
|
|
||||||
Values = new()
|
|
||||||
{
|
|
||||||
{ CurrencyTypes.Gem, 120 }
|
|
||||||
},
|
|
||||||
Tickets = new() { },
|
|
||||||
Property = new() { },
|
|
||||||
Gem = 120,
|
|
||||||
IsEmpty = false
|
|
||||||
},
|
|
||||||
|
|
||||||
Gold = 0,
|
|
||||||
Gem = 120,
|
|
||||||
|
|
||||||
},
|
|
||||||
EquipmentDBs = [],
|
|
||||||
ItemDBs = [],
|
|
||||||
FurnitureDBs = [],
|
|
||||||
ConsumeCondition = 0,
|
|
||||||
},
|
|
||||||
GoodsId = 35840,
|
|
||||||
ShopUniqueId = 50668,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SendPostRequestAsync<T>(string url, T requestPacket) where T : RequestPacket
|
|
||||||
{
|
|
||||||
requestPacket.SessionKey = new()
|
|
||||||
{
|
|
||||||
MxToken = this.MxToken,
|
|
||||||
AccountServerId = this.AccountServerId,
|
|
||||||
};
|
|
||||||
|
|
||||||
requestPacket.Hash = this.Hash;
|
|
||||||
requestPacket.Resendable = true;
|
|
||||||
requestPacket.ClientUpTime = 0;
|
|
||||||
requestPacket.IsTest = false;
|
|
||||||
|
|
||||||
string packetJsonStr = JsonSerializer.Serialize((T)requestPacket);
|
|
||||||
|
|
||||||
Log.Information("Sending Post Request to " + url);
|
|
||||||
Log.Information($"Payload: {packetJsonStr}");
|
|
||||||
|
|
||||||
byte[] payload = PacketCryptManager.Instance.RequestToBinary(requestPacket.Protocol, packetJsonStr);
|
|
||||||
|
|
||||||
File.WriteAllBytes("./mx.dat", payload);
|
|
||||||
Log.Information("Writeen All Bytes");
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
using var fileStream = new FileStream("./mx.dat", FileMode.Create, FileAccess.Write);
|
|
||||||
using var binaryWriterFile = new BinaryWriter(fileStream);
|
|
||||||
|
|
||||||
binaryWriterFile.Write(payload);
|
|
||||||
|
|
||||||
var mxFile = new StreamContent(binaryWriterFile.BaseStream);
|
|
||||||
|
|
||||||
mxFile.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
|
|
||||||
|
|
||||||
// Add the in-memory content as a file with a name
|
|
||||||
var boundary = "BestHTTP_HTTPMultiPartForm_328B5160";
|
|
||||||
using var content = new MultipartFormDataContent(boundary);
|
|
||||||
|
|
||||||
content.Add(mxFile, "mx", "1");
|
|
||||||
|
|
||||||
content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
|
|
||||||
content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", boundary));
|
|
||||||
|
|
||||||
// Set up custom headers to match the request shown
|
|
||||||
_httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
|
|
||||||
_httpClient.DefaultRequestHeaders.Add("Bundle-Version", "li3pmyogha");
|
|
||||||
_httpClient.DefaultRequestHeaders.Connection.Add("Keep-Alive");
|
|
||||||
_httpClient.DefaultRequestHeaders.Connection.Add("TE");
|
|
||||||
_httpClient.DefaultRequestHeaders.Add("Keep-Alive", "timeout=21");
|
|
||||||
//_httpClient.DefaultRequestHeaders.Add("TE", "identity");
|
|
||||||
_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("BestHTTP/2 v2.4.0");
|
|
||||||
|
|
||||||
|
|
||||||
// Send the POST request
|
|
||||||
HttpResponseMessage response = await _httpClient.PostAsync(url, content);
|
|
||||||
|
|
||||||
if (response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
string responseData = await response.Content.ReadAsStringAsync();
|
|
||||||
Log.Information("Success: " + responseData);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.Information($"Error: {response.StatusCode}");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static class PrivateClientServiceExtensions
|
|
||||||
{
|
|
||||||
public static void AddPrivateClientService(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddHostedService<PrivateClientService>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"Serilog": {
|
|
||||||
"MinimumLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Override": {
|
|
||||||
"Microsoft": "Warning",
|
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"AllowedHosts": "*"
|
|
||||||
}
|
|
|
@ -7,7 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SCHALE.GameServer", "SCHALE
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SCHALE.Common", "SCHALE.Common\SCHALE.Common.csproj", "{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SCHALE.Common", "SCHALE.Common\SCHALE.Common.csproj", "{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SCHALE.GameClient", "SCHALE.GameClient\SCHALE.GameClient.csproj", "{EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SCHALE.GameClient", "SCHALE.GameClient\SCHALE.GameClient.csproj", "{27F99AC7-2101-48F3-AF4E-8AC1AA78FB32}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -23,10 +23,10 @@ Global
|
||||||
{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D8ED8CB5-EA39-46BE-9236-7FC1F46FE15B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{27F99AC7-2101-48F3-AF4E-8AC1AA78FB32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{27F99AC7-2101-48F3-AF4E-8AC1AA78FB32}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{27F99AC7-2101-48F3-AF4E-8AC1AA78FB32}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{EBA95AE2-BBCA-4386-ADB3-FC6EC2102E88}.Release|Any CPU.Build.0 = Release|Any CPU
|
{27F99AC7-2101-48F3-AF4E-8AC1AA78FB32}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
Loading…
Reference in New Issue