mirror of
https://github.com/SoDOff-Project/sodoff.git
synced 2025-10-11 08:18:49 -07:00
Achievement race condition fix (#28)
This commit is contained in:
parent
e564a44b13
commit
d0eacb75b6
41
src/Attributes/VikingSession.cs
Normal file
41
src/Attributes/VikingSession.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
using sodoff.Model;
|
||||
using sodoff.Controllers.Common;
|
||||
|
||||
namespace sodoff.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
public class VikingSession : Attribute, IAsyncActionFilter {
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) {
|
||||
DBContext ctx = ((AchievementController)context.Controller).ctx;
|
||||
|
||||
foreach (var a in context.ActionArguments.Keys) {
|
||||
Console.WriteLine(a);
|
||||
}
|
||||
|
||||
if (!context.HttpContext.Request.Form.ContainsKey("apiToken")) {
|
||||
context.Result = new UnauthorizedObjectResult("Unauthorized") { StatusCode = 403 };
|
||||
return;
|
||||
}
|
||||
|
||||
Session? session = ctx.Sessions.FirstOrDefault(x => x.ApiToken == context.HttpContext.Request.Form["apiToken"].ToString());
|
||||
if (session?.VikingId is null) {
|
||||
context.Result = new UnauthorizedObjectResult("Unauthorized") { StatusCode = 403 };
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: we can't refer to session.Viking here, because it may cause to ignore modifications from the threads we are waiting for
|
||||
// we can use session.Viking only after vikingMutex.WaitOne()
|
||||
|
||||
Mutex vikingMutex = new Mutex(false, "SoDOffViking:" + session.VikingId);
|
||||
try {
|
||||
vikingMutex.WaitOne();
|
||||
context.ActionArguments["viking"] = session.Viking;
|
||||
await next();
|
||||
} finally {
|
||||
vikingMutex.ReleaseMutex();
|
||||
}
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ using sodoff.Util;
|
||||
namespace sodoff.Controllers.Common;
|
||||
public class AchievementController : Controller {
|
||||
|
||||
private readonly DBContext ctx;
|
||||
public readonly DBContext ctx;
|
||||
private AchievementService achievementService;
|
||||
public AchievementController(DBContext ctx, AchievementService achievementService) {
|
||||
this.ctx = ctx;
|
||||
@ -138,14 +138,10 @@ public class AchievementController : Controller {
|
||||
[Produces("application/xml")]
|
||||
[Route("AchievementWebService.asmx/SetAchievementAndGetReward")]
|
||||
[Route("AchievementWebService.asmx/SetUserAchievementAndGetReward")]
|
||||
public IActionResult SetAchievementAndGetReward([FromForm] string apiToken, [FromForm] int achievementID) {
|
||||
Viking? viking = ctx.Sessions.FirstOrDefault(x => x.ApiToken == apiToken).Viking;
|
||||
|
||||
if (viking is null) {
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
[VikingSession()]
|
||||
public IActionResult SetAchievementAndGetReward(Viking viking, [FromForm] int achievementID) {
|
||||
var rewards = achievementService.ApplyAchievementRewardsByID(viking, achievementID);
|
||||
|
||||
ctx.SaveChanges();
|
||||
|
||||
return Ok(rewards);
|
||||
@ -155,13 +151,8 @@ public class AchievementController : Controller {
|
||||
[Produces("application/xml")]
|
||||
[Route("V2/AchievementWebService.asmx/SetUserAchievementTask")]
|
||||
[DecryptRequest("achievementTaskSetRequest")]
|
||||
public IActionResult SetUserAchievementTask([FromForm] string apiToken) {
|
||||
Viking? viking = ctx.Sessions.FirstOrDefault(x => x.ApiToken == apiToken).Viking;
|
||||
|
||||
if (viking is null) {
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
[VikingSession()]
|
||||
public IActionResult SetUserAchievementTask(Viking viking) {
|
||||
AchievementTaskSetRequest request = XmlUtil.DeserializeXml<AchievementTaskSetRequest>(Request.Form["achievementTaskSetRequest"]);
|
||||
|
||||
var response = new List<AchievementTaskSetResponse>();
|
||||
|
@ -51,51 +51,6 @@
|
||||
<ii>0</ii>
|
||||
</AR>
|
||||
</AchievementsIdInfo>
|
||||
<AchievementsIdInfo>
|
||||
<AID>201323</AID>
|
||||
<AR>
|
||||
<p>2</p>
|
||||
<a>25</a>
|
||||
<t>1</t>
|
||||
<r>21</r>
|
||||
<ii>0</ii>
|
||||
</AR>
|
||||
<AR>
|
||||
<p>1</p>
|
||||
<a>50</a>
|
||||
<t>1</t>
|
||||
<r>32</r>
|
||||
<ii>0</ii>
|
||||
</AR>
|
||||
<AR>
|
||||
<p>12</p>
|
||||
<a>100</a>
|
||||
<t>1</t>
|
||||
<r>913</r>
|
||||
<ii>0</ii>
|
||||
</AR>
|
||||
<AR>
|
||||
<p>12</p>
|
||||
<a>10</a>
|
||||
<t>1</t>
|
||||
<r>920</r>
|
||||
<ii>0</ii>
|
||||
</AR>
|
||||
<AR>
|
||||
<p>8</p>
|
||||
<a>200</a>
|
||||
<t>3</t>
|
||||
<r>611</r>
|
||||
<ii>0</ii>
|
||||
</AR>
|
||||
<AR>
|
||||
<p>12</p>
|
||||
<a>10</a>
|
||||
<t>3</t>
|
||||
<r>920</r>
|
||||
<ii>0</ii>
|
||||
</AR>
|
||||
</AchievementsIdInfo>
|
||||
<AchievementsIdInfo>
|
||||
<AID>201323</AID>
|
||||
<AR>
|
||||
|
Loading…
x
Reference in New Issue
Block a user