Add stubs for online mathcing and writing
This commit is contained in:
parent
aefc9ca326
commit
7093997658
@ -22,9 +22,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Game\Card\OnlineMatching" />
|
||||
<Folder Include="Game\Card\Read" />
|
||||
<Folder Include="Game\Card\Write" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -0,0 +1,6 @@
|
||||
namespace Application.Game.Card.OnlineMatching;
|
||||
|
||||
public class StartOnlineMatchingCommand
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
namespace Application.Game.Card.OnlineMatching;
|
||||
|
||||
public class UpdateOnlineMatchingCommand
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
namespace Application.Game.Card.OnlineMatching;
|
||||
|
||||
public class UploadOnlineMatchingResultCommand
|
||||
{
|
||||
|
||||
}
|
17
Application/Game/Card/Write/WriteAvatarCommand.cs
Normal file
17
Application/Game/Card/Write/WriteAvatarCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteAvatarCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteAvatarCommandHandler : CardRequestHandlerBase<WriteAvatarCommand, string>
|
||||
{
|
||||
public WriteAvatarCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteAvatarCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
17
Application/Game/Card/Write/WriteCoinCommand.cs
Normal file
17
Application/Game/Card/Write/WriteCoinCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteCoinCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteCoinCommandHandler : CardRequestHandlerBase<WriteCoinCommand, string>
|
||||
{
|
||||
public WriteCoinCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteCoinCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
17
Application/Game/Card/Write/WriteItemCommand.cs
Normal file
17
Application/Game/Card/Write/WriteItemCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteItemCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteItemCommandHandler : CardRequestHandlerBase<WriteItemCommand, string>
|
||||
{
|
||||
public WriteItemCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteItemCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
17
Application/Game/Card/Write/WriteMusicDetailCommand.cs
Normal file
17
Application/Game/Card/Write/WriteMusicDetailCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteMusicDetailCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteMusicDetailCommandHandler : CardRequestHandlerBase<WriteMusicDetailCommand, string>
|
||||
{
|
||||
public WriteMusicDetailCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteMusicDetailCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
17
Application/Game/Card/Write/WriteNavigatorCommand.cs
Normal file
17
Application/Game/Card/Write/WriteNavigatorCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteNavigatorCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteNavigatorCommandHandler : CardRequestHandlerBase<WriteNavigatorCommand, string>
|
||||
{
|
||||
public WriteNavigatorCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteNavigatorCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
17
Application/Game/Card/Write/WriteSkinCommand.cs
Normal file
17
Application/Game/Card/Write/WriteSkinCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteSkinCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteSkinCommandHandler : CardRequestHandlerBase<WriteSkinCommand, string>
|
||||
{
|
||||
public WriteSkinCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteSkinCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
17
Application/Game/Card/Write/WriteSoundEffectCommand.cs
Normal file
17
Application/Game/Card/Write/WriteSoundEffectCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteSoundEffectCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteSoundEffectCommandHandler : CardRequestHandlerBase<WriteSoundEffectCommand, string>
|
||||
{
|
||||
public WriteSoundEffectCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteSoundEffectCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
17
Application/Game/Card/Write/WriteTitleCommand.cs
Normal file
17
Application/Game/Card/Write/WriteTitleCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteTitleCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteTitleCommandHandler : CardRequestHandlerBase<WriteTitleCommand, string>
|
||||
{
|
||||
public WriteTitleCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteTitleCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
17
Application/Game/Card/Write/WriteUnlockKeynumCommand.cs
Normal file
17
Application/Game/Card/Write/WriteUnlockKeynumCommand.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Application.Common.Models;
|
||||
using Application.Interfaces;
|
||||
|
||||
namespace Application.Game.Card.Write;
|
||||
|
||||
public record WriteUnlockKeynumCommand(long CardId, string Data) : IRequestWrapper<string>;
|
||||
|
||||
public class WriteUnlockKeynumCommandHandler : CardRequestHandlerBase<WriteUnlockKeynumCommand, string>
|
||||
{
|
||||
public WriteUnlockKeynumCommandHandler(ICardDependencyAggregate aggregate) : base(aggregate) {}
|
||||
|
||||
public override Task<ServiceResult<string>> Handle(WriteUnlockKeynumCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Add proper implementation
|
||||
return Task.FromResult(new ServiceResult<string>(request.Data));
|
||||
}
|
||||
}
|
@ -141,6 +141,14 @@ public static class Configs
|
||||
|
||||
public const int SCORE_PCOL1 = 21;
|
||||
|
||||
public const string MATCHING_URL_BASE = "Matching";
|
||||
|
||||
public const string START_MATCHING_URL = "Start";
|
||||
public const string UPDATE_MATCHING_URL = "Update";
|
||||
public const string FINISH_MATCHING_URL = "Finish";
|
||||
|
||||
|
||||
|
||||
public static readonly List<string> DOMAINS = new()
|
||||
{
|
||||
"localhost",
|
||||
@ -164,6 +172,8 @@ public static class Configs
|
||||
public const string DEFAULT_RELAY_SERVER = "127.0.0.1";
|
||||
public const int DEFAULT_RELAY_PORT = 54321;
|
||||
public const string DEFAULT_EVENT_FOLDER = "event";
|
||||
public const string DEFAULT_MATCHING_SERVER = "127.0.0.1:5000";
|
||||
|
||||
|
||||
public static readonly IReadOnlyList<int> DEFAULT_UNLOCKABLE_SONGS = new[]
|
||||
{
|
||||
|
61
GC-local-server-rewrite/common/Converters.cs
Normal file
61
GC-local-server-rewrite/common/Converters.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using GCLocalServerRewrite.models;
|
||||
using SharedProject.models;
|
||||
|
||||
namespace GCLocalServerRewrite.common;
|
||||
|
||||
public static class Converters
|
||||
{
|
||||
public static OnlineMatchingData ConvertFromEntry(OnlineMatchingEntry entry)
|
||||
{
|
||||
return new OnlineMatchingData
|
||||
{
|
||||
AvatarId = entry.AvatarId,
|
||||
CardId = entry.CardId,
|
||||
ClassId = entry.ClassId,
|
||||
EntryNo = entry.EntryNo,
|
||||
EntryStart = entry.EntryStart,
|
||||
EventId = entry.EventId,
|
||||
GroupId = entry.GroupId,
|
||||
MachineId = entry.MachineId,
|
||||
MatchingId = entry.MatchingId,
|
||||
MatchingRemainingTime = entry.MatchingRemainingTime,
|
||||
Pref = entry.Pref,
|
||||
Status = entry.Status,
|
||||
MatchingTimeout = entry.MatchingTimeout,
|
||||
MessageId = entry.MessageId,
|
||||
PlayerName = entry.PlayerName,
|
||||
PrefId = entry.PrefId,
|
||||
TenpoId = entry.TenpoId,
|
||||
TenpoName = entry.TenpoName,
|
||||
TitleId = entry.TitleId,
|
||||
MatchingWaitTime = entry.MatchingWaitTime
|
||||
};
|
||||
}
|
||||
|
||||
public static OnlineMatchingEntry ConvertFromData(OnlineMatchingData entry)
|
||||
{
|
||||
return new OnlineMatchingEntry
|
||||
{
|
||||
AvatarId = entry.AvatarId,
|
||||
CardId = entry.CardId,
|
||||
ClassId = entry.ClassId,
|
||||
EntryNo = entry.EntryNo,
|
||||
EntryStart = entry.EntryStart,
|
||||
EventId = entry.EventId,
|
||||
GroupId = entry.GroupId,
|
||||
MachineId = entry.MachineId,
|
||||
MatchingId = entry.MatchingId,
|
||||
MatchingRemainingTime = entry.MatchingRemainingTime,
|
||||
Pref = entry.Pref,
|
||||
Status = entry.Status,
|
||||
MatchingTimeout = entry.MatchingTimeout,
|
||||
MessageId = entry.MessageId,
|
||||
PlayerName = entry.PlayerName,
|
||||
PrefId = entry.PrefId,
|
||||
TenpoId = entry.TenpoId,
|
||||
TenpoName = entry.TenpoName,
|
||||
TitleId = entry.TitleId,
|
||||
MatchingWaitTime = entry.MatchingWaitTime
|
||||
};
|
||||
}
|
||||
}
|
@ -43,6 +43,9 @@ public interface IAppSettings
|
||||
[Option(DefaultValue = false)]
|
||||
bool DownloadEvents { get; }
|
||||
|
||||
[Option(DefaultValue = Configs.DEFAULT_MATCHING_SERVER)]
|
||||
string MatchingServer { get; }
|
||||
|
||||
[Option(DefaultValue = null)]
|
||||
IEnumerable<int>? UnlockableSongIds { get; }
|
||||
|
||||
|
@ -11,7 +11,8 @@
|
||||
"EventFolder": "event",
|
||||
"DownloadEvents": false,
|
||||
"RelayServer": "127.0.0.1",
|
||||
"RelayPort": 54321,
|
||||
"RelayPort": 3333,
|
||||
"MatchingServer": "127.0.0.1:5038",
|
||||
"UnlockableSongIds": [
|
||||
11,
|
||||
13,
|
||||
@ -68,7 +69,7 @@
|
||||
"FileName": "/event_103_20201125.evt",
|
||||
"NotBeforeUnixTime": 1335677127,
|
||||
"NotAfterUnixTime": 1966397127,
|
||||
"Md5": "9ef6c4d5ca381583a2d99b626ce06b5e",
|
||||
"Md5": "27b503145a62e46f5f611b6f8a91e4f3",
|
||||
"Index": 0
|
||||
},
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net.Http.Json;
|
||||
using System.Net.Mime;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
@ -8,9 +8,13 @@ using EmbedIO.Routing;
|
||||
using EmbedIO.WebApi;
|
||||
using GCLocalServerRewrite.common;
|
||||
using GCLocalServerRewrite.models;
|
||||
using SharedProject.models;
|
||||
using SQLite.Net2;
|
||||
using Swan;
|
||||
using Swan.Logging;
|
||||
using Avatar=GCLocalServerRewrite.models.Avatar;
|
||||
using Navigator=GCLocalServerRewrite.models.Navigator;
|
||||
using Title=GCLocalServerRewrite.models.Title;
|
||||
|
||||
namespace GCLocalServerRewrite.controllers;
|
||||
|
||||
@ -19,13 +23,6 @@ public class CardServiceController : WebApiController
|
||||
private readonly SQLiteConnection cardSqLiteConnection;
|
||||
private readonly SQLiteConnection musicSqLiteConnection;
|
||||
|
||||
private static readonly ConcurrentDictionary<long, List<OnlineMatchingEntry>> OnlineMatchingEntries = new()
|
||||
{
|
||||
[0xDEADBEEF] = new List<OnlineMatchingEntry>(),
|
||||
[0xCAFEBABE] = new List<OnlineMatchingEntry>(),
|
||||
[0xD0D0CACA] = new List<OnlineMatchingEntry>()
|
||||
};
|
||||
|
||||
public CardServiceController()
|
||||
{
|
||||
cardSqLiteConnection = DatabaseHelper.ConnectDatabase(Configs.SETTINGS.CardDbName);
|
||||
@ -34,17 +31,17 @@ public class CardServiceController : WebApiController
|
||||
|
||||
[Route(HttpVerbs.Post, "/cardn.cgi")]
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public string CardService([FormField] int gid, [FormField("mac_addr")] string mac, [FormField] int type,
|
||||
public async Task<string> CardService([FormField] int gid, [FormField("mac_addr")] string mac, [FormField] int type,
|
||||
[FormField("card_no")] long cardId, [FormField("data")] string xmlData, [FormField("cmd_str")] int cmdType)
|
||||
{
|
||||
HttpContext.Response.ContentType = MediaTypeNames.Application.Octet;
|
||||
HttpContext.Response.ContentEncoding = new UTF8Encoding(false);
|
||||
HttpContext.Response.KeepAlive = true;
|
||||
|
||||
return ProcessCommand(cmdType, mac, cardId, xmlData, type);
|
||||
return await ProcessCommand(cmdType, mac, cardId, xmlData, type);
|
||||
}
|
||||
|
||||
private string ProcessCommand(int cmdType, string mac, long cardId, string xmlData, int type)
|
||||
private async Task<string> ProcessCommand(int cmdType, string mac, long cardId, string xmlData, int type)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(Command), cmdType))
|
||||
{
|
||||
@ -55,7 +52,7 @@ public class CardServiceController : WebApiController
|
||||
|
||||
return command switch
|
||||
{
|
||||
Command.CardReadRequest or Command.CardWriteRequest => ProcessCardRequest(mac, cardId, xmlData, type),
|
||||
Command.CardReadRequest or Command.CardWriteRequest => await ProcessCardRequest(mac, cardId, xmlData, type),
|
||||
Command.ReissueRequest => ProcessReissueRequest(),
|
||||
Command.RegisterRequest => ProcessRegisterRequest(cardId, xmlData),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(command), command, "Command unknown, should never happen!")
|
||||
@ -75,7 +72,7 @@ public class CardServiceController : WebApiController
|
||||
return ConstructResponse("", ReturnCode.NotReissue);
|
||||
}
|
||||
|
||||
private string ProcessCardRequest(string mac, long cardId, string xmlData, int type)
|
||||
private async Task<string> ProcessCardRequest(string mac, long cardId, string xmlData, int type)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(CardRequestType), type))
|
||||
{
|
||||
@ -230,19 +227,22 @@ public class CardServiceController : WebApiController
|
||||
case CardRequestType.StartOnlineMatching:
|
||||
{
|
||||
$"Start Online Matching, data is {xmlData}".Info();
|
||||
return ConstructResponse(StartOnlineMatching(cardId, xmlData));
|
||||
var resultString = await StartOnlineMatching(cardId, xmlData);
|
||||
return ConstructResponse(resultString);
|
||||
}
|
||||
|
||||
case CardRequestType.UpdateOnlineMatching:
|
||||
{
|
||||
$"Update Online Matching, data is {xmlData}".Info();
|
||||
return ConstructResponse(UpdateOnlineMatching(cardId, xmlData));
|
||||
var resultString = await UpdateOnlineMatching(cardId, xmlData);
|
||||
return ConstructResponse(resultString);
|
||||
}
|
||||
|
||||
case CardRequestType.UploadOnlineMatchingResult:
|
||||
{
|
||||
$"Get Online Matching result, data is {xmlData}".Info();
|
||||
return ConstructResponse(UploadOnlineMatchingResult(cardId, xmlData));
|
||||
var resultString = await UploadOnlineMatchingResult(cardId, xmlData);
|
||||
return ConstructResponse(resultString);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -618,67 +618,98 @@ public class CardServiceController : WebApiController
|
||||
|
||||
#region OnlineMatchingImplementation
|
||||
|
||||
private static string StartOnlineMatching(long cardId, string xmlData)
|
||||
private static async Task<string> StartOnlineMatching(long cardId, string xmlData)
|
||||
{
|
||||
var reader = new ChoXmlReader<OnlineMatchingEntry>(new StringReader(xmlData)).WithXPath(Configs.DATA_XPATH);
|
||||
var entry = reader.Read();
|
||||
|
||||
entry.CardId = cardId;
|
||||
entry.MatchingId = 0xDEADBEEF;
|
||||
entry.EntryNo = OnlineMatchingEntries[0xDEADBEEF].Count;
|
||||
entry.EntryStart = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
entry.MatchingTimeout = 20;
|
||||
entry.MatchingRemainingTime = 3;
|
||||
entry.MatchingWaitTime = 10;
|
||||
entry.Status = 1;
|
||||
entry.Dump().Info();
|
||||
var entries = OnlineMatchingEntries[0xDEADBEEF];
|
||||
var existing = entries.Find(matchingEntry => matchingEntry.CardId == cardId);
|
||||
if (existing is not null)
|
||||
var request = Converters.ConvertFromEntry(entry) ;
|
||||
request.CardId = cardId;
|
||||
request.EntryStart = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
request.MatchingTimeout = 20;
|
||||
request.MatchingRemainingTime = 3;
|
||||
request.MatchingWaitTime = 10;
|
||||
request.Status = 1;
|
||||
|
||||
var client = new HttpClient();
|
||||
var url = $"http://{Configs.SETTINGS.MatchingServer}/{Configs.MATCHING_URL_BASE}/{Configs.START_MATCHING_URL}";
|
||||
try
|
||||
{
|
||||
"Card id already exist in entry! Previous match is not cleaned up! Clearing now".Warn();
|
||||
entries.Clear();
|
||||
var response = await client.PostAsJsonAsync(url, request);
|
||||
var dataList = await response.Content.ReadFromJsonAsync<List<OnlineMatchingData>>();
|
||||
if (dataList is null)
|
||||
{
|
||||
throw new HttpRequestException("Start matching request fail");
|
||||
}
|
||||
var result = dataList.ConvertAll(input => Converters.ConvertFromData(input));
|
||||
return GenerateRecordsXml(result, Configs.ONLINE_MATCHING_XPATH);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.Error("", "Http request failed");
|
||||
throw;
|
||||
}
|
||||
OnlineMatchingEntries[0xDEADBEEF].Add(entry);
|
||||
|
||||
return GenerateRecordsXml(OnlineMatchingEntries[0xDEADBEEF], Configs.ONLINE_MATCHING_XPATH);
|
||||
}
|
||||
|
||||
private static string UpdateOnlineMatching(long cardId, string xmlData)
|
||||
private static async Task<string> UpdateOnlineMatching(long cardId, string xmlData)
|
||||
{
|
||||
var reader = new ChoXmlReader<OnlineMatchingUpdateData>(new StringReader(xmlData));
|
||||
var data = reader.Read();
|
||||
var entries = OnlineMatchingEntries[0xDEADBEEF];
|
||||
var entry = entries.Find(matchingEntry => matchingEntry.CardId == cardId);
|
||||
if (entry is null)
|
||||
var request = new OnlineMatchingUpdateRequest
|
||||
{
|
||||
throw new HttpException(400,"Entry for this card id does not exist!");
|
||||
}
|
||||
if (data.Action != 0)
|
||||
Action = data.Action,
|
||||
CardId = cardId,
|
||||
EventId = data.EventId,
|
||||
MatchingId = data.MatchingId,
|
||||
MessageId = data.MessageId
|
||||
};
|
||||
var client = new HttpClient();
|
||||
var url = $"http://{Configs.SETTINGS.MatchingServer}/{Configs.MATCHING_URL_BASE}/{Configs.UPDATE_MATCHING_URL}";
|
||||
try
|
||||
{
|
||||
$"Action is {data.Action}".Info();
|
||||
var response = await client.PostAsJsonAsync(url, request);
|
||||
var dataList = await response.Content.ReadFromJsonAsync<List<OnlineMatchingEntry>>();
|
||||
if (dataList is null)
|
||||
{
|
||||
throw new HttpRequestException("Update matching request fail");
|
||||
}
|
||||
return GenerateRecordsXml(dataList, Configs.ONLINE_MATCHING_XPATH);
|
||||
}
|
||||
|
||||
entry.MessageId = data.MessageId;
|
||||
if (entry.MatchingRemainingTime <= 0)
|
||||
catch (Exception e)
|
||||
{
|
||||
entry.Status = 3;
|
||||
entry.Dump().Info();
|
||||
return GenerateRecordsXml(OnlineMatchingEntries[0xDEADBEEF], Configs.ONLINE_MATCHING_XPATH);
|
||||
e.Error("", "Http request failed");
|
||||
throw;
|
||||
}
|
||||
|
||||
entry.MatchingRemainingTime--;
|
||||
entry.Dump().Info();
|
||||
|
||||
return GenerateRecordsXml(OnlineMatchingEntries[0xDEADBEEF], Configs.ONLINE_MATCHING_XPATH);
|
||||
}
|
||||
|
||||
private static string UploadOnlineMatchingResult(long cardId, string xmlData)
|
||||
private static async Task<string> UploadOnlineMatchingResult(long cardId, string xmlData)
|
||||
{
|
||||
var reader = new ChoXmlReader<OnlineMatchingResultData>(new StringReader(xmlData));
|
||||
var data = reader.Read();
|
||||
|
||||
var entries = OnlineMatchingEntries[0xDEADBEEF];
|
||||
var request = new OnlineMatchingFinishRequest
|
||||
{
|
||||
CardId = cardId,
|
||||
MatchingId = data.MatchingId
|
||||
};
|
||||
var client = new HttpClient();
|
||||
var url = $"http://{Configs.SETTINGS.MatchingServer}/{Configs.MATCHING_URL_BASE}/{Configs.UPDATE_MATCHING_URL}";
|
||||
try
|
||||
{
|
||||
var response = await client.PostAsJsonAsync(url, request);
|
||||
var success = await response.Content.ReadFromJsonAsync<bool>();
|
||||
|
||||
var result = new OnlineMatchingResult
|
||||
{
|
||||
Status = success ? 1:0
|
||||
};
|
||||
return GenerateSingleXml(result, Configs.ONLINE_BATTLE_RESULT_XPATH);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.Error("", "Http request failed");
|
||||
throw;
|
||||
}
|
||||
/*var entries = OnlineMatchingEntries[0xDEADBEEF];
|
||||
var entry = entries.Find(matchingEntry => matchingEntry.CardId == cardId);
|
||||
if (entry is null)
|
||||
{
|
||||
@ -695,7 +726,7 @@ public class CardServiceController : WebApiController
|
||||
{
|
||||
Status = 1
|
||||
};
|
||||
return GenerateSingleXml(result, Configs.ONLINE_BATTLE_RESULT_XPATH);
|
||||
return GenerateSingleXml(result, Configs.ONLINE_BATTLE_RESULT_XPATH);*/
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
131
MatchServer/Controllers/MatchingController.cs
Normal file
131
MatchServer/Controllers/MatchingController.cs
Normal file
@ -0,0 +1,131 @@
|
||||
using MatchServer.Storage;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharedProject.models;
|
||||
|
||||
namespace MatchServer.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class MatchingController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<MatchingController> logger;
|
||||
|
||||
|
||||
public MatchingController(ILogger<MatchingController> logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
[HttpPost("Start")]
|
||||
public ActionResult<IEnumerable<OnlineMatchingData>> StartOnlineMatching(OnlineMatchingData startData)
|
||||
{
|
||||
logger.LogInformation("Start matching, card id {CardId}, player name {PlayerName}", startData.CardId, startData.PlayerName);
|
||||
var matchingDb = MatchingDb.GetInstance;
|
||||
|
||||
lock (matchingDb.DbLock)
|
||||
{
|
||||
foreach (var (matchingId, entries) in matchingDb.MatchingDictionary)
|
||||
{
|
||||
if (entries.Count >= 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entries.Any(data => data.CardId == startData.CardId))
|
||||
{
|
||||
logger.LogWarning("Card id {CardId} already exists in matching id {MatchingId}", startData.CardId, matchingId);
|
||||
continue;
|
||||
}
|
||||
|
||||
entries.Add(startData);
|
||||
startData.MatchingId = matchingId;
|
||||
startData.EntryNo = entries.Count - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (startData.MatchingId != 0)
|
||||
{
|
||||
return Ok(matchingDb.MatchingDictionary[startData.MatchingId]);
|
||||
}
|
||||
|
||||
startData.MatchingId = matchingDb.MatchingDictionary.Count + 1;
|
||||
startData.EntryNo = 0;
|
||||
matchingDb.MatchingDictionary[startData.MatchingId] = new List<OnlineMatchingData>
|
||||
{
|
||||
startData
|
||||
};
|
||||
|
||||
return Ok(matchingDb.MatchingDictionary[startData.MatchingId]);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("Update")]
|
||||
public ActionResult<IEnumerable<OnlineMatchingUpdateRequest>> UpdateOnlineMatching(OnlineMatchingUpdateRequest updateData)
|
||||
{
|
||||
var matchingDb = MatchingDb.GetInstance;
|
||||
var matchingId = updateData.MatchingId;
|
||||
|
||||
logger.LogInformation("Update matching, card id is {CardId}, matching id is {MatchingId}", updateData.CardId, updateData.MatchingId);
|
||||
|
||||
if (!matchingDb.MatchingDictionary.ContainsKey(matchingId))
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var dataList = matchingDb.MatchingDictionary[matchingId];
|
||||
|
||||
var data = dataList.Find(data => data.CardId == updateData.CardId);
|
||||
if (data is null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
data.MessageId = updateData.MessageId;
|
||||
if (data.MatchingRemainingTime <= 0)
|
||||
{
|
||||
data.Status = 3;
|
||||
return Ok(dataList);
|
||||
}
|
||||
|
||||
data.MatchingRemainingTime--;
|
||||
return Ok(dataList);
|
||||
}
|
||||
|
||||
[HttpPost("Finish")]
|
||||
public ActionResult<bool> FinishOnlineMatching(OnlineMatchingFinishRequest request)
|
||||
{
|
||||
var matchingDb = MatchingDb.GetInstance;
|
||||
var matchingId = request.MatchingId;
|
||||
|
||||
lock (matchingDb.DbLock)
|
||||
{
|
||||
if (!matchingDb.MatchingDictionary.ContainsKey(matchingId))
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
var dataList = matchingDb.MatchingDictionary[matchingId];
|
||||
|
||||
var index = dataList.FindIndex(data => data.CardId == request.CardId);
|
||||
dataList.RemoveAt(index);
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpGet("Debug")]
|
||||
public ActionResult<Dictionary<long, List<OnlineMatchingUpdateRequest>>> InspectOnlineMatching()
|
||||
{
|
||||
var matchingDb = MatchingDb.GetInstance;
|
||||
|
||||
return Ok(matchingDb.MatchingDictionary);
|
||||
}
|
||||
|
||||
[HttpGet("Clear")]
|
||||
public ActionResult<bool> Clear()
|
||||
{
|
||||
var matchingDb = MatchingDb.GetInstance;
|
||||
lock (matchingDb.DbLock)
|
||||
{
|
||||
matchingDb.MatchingDictionary.Clear();
|
||||
}
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
17
MatchServer/MatchServer.csproj
Normal file
17
MatchServer/MatchServer.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SharedProject\SharedProject.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
21
MatchServer/Program.cs
Normal file
21
MatchServer/Program.cs
Normal file
@ -0,0 +1,21 @@
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.Run();
|
31
MatchServer/Properties/launchSettings.json
Normal file
31
MatchServer/Properties/launchSettings.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:45319",
|
||||
"sslPort": 44313
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"MatchServer": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:7023;http://localhost:5038",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
MatchServer/Storage/MatchingDb.cs
Normal file
22
MatchServer/Storage/MatchingDb.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using SharedProject.models;
|
||||
|
||||
namespace MatchServer.Storage;
|
||||
|
||||
public class MatchingDb
|
||||
{
|
||||
public Dictionary<long, List<OnlineMatchingData>> MatchingDictionary;
|
||||
|
||||
public object DbLock = new();
|
||||
|
||||
static MatchingDb()
|
||||
{
|
||||
}
|
||||
|
||||
private MatchingDb()
|
||||
{
|
||||
MatchingDictionary = new Dictionary<long, List<OnlineMatchingData>>();
|
||||
}
|
||||
|
||||
public static MatchingDb GetInstance { get; } = new MatchingDb();
|
||||
|
||||
}
|
8
MatchServer/appsettings.Development.json
Normal file
8
MatchServer/appsettings.Development.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
9
MatchServer/appsettings.json
Normal file
9
MatchServer/appsettings.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
44
SharedProject/models/OnlineMatchingData.cs
Normal file
44
SharedProject/models/OnlineMatchingData.cs
Normal file
@ -0,0 +1,44 @@
|
||||
namespace SharedProject.models;
|
||||
|
||||
public class OnlineMatchingData
|
||||
{
|
||||
public long MachineId { get; set; }
|
||||
|
||||
public long EventId { get; set; }
|
||||
|
||||
public long MatchingId { get; set; }
|
||||
|
||||
public long EntryNo { get; set; }
|
||||
|
||||
public string EntryStart { get; set; } = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
public long Status { get; set; } = 1;
|
||||
|
||||
public long CardId { get; set; }
|
||||
|
||||
public string PlayerName { get; set; } = string.Empty;
|
||||
|
||||
public long AvatarId { get; set; }
|
||||
|
||||
public long TitleId { get; set; }
|
||||
|
||||
public long ClassId { get; set; }
|
||||
|
||||
public long GroupId { get; set; }
|
||||
|
||||
public long TenpoId { get; set; }
|
||||
|
||||
public string TenpoName { get; set; } = "1337";
|
||||
|
||||
public long PrefId { get; set; }
|
||||
|
||||
public string Pref { get; set; } = "nesys";
|
||||
|
||||
public long MessageId { get; set; }
|
||||
|
||||
public long MatchingTimeout { get; set; } = 99;
|
||||
|
||||
public long MatchingWaitTime { get; set; } = 10;
|
||||
|
||||
public long MatchingRemainingTime { get; set; } = 3;
|
||||
}
|
8
SharedProject/models/OnlineMatchingFinishRequest.cs
Normal file
8
SharedProject/models/OnlineMatchingFinishRequest.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace SharedProject.models;
|
||||
|
||||
public class OnlineMatchingFinishRequest
|
||||
{
|
||||
public long CardId { get; set; }
|
||||
|
||||
public long MatchingId { get; set; }
|
||||
}
|
14
SharedProject/models/OnlineMatchingUpdateRequest.cs
Normal file
14
SharedProject/models/OnlineMatchingUpdateRequest.cs
Normal file
@ -0,0 +1,14 @@
|
||||
namespace SharedProject.models;
|
||||
|
||||
public class OnlineMatchingUpdateRequest
|
||||
{
|
||||
public long Action { get; set; }
|
||||
|
||||
public long EventId { get; set; }
|
||||
|
||||
public long CardId { get; set; }
|
||||
|
||||
public long MatchingId { get; set; }
|
||||
|
||||
public long MessageId { get; set; }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user