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

Added RoundStartingEventArgs #2797

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Exiled.Events/EventArgs/Server/RoundStartingEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// -----------------------------------------------------------------------
// <copyright file="RoundStartingEventArgs.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.EventArgs.Server
{
/// <summary>
/// Contains isallowed or not.
angelseraphim marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
public class RoundStartingEventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="RoundStartingEventArgs" /> class.
/// </summary>
/// <param name="isAllowed">
/// <inheritdoc cref="IsAllowed" />
/// </param>
public RoundStartingEventArgs(bool isAllowed = true)
{
IsAllowed = isAllowed;
}

/// <summary>
/// Gets or sets a value indicating whether the round can start or not.
/// </summary>
public bool IsAllowed { get; set; }
}
}
13 changes: 12 additions & 1 deletion Exiled.Events/Handlers/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ public static class Server
/// </summary>
public static Event ReloadedPermissions { get; set; } = new();

/// <summary>
/// Invoked before the round starts.
/// </summary>
public static Event<RoundStartingEventArgs> RoundStarting { get; set; } = new();

/// <summary>
/// Called before waiting for players.
/// </summary>
Expand Down Expand Up @@ -195,5 +200,11 @@ public static class Server
/// </summary>
/// <param name="ev">The <see cref="SelectingRespawnTeamEventArgs"/> instance.</param>
public static void OnSelectingRespawnTeam(SelectingRespawnTeamEventArgs ev) => SelectingRespawnTeam.InvokeSafely(ev);

/// <summary>
/// Called before round started.
/// </summary>
/// <param name="ev">The <see cref="RoundStartingEventArgs"/> instance.</param>
public static void OnRoundStarting(RoundStartingEventArgs ev) => RoundStarting.InvokeSafely(ev);
}
}
}
78 changes: 78 additions & 0 deletions Exiled.Events/Patches/Events/Server/RoundStarting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// -----------------------------------------------------------------------
// <copyright file="RoundStarting.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Patches.Events.Server
{
using System.Collections.Generic;
using System.Reflection.Emit;

using API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Server;
using Exiled.Events.Handlers;

using GameCore;

using HarmonyLib;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patch the <see cref="RoundStart.NetworkTimer" />.
/// Adds the <see cref="Server.RoundStarting" /> event.
/// </summary>
[EventPatch(typeof(Server), nameof(Server.RoundStarting))]
[HarmonyPatch(typeof(RoundStart), nameof(RoundStart.NetworkTimer), MethodType.Setter)]
internal static class RoundStarting
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label ret = generator.DefineLabel();
Label contlabel = generator.DefineLabel();

newInstructions[newInstructions.Count - 1].labels.Add(ret);
LocalBuilder ev = generator.DeclareLocal(typeof(RoundStartingEventArgs));

newInstructions.InsertRange(
0,
new CodeInstruction[]
{
// Getting a old value
new CodeInstruction(OpCodes.Ldarg_1),

// Getting a new value
new CodeInstruction(OpCodes.Ldc_I4, -1),

// If the value is not equal, jump
new CodeInstruction(OpCodes.Bne_Un, contlabel),

// RoundStartingEventArgs ev = new
new CodeInstruction(OpCodes.Newobj, GetDeclaredConstructors(typeof(RoundStartingEventArgs))[0]),
new CodeInstruction(OpCodes.Dup),
new CodeInstruction(OpCodes.Stloc_S, ev.LocalIndex),

// Handlers.Server.OnRoundStarting(ev)
new CodeInstruction(OpCodes.Call, Method(typeof(Server), nameof(Server.OnRoundStarting))),
new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex),

// If isallowed = false
new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(RoundStartingEventArgs), nameof(RoundStartingEventArgs.IsAllowed))),
new CodeInstruction(OpCodes.Brfalse_S, ret),

// Empty opcode for jump
new CodeInstruction(OpCodes.Nop).WithLabels(contlabel),
});

for (int z = 0; z < newInstructions.Count; z++)
yield return newInstructions[z];

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
}
Loading