Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple submissions for the same nation cause server to return error #45

Closed
lifehackerhansol opened this issue Feb 17, 2025 · 1 comment

Comments

@lifehackerhansol
Copy link

It is possible for multiple users to join as one country. This can cause race conditions as seen in the following game input: https://pastebin.com/9TZqtdXh

(thanks to penteract for the script: https://gist.github.com/penteract/54cdae72e4cf3dc9316a2f68b4feb884)

In the above log, Vienna managed to get two events happening at once, effectively ending the game (the game ID will return 500 forever) and causing the following stack trace:

backend-1  | fail: Microsoft.AspNetCore.Server.Kestrel[13]
backend-1  |       Connection id "0HNAABBHDFSNS", Request id "0HNAABBHDFSNS:00000003": An unhandled exception was thrown by the application.
backend-1  |       System.ArgumentException: An item with the same key has already been added. Key: Vie
backend-1  |          at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
backend-1  |          at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](List`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
backend-1  |          at Mappers.EntityMapper.MapBoard(Board board, List`1 builds)
backend-1  |          at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
backend-1  |          at System.Collections.Generic.List`1.AddRange(IEnumerable`1 collection)
backend-1  |          at Mappers.EntityMapper.MapWorld(World world, Nullable`1 player) in /app/Mappers/EntityMapper.cs:line 15
backend-1  |          at Controllers.GameController.GetWorld(Int32 gameId, Nation player) in /app/Controllers/GameController.cs:line 90
backend-1  |          at lambda_method461(Closure, Object)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
backend-1  |          at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
backend-1  |          at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
backend-1  |          at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
backend-1  |          at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

As far as I can tell, there seems to be no mechanism to block multiple users submitting as one country. Could something like that be configured? (such as a keepalive ping?)

@Oliveriver Oliveriver changed the title Multiple users joining as one country can cause race condition breaking an entire game Multiple submissions for the same nation cause server to return error Feb 20, 2025
@Oliveriver
Copy link
Owner

I changed the title slightly since it's not joining as the same nation that causes the error, but submitting as the same nation.

I believe I've fixed the most likely crash with 0484f64, but I thought it through and there is still a minor potential for race conditions in the way submission is handled. I think it's unlikely enough that it's not worth thinking too hard about though.

I will close this for now, but will reopen it if anyone reports experiencing race conditions even after this fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants