Implement PvPCommands

This commit is contained in:
AlexBond 2026-03-31 18:49:29 +03:00
parent 088590eca2
commit 34b059fc96
7 changed files with 104 additions and 11 deletions

View file

@ -27,7 +27,13 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
QueueParams = queueParams;
int[] teamLimits = Queue.Prototype.TeamLimits;
if (teamLimits.HasValue())
if (queueParams.TeamSizeOverride > 0)
{
_teams.Add(new MatchTeam(0, queueParams.TeamSizeOverride));
_teams.Add(new MatchTeam(1, queueParams.TeamSizeOverride));
}
else if (teamLimits.HasValue())
{
for (int i = 0; i < teamLimits.Length; i++)
{
@ -97,6 +103,11 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
return true;
}
public bool IsCompatibleWith(in RegionRequestQueueParams queueParams)
{
return QueueParams.TeamSizeOverride == queueParams.TeamSizeOverride;
}
public bool IsReady()
{
if (IsFull() == false && IsBypass == false && Queue.Prototype.QueueDoNotWaitToFull == false)

View file

@ -45,7 +45,7 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
foreach (Match match in _matches)
{
if (match.IsLookingForMore())
if (match.IsLookingForMore() && match.IsCompatibleWith(queueParams))
lfmMatches.Add(match);
}

View file

@ -22,7 +22,7 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
}
public void HandleCommand(PrototypeId regionRef, PrototypeId difficultyTierRef, PrototypeId metaStateRef,
RegionRequestQueueCommandVar command, ulong regionRequestGroupId, ulong targetPlayerDbId)
RegionRequestQueueCommandVar command, ulong regionRequestGroupId, ulong targetPlayerDbId, int teamSizeOverride = -1)
{
Logger.Trace($"HandleCommand(): command=[{command}], region=[{regionRef.GetNameFormatted()}], player=[{_player}]");
@ -31,7 +31,7 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
case RegionRequestQueueCommandVar.eRRQC_AddToQueueSolo:
case RegionRequestQueueCommandVar.eRRQC_AddToQueueParty:
case RegionRequestQueueCommandVar.eRRQC_AddToQueueBypass:
OnAddToQueue(regionRef, difficultyTierRef, metaStateRef, command);
OnAddToQueue(regionRef, difficultyTierRef, metaStateRef, command, teamSizeOverride);
break;
case RegionRequestQueueCommandVar.eRRQC_RemoveFromQueue:
@ -53,7 +53,8 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
}
}
private bool OnAddToQueue(PrototypeId regionRef, PrototypeId difficultyTierRef, PrototypeId metaStateRef, RegionRequestQueueCommandVar command)
private bool OnAddToQueue(PrototypeId regionRef, PrototypeId difficultyTierRef, PrototypeId metaStateRef,
RegionRequestQueueCommandVar command, int teamSizeOverride = -1)
{
RegionRequestQueue queue = PlayerManagerService.Instance.RegionRequestQueueManager.GetRegionRequestQueue(regionRef);
if (queue == null)
@ -74,7 +75,7 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
// Create region request group
MasterParty party = command == RegionRequestQueueCommandVar.eRRQC_AddToQueueParty ? _player.CurrentParty : null;
RegionRequestQueueParams queueParams = new(difficultyTierRef, metaStateRef, command == RegionRequestQueueCommandVar.eRRQC_AddToQueueBypass);
RegionRequestQueueParams queueParams = new(difficultyTierRef, metaStateRef, command == RegionRequestQueueCommandVar.eRRQC_AddToQueueBypass, teamSizeOverride);
RegionRequestGroup group = RegionRequestGroup.Create(queue, queueParams, _player, party);
if (group == null)

View file

@ -10,17 +10,19 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
public readonly PrototypeId DifficultyTierRef;
public readonly PrototypeId MetaStateRef;
public readonly bool IsBypass;
public readonly int TeamSizeOverride;
public RegionRequestQueueParams(PrototypeId difficultyTierRef, PrototypeId metaStateRef, bool isBypass)
public RegionRequestQueueParams(PrototypeId difficultyTierRef, PrototypeId metaStateRef, bool isBypass, int teamSizeOverride)
{
DifficultyTierRef = difficultyTierRef;
MetaStateRef = metaStateRef;
IsBypass = isBypass;
TeamSizeOverride = teamSizeOverride;
}
public override string ToString()
{
return $"difficulty={DifficultyTierRef.GetNameFormatted()}, metaState={MetaStateRef.GetNameFormatted()}, isBypass={IsBypass}";
return $"difficulty={DifficultyTierRef.GetNameFormatted()}, metaState={MetaStateRef.GetNameFormatted()}, isBypass={IsBypass}, teamSizeOverride={TeamSizeOverride}";
}
public override int GetHashCode()
@ -40,7 +42,8 @@ namespace MHServerEmu.PlayerManagement.Matchmaking
{
return DifficultyTierRef == other.DifficultyTierRef &&
MetaStateRef == other.MetaStateRef &&
IsBypass == other.IsBypass;
IsBypass == other.IsBypass &&
TeamSizeOverride == other.TeamSizeOverride;
}
public static bool operator ==(RegionRequestQueueParams left, RegionRequestQueueParams right)

View file

@ -147,6 +147,11 @@ namespace MHServerEmu.PlayerManagement
statusDict["PlayerManagerPendingSessions"] = SessionManager.PendingSessionCount;
}
public PlayerHandle GetPlayer(ulong playerDbId)
{
return ClientManager.GetPlayer(playerDbId);
}
private void OnRouteMessageBuffer(in ServiceMessage.RouteMessageBuffer routeMessageBuffer)
{
IFrontendClient client = routeMessageBuffer.Client;

View file

@ -814,9 +814,9 @@ namespace MHServerEmu.PlayerManagement.Players
}
public void ReceiveRegionRequestQueueCommand(PrototypeId regionRef, PrototypeId difficultyTierRef, PrototypeId metaStateRef,
RegionRequestQueueCommandVar command, ulong regionRequestGroupId, ulong targetPlayerDbId)
RegionRequestQueueCommandVar command, ulong regionRequestGroupId, ulong targetPlayerDbId, int teamSizeOverride = -1)
{
_regionRequestQueueCommandHandler.HandleCommand(regionRef, difficultyTierRef, metaStateRef, command, regionRequestGroupId, targetPlayerDbId);
_regionRequestQueueCommandHandler.HandleCommand(regionRef, difficultyTierRef, metaStateRef, command, regionRequestGroupId, targetPlayerDbId, teamSizeOverride);
}
public void AddToChatRoom(ChatRoomTypes roomType, ulong roomId)

View file

@ -0,0 +1,73 @@
using Gazillion;
using MHServerEmu.Commands.Attributes;
using MHServerEmu.Core.Network;
using MHServerEmu.DatabaseAccess.Models;
using MHServerEmu.Games.GameData;
using MHServerEmu.Games.Network;
using MHServerEmu.PlayerManagement;
using MHServerEmu.PlayerManagement.Players;
namespace MHServerEmu.Commands.Implementations
{
[CommandGroup("pvp")]
[CommandGroupDescription("Commands related to PvP matchmaking.")]
[CommandGroupUserLevel(AccountUserLevel.User)]
public class PvPCommands : CommandGroup
{
private static readonly PrototypeId RegionRef =
GameDatabase.GetPrototypeRefByName("Metagame/DefenderPvP/Regions/PvPDefenderTier5Region.prototype");
private static readonly PrototypeId DifficultyRef =
GameDatabase.GetPrototypeRefByName("Difficulty/Tiers/Tier1Normal.prototype");
private string JoinQueue(int size, NetClient client)
{
PlayerConnection playerConnection = (PlayerConnection)client;
var player = playerConnection.Player;
if (player == null) return "Player not found.";
bool isInParty = player.Party != null && player.Party.NumMembers > 1;
var command = isInParty
? RegionRequestQueueCommandVar.eRRQC_AddToQueueParty
: RegionRequestQueueCommandVar.eRRQC_AddToQueueSolo;
var playerManager = ServerManager.Instance.GetGameService(GameServiceType.PlayerManager) as PlayerManagerService;
if (playerManager == null) return "Failed to connect to the player manager.";
PlayerHandle destPlayer = playerManager.GetPlayer(playerConnection.PlayerDbId);
destPlayer.ReceiveRegionRequestQueueCommand(RegionRef, DifficultyRef, PrototypeId.Invalid, command, 0, 0, size);
return $"Queued for {size}v{size} PvP! ({(isInParty ? "Party" : "Solo")})";
}
[Command("1v1")]
[CommandDescription("Join 1v1 PvP queue.")]
[CommandUsage("pvp 1v1")]
[CommandInvokerType(CommandInvokerType.Client)]
public string Queue1v1(string[] @params, NetClient client) => JoinQueue(1, client);
[Command("2v2")]
[CommandDescription("Join 2v2 PvP queue.")]
[CommandUsage("pvp 2v2")]
[CommandInvokerType(CommandInvokerType.Client)]
public string Queue2v2(string[] @params, NetClient client) => JoinQueue(2, client);
[Command("3v3")]
[CommandDescription("Join 3v3 PvP queue.")]
[CommandUsage("pvp 3v3")]
[CommandInvokerType(CommandInvokerType.Client)]
public string Queue3v3(string[] @params, NetClient client) => JoinQueue(3, client);
[Command("4v4")]
[CommandDescription("Join 4v4 PvP queue.")]
[CommandUsage("pvp 4v4")]
[CommandInvokerType(CommandInvokerType.Client)]
public string Queue4v4(string[] @params, NetClient client) => JoinQueue(4, client);
[Command("5v5")]
[CommandDescription("Join 5v5 PvP queue.")]
[CommandUsage("pvp 5v5")]
[CommandInvokerType(CommandInvokerType.Client)]
public string Queue5v5(string[] @params, NetClient client) => JoinQueue(-1, client);
}
}