mirror of
https://github.com/Impostor/Impostor.git
synced 2026-10-19 15:51:42 +00:00
Basically support AMCI
This commit is contained in:
1 parent
8f41030faf
commit
510ed07389
13 files changed
+107
-16
No files matched your search
@@ -151,6 +151,7 @@
|
|||||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
".NETStandard,Version=v2.0/win-x64": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Impostor.Api.Innersloth;
|
using Impostor.Api.Innersloth;
|
||||||
@@ -47,6 +48,11 @@ namespace Impostor.Api.Games
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
bool IsHostAuthoritive { get; }
|
bool IsHostAuthoritive { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the mod GUID that the game was registered with through the AMCI.
|
||||||
|
/// </summary>
|
||||||
|
Guid? ModGuid { get; }
|
||||||
|
|
||||||
IClientPlayer? GetClientPlayer(int clientId);
|
IClientPlayer? GetClientPlayer(int clientId);
|
||||||
|
|
||||||
T? FindObjectByNetId<T>(uint netId)
|
T? FindObjectByNetId<T>(uint netId)
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ namespace Impostor.Api.Innersloth.GameFilters
|
|||||||
case "bool":
|
case "bool":
|
||||||
return JsonSerializer.Deserialize<BoolGameFilter>(filterString)
|
return JsonSerializer.Deserialize<BoolGameFilter>(filterString)
|
||||||
?? throw new InvalidOperationException("Deserialization returned null for BoolGameFilter");
|
?? throw new InvalidOperationException("Deserialization returned null for BoolGameFilter");
|
||||||
|
case "mod":
|
||||||
|
return JsonSerializer.Deserialize<ModFilter>(filterString)
|
||||||
|
?? throw new InvalidOperationException("Deserialization returned null for ModFilter");
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException("No type matches subfilter");
|
throw new InvalidOperationException("No type matches subfilter");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
// https://github.com/Innersloth-LLC/AmongUsModdingInformation
|
||||||
|
namespace Impostor.Api.Innersloth.GameFilters
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class ModFilter : ISubFilter
|
||||||
|
{
|
||||||
|
[JsonPropertyName("FilterType")]
|
||||||
|
public string FilterType { get; } = "mod";
|
||||||
|
|
||||||
|
[JsonPropertyName("AcceptedValues")]
|
||||||
|
public required Guid AcceptedValues { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Impostor.Api.Innersloth;
|
using Impostor.Api.Innersloth;
|
||||||
using Impostor.Api.Innersloth.GameOptions;
|
using Impostor.Api.Innersloth.GameOptions;
|
||||||
|
|
||||||
namespace Impostor.Api.Net.Messages.C2S
|
namespace Impostor.Api.Net.Messages.C2S
|
||||||
@@ -20,5 +20,11 @@ namespace Impostor.Api.Net.Messages.C2S
|
|||||||
crossplayFlags = (CrossplayFlags)reader.ReadInt32();
|
crossplayFlags = (CrossplayFlags)reader.ReadInt32();
|
||||||
gameFilterOptions = GameFilterOptions.Deserialize(reader);
|
gameFilterOptions = GameFilterOptions.Deserialize(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void DeserializeModded(IMessageReader reader, out IGameOptions gameOptions, out CrossplayFlags crossplayFlags, out GameFilterOptions gameFilterOptions, out Guid modGuid)
|
||||||
|
{
|
||||||
|
Deserialize(reader, out gameOptions, out crossplayFlags, out gameFilterOptions);
|
||||||
|
modGuid = new Guid(reader.ReadBytes(16).Span);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,6 +29,7 @@ namespace Impostor.Api.Net.Messages
|
|||||||
public const byte QueryPlatformIds = 22;
|
public const byte QueryPlatformIds = 22;
|
||||||
public const byte QueryLobbyInfo = 23;
|
public const byte QueryLobbyInfo = 23;
|
||||||
public const byte EndGameHostMigration = 24;
|
public const byte EndGameHostMigration = 24;
|
||||||
|
public const byte HostModdedGame = 25;
|
||||||
public const byte PackedGameDataTo = 26;
|
public const byte PackedGameDataTo = 26;
|
||||||
|
|
||||||
private static readonly Dictionary<byte, string> FlagCache;
|
private static readonly Dictionary<byte, string> FlagCache;
|
||||||
|
|||||||
@@ -40,6 +40,12 @@
|
|||||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
|
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Microsoft.NET.ILLink.Tasks": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[8.0.30, )",
|
||||||
|
"resolved": "8.0.30",
|
||||||
|
"contentHash": "SfmwuZjUPBTEoBMAsXZ/hWkaEK9oL+Y/UtAx7N6RyWHfcMt9J0ExrNPuOgTyPbCXIyiTBFsxFNrPLEZNPmJcvA=="
|
||||||
|
},
|
||||||
"StyleCop.Analyzers": {
|
"StyleCop.Analyzers": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[1.2.0-beta.556, )",
|
"requested": "[1.2.0-beta.556, )",
|
||||||
@@ -117,6 +123,7 @@
|
|||||||
"resolved": "4.5.0",
|
"resolved": "4.5.0",
|
||||||
"contentHash": "Xg4G4Indi4dqP1iuAiMSwpiWS54ZghzR644OtsRCm/m/lBMG8dUBhLVN7hLm8NNrNTR+iGbshCPTwrvxZPlm4g=="
|
"contentHash": "Xg4G4Indi4dqP1iuAiMSwpiWS54ZghzR644OtsRCm/m/lBMG8dUBhLVN7hLm8NNrNTR+iGbshCPTwrvxZPlm4g=="
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"net8.0/win-x64": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,6 +59,10 @@ public sealed class ListingManager
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (game.ModGuid != null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_compatibilityConfig.AllowVersionMixing &&
|
if (!_compatibilityConfig.AllowVersionMixing &&
|
||||||
game.Host != null &&
|
game.Host != null &&
|
||||||
@@ -137,6 +141,10 @@ public sealed class ListingManager
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (game.ModGuid != null && !filterSet.Filters.Any(f => f.OptionType == "mod"))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var matchesAllFilters = true;
|
var matchesAllFilters = true;
|
||||||
|
|
||||||
@@ -191,6 +199,13 @@ public sealed class ListingManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "mod":
|
||||||
|
if (filter.SubFilter is ModFilter modFilter && game.ModGuid != modFilter.AcceptedValues)
|
||||||
|
{
|
||||||
|
matchesAllFilters = false;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Impostor.Api;
|
|||||||
using Impostor.Api.Config;
|
using Impostor.Api.Config;
|
||||||
using Impostor.Api.Games;
|
using Impostor.Api.Games;
|
||||||
using Impostor.Api.Innersloth;
|
using Impostor.Api.Innersloth;
|
||||||
|
using Impostor.Api.Innersloth.GameOptions;
|
||||||
using Impostor.Api.Net;
|
using Impostor.Api.Net;
|
||||||
using Impostor.Api.Net.Custom;
|
using Impostor.Api.Net.Custom;
|
||||||
using Impostor.Api.Net.Messages;
|
using Impostor.Api.Net.Messages;
|
||||||
@@ -41,6 +42,11 @@ namespace Impostor.Server.Net
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Player != null && Player.Game.ModGuid != null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Player != null && Player.IsHost)
|
if (Player != null && Player.IsHost)
|
||||||
{
|
{
|
||||||
@@ -124,12 +130,25 @@ namespace Impostor.Server.Net
|
|||||||
switch (flag)
|
switch (flag)
|
||||||
{
|
{
|
||||||
case MessageFlags.HostGame:
|
case MessageFlags.HostGame:
|
||||||
|
case MessageFlags.HostModdedGame:
|
||||||
{
|
{
|
||||||
// Read game settings.
|
IGameOptions gameOptions;
|
||||||
Message00HostGameC2S.Deserialize(reader, out var gameOptions, out _, out var gameFilterOptions);
|
GameFilterOptions gameFilterOptions;
|
||||||
|
Guid? modGuid = null;
|
||||||
|
|
||||||
|
if (flag == MessageFlags.HostModdedGame)
|
||||||
|
{
|
||||||
|
Message00HostGameC2S.DeserializeModded(reader, out gameOptions, out _, out gameFilterOptions, out var parsedModGuid);
|
||||||
|
modGuid = parsedModGuid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Read game settings.
|
||||||
|
Message00HostGameC2S.Deserialize(reader, out gameOptions, out _, out gameFilterOptions);
|
||||||
|
}
|
||||||
|
|
||||||
// Create game.
|
// Create game.
|
||||||
var game = await _gameManager.CreateAsync(this, gameOptions, gameFilterOptions);
|
var game = await _gameManager.CreateAsync(this, gameOptions, gameFilterOptions, modGuid);
|
||||||
|
|
||||||
if (game == null)
|
if (game == null)
|
||||||
{
|
{
|
||||||
@@ -137,6 +156,11 @@ namespace Impostor.Server.Net
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (modGuid != null)
|
||||||
|
{
|
||||||
|
_logger.LogInformation("Client {Name} ({Id}) hosted a modded game with mod GUID {ModGuid}.", Name, Id, modGuid);
|
||||||
|
}
|
||||||
|
|
||||||
// Code in the packet below will be used in JoinGame.
|
// Code in the packet below will be used in JoinGame.
|
||||||
using (var writer = MessageWriter.Get(MessageType.Reliable))
|
using (var writer = MessageWriter.Get(MessageType.Reliable))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -85,7 +85,7 @@ namespace Impostor.Server.Net.Manager
|
|||||||
await _eventManager.CallAsync(new GameDestroyedEvent(game));
|
await _eventManager.CallAsync(new GameDestroyedEvent(game));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask<IGame?> CreateAsync(IClient? owner, IGameOptions options, GameFilterOptions filterOptions)
|
public async ValueTask<IGame?> CreateAsync(IClient? owner, IGameOptions options, GameFilterOptions filterOptions, Guid? modGuid = null)
|
||||||
{
|
{
|
||||||
if (owner != null && !_gamesCreatedBy.TryAdd(owner, null))
|
if (owner != null && !_gamesCreatedBy.TryAdd(owner, null))
|
||||||
{
|
{
|
||||||
@@ -101,11 +101,11 @@ namespace Impostor.Server.Net.Manager
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var (success, game) = await TryCreateAsync(options, filterOptions, owner, @event.GameCode);
|
var (success, game) = await TryCreateAsync(options, filterOptions, owner, @event.GameCode, modGuid);
|
||||||
|
|
||||||
for (var i = 0; i < 10 && !success; i++)
|
for (var i = 0; i < 10 && !success; i++)
|
||||||
{
|
{
|
||||||
(success, game) = await TryCreateAsync(options, filterOptions, owner);
|
(success, game) = await TryCreateAsync(options, filterOptions, owner, modGuid: modGuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (owner != null)
|
if (owner != null)
|
||||||
@@ -126,10 +126,12 @@ namespace Impostor.Server.Net.Manager
|
|||||||
return CreateAsync(null, options, filterOptions);
|
return CreateAsync(null, options, filterOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async ValueTask<(bool Success, Game? Game)> TryCreateAsync(IGameOptions options, GameFilterOptions filterOptions, IClient? owner, GameCode? desiredGameCode = null)
|
private async ValueTask<(bool Success, Game? Game)> TryCreateAsync(IGameOptions options, GameFilterOptions filterOptions, IClient? owner, GameCode? desiredGameCode = null, Guid? modGuid = null)
|
||||||
{
|
{
|
||||||
var gameCode = desiredGameCode ?? _gameCodeFactory.Create();
|
var gameCode = desiredGameCode ?? _gameCodeFactory.Create();
|
||||||
var game = ActivatorUtilities.CreateInstance<Game>(_serviceProvider, _publicIp, gameCode, options, filterOptions);
|
var game = modGuid.HasValue
|
||||||
|
? ActivatorUtilities.CreateInstance<Game>(_serviceProvider, _publicIp, gameCode, options, filterOptions, modGuid.Value)
|
||||||
|
: ActivatorUtilities.CreateInstance<Game>(_serviceProvider, _publicIp, gameCode, options, filterOptions);
|
||||||
|
|
||||||
if (!_games.TryAdd(gameCode, game))
|
if (!_games.TryAdd(gameCode, game))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ namespace Impostor.Server.Net.State
|
|||||||
IEventManager eventManager,
|
IEventManager eventManager,
|
||||||
ICompatibilityManager compatibilityManager,
|
ICompatibilityManager compatibilityManager,
|
||||||
IOptions<CompatibilityConfig> compatibilityConfig,
|
IOptions<CompatibilityConfig> compatibilityConfig,
|
||||||
IOptions<TimeoutConfig> timeoutConfig)
|
IOptions<TimeoutConfig> timeoutConfig,
|
||||||
|
Guid? modGuid = null)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_serviceProvider = serviceProvider;
|
_serviceProvider = serviceProvider;
|
||||||
@@ -62,6 +63,7 @@ namespace Impostor.Server.Net.State
|
|||||||
GameNet = new GameNet();
|
GameNet = new GameNet();
|
||||||
Options = options;
|
Options = options;
|
||||||
FilterOptions = filterOptions;
|
FilterOptions = filterOptions;
|
||||||
|
ModGuid = modGuid;
|
||||||
_clientManager = clientManager;
|
_clientManager = clientManager;
|
||||||
_eventManager = eventManager;
|
_eventManager = eventManager;
|
||||||
_compatibilityManager = compatibilityManager;
|
_compatibilityManager = compatibilityManager;
|
||||||
@@ -96,6 +98,8 @@ namespace Impostor.Server.Net.State
|
|||||||
|
|
||||||
public bool IsHostAuthoritive => Host != null && Host.Client.GameVersion.HasDisableServerAuthorityFlag;
|
public bool IsHostAuthoritive => Host != null && Host.Client.GameVersion.HasDisableServerAuthorityFlag;
|
||||||
|
|
||||||
|
public Guid? ModGuid { get; }
|
||||||
|
|
||||||
internal GameNet GameNet { get; }
|
internal GameNet GameNet { get; }
|
||||||
|
|
||||||
public bool TryGetPlayer(int id, [MaybeNullWhen(false)] out ClientPlayer player)
|
public bool TryGetPlayer(int id, [MaybeNullWhen(false)] out ClientPlayer player)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Impostor.Api.Config;
|
using Impostor.Api.Config;
|
||||||
using Impostor.Api.Innersloth;
|
using Impostor.Api.Innersloth;
|
||||||
using Impostor.Api.Net.Custom;
|
using Impostor.Api.Net.Custom;
|
||||||
@@ -52,7 +52,7 @@ namespace Impostor.Server.Recorder
|
|||||||
await base.HandleMessageAsync(reader, messageType);
|
await base.HandleMessageAsync(reader, messageType);
|
||||||
|
|
||||||
// Player created a game.
|
// Player created a game.
|
||||||
if (reader.Tag == MessageFlags.HostGame)
|
if (reader.Tag is MessageFlags.HostGame or MessageFlags.HostModdedGame)
|
||||||
{
|
{
|
||||||
_createdGame = true;
|
_createdGame = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,12 @@
|
|||||||
"resolved": "8.0.1",
|
"resolved": "8.0.1",
|
||||||
"contentHash": "X21b8D6z58EG34OMLH955750mFaEaGs5xLGe9Vyi3059Cgb3sk+p2k/JlQXaieEBRrk+SVlFzDei3Q6PdVzJOA=="
|
"contentHash": "X21b8D6z58EG34OMLH955750mFaEaGs5xLGe9Vyi3059Cgb3sk+p2k/JlQXaieEBRrk+SVlFzDei3Q6PdVzJOA=="
|
||||||
},
|
},
|
||||||
|
"Microsoft.NET.ILLink.Tasks": {
|
||||||
|
"type": "Direct",
|
||||||
|
"requested": "[8.0.30, )",
|
||||||
|
"resolved": "8.0.30",
|
||||||
|
"contentHash": "SfmwuZjUPBTEoBMAsXZ/hWkaEK9oL+Y/UtAx7N6RyWHfcMt9J0ExrNPuOgTyPbCXIyiTBFsxFNrPLEZNPmJcvA=="
|
||||||
|
},
|
||||||
"Serilog.Extensions.Hosting": {
|
"Serilog.Extensions.Hosting": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[8.0.0, )",
|
"requested": "[8.0.0, )",
|
||||||
|
|||||||
Reference in new issue
Block a user