Skip to content
This repository has been archived by the owner on Jan 19, 2025. It is now read-only.

HintModule #2728

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
16 changes: 16 additions & 0 deletions EXILED.sln
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "docs", "docs\docs.csproj",
{9FEBCAEA-EB51-46D0-BC04-F74789A40079} = {9FEBCAEA-EB51-46D0-BC04-F74789A40079}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Exiled.Hints", "Exiled.Hints\Exiled.Hints.csproj", "{2D7FD4F7-3A5C-42FE-A97C-6FC9BA2C8CE2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RueI", "RueI\RueI.csproj", "{0ECF1DEA-96C2-4CDF-A7F2-10D20E1C06A0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -85,6 +89,18 @@ Global
{33EEFAC8-F5A7-4E51-8FD1-C45D25268B4A}.Installer|Any CPU.Build.0 = Debug|Any CPU
{33EEFAC8-F5A7-4E51-8FD1-C45D25268B4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33EEFAC8-F5A7-4E51-8FD1-C45D25268B4A}.Release|Any CPU.Build.0 = Release|Any CPU
{2D7FD4F7-3A5C-42FE-A97C-6FC9BA2C8CE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D7FD4F7-3A5C-42FE-A97C-6FC9BA2C8CE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D7FD4F7-3A5C-42FE-A97C-6FC9BA2C8CE2}.Installer|Any CPU.ActiveCfg = Debug|Any CPU
{2D7FD4F7-3A5C-42FE-A97C-6FC9BA2C8CE2}.Installer|Any CPU.Build.0 = Debug|Any CPU
{2D7FD4F7-3A5C-42FE-A97C-6FC9BA2C8CE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D7FD4F7-3A5C-42FE-A97C-6FC9BA2C8CE2}.Release|Any CPU.Build.0 = Release|Any CPU
{0ECF1DEA-96C2-4CDF-A7F2-10D20E1C06A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0ECF1DEA-96C2-4CDF-A7F2-10D20E1C06A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0ECF1DEA-96C2-4CDF-A7F2-10D20E1C06A0}.Installer|Any CPU.ActiveCfg = Debug|Any CPU
{0ECF1DEA-96C2-4CDF-A7F2-10D20E1C06A0}.Installer|Any CPU.Build.0 = Debug|Any CPU
{0ECF1DEA-96C2-4CDF-A7F2-10D20E1C06A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0ECF1DEA-96C2-4CDF-A7F2-10D20E1C06A0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
1 change: 1 addition & 0 deletions Exiled.API/Exiled.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Installer</Configurations>
<Platforms>AnyCPU</Platforms>
<LangVersion>10</LangVersion>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no.

</PropertyGroup>

<Import Project="../EXILED.props" />
Expand Down
16 changes: 8 additions & 8 deletions Exiled.API/Features/Hint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ public Hint()
/// <param name="show">Whether or not the hint should be shown.</param>
public Hint(string content, float duration = 3, bool show = true, HintParameter[] parameters = null, HintEffect[] effects = null)
{
Content = content;
Duration = duration;
Show = show;
Parameters = parameters ?? new HintParameter[] { new StringHintParameter(Content) };
Effects = effects;
this.Content = content;
this.Duration = duration;
this.Show = show;
this.Parameters = parameters ?? new HintParameter[] { new StringHintParameter(this.Content) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not necessary here

this.Effects = effects;
}

/// <summary>
Expand Down Expand Up @@ -73,8 +73,8 @@ public Hint(string content, float duration = 3, bool show = true, HintParameter[
[YamlIgnore]
public HintParameter[] Parameters
{
get => parameters ??= new HintParameter[] { new StringHintParameter(Content) };
set => parameters = value;
get => this.parameters ??= new HintParameter[] { new StringHintParameter(this.Content) };
set => this.parameters = value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

}

/// <summary>
Expand All @@ -87,6 +87,6 @@ public HintParameter[] Parameters
/// Returns the hint in a human-readable format.
/// </summary>
/// <returns>A string containing hint-related data.</returns>
public override string ToString() => $"({Content}) {Duration}";
public override string ToString() => $"({this.Content}) {this.Duration}";
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

}
2 changes: 1 addition & 1 deletion Exiled.API/Features/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ private set
/// <summary>
/// Gets the <see cref="Hints.HintDisplay"/> of the player.
/// </summary>
public HintDisplay HintDisplay { get; private set; }
public Hints.HintDisplay HintDisplay { get; private set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to do this?


/// <summary>
/// Gets the player's <see cref="InventorySystem.Inventory"/>.
Expand Down
5 changes: 5 additions & 0 deletions Exiled.CustomModules/API/Enums/UUModuleType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,10 @@ public class UUModuleType : UniqueUnmanagedEnumClass<uint, UUCustomRoleType>
/// Custom game modes module.
/// </summary>
public static readonly UUModuleType CustomGameModes = new();

/// <summary>
/// Custom hints' module.
/// </summary>
public static readonly UUModuleType CustomHints = new();
}
}
40 changes: 40 additions & 0 deletions Exiled.Hints/CustomHints/HintPatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// -----------------------------------------------------------------------
// <copyright file="HintPatch.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

using Hints;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this


namespace Exiled.API.Features.CustomHints
{
using System;
using System.Collections.Generic;

using HarmonyLib;
using Hints;
using Mirror;

/// <summary>
/// The patch for hints.
/// </summary>
[HarmonyPatch(typeof(HintDisplay))]
[HarmonyPatch("Show")]
public static class HintPatch
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both attributes can be in the same one [HarmonyPatch(typeof(HintDisplay), nameof(HintDisplay.Show))]

{
#pragma warning disable SA1313
private static bool Prefix(HintDisplay __instance, ref global::Hints.Hint hint)
#pragma warning restore SA1313
{
if (hint.GetType() != typeof(TextHint))
{
return true;
}

TextHint textHint = (TextHint)hint;
HintSys.Display(textHint.Text, textHint.DurationScalar, [Player.Get(__instance.netIdentity)]);
return false;
}
}
}
121 changes: 121 additions & 0 deletions Exiled.Hints/CustomHints/HintSys.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// -----------------------------------------------------------------------
// <copyright file="HintSys.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

using Hints;
using RueI.Displays;
using RueI.Elements;
using RueI.Parsing;
using RueI.Parsing.Records;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all of this should be with the other ones, also why using 2 Hints Namespaces

namespace Exiled.API.Features.CustomHints
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

using Hints;
using MEC;
using Mirror;

/// <summary>
/// A powerful hint system that allows multiple concurrent hints.
/// </summary>
public static class HintSys
{
/// <summary>
/// A dictionary containing the caller and a tuple containing the hint, a list of players to receive the hint, and the timestamp the hint was sent at.
/// </summary>
private static Dictionary<string, Tuple<Hint, List<Player>, long>> hints = new();

private static Dictionary<Player, List<string>> playerHints = new();

private static CoroutineHandle? hintHandle;

/// <summary>
/// Gets the hints.
/// </summary>
/// <returns>A dictionary containing all hints, modifying will do nothing.</returns>
public static Dictionary<string, Tuple<Hint, List<Player>, long>> GetHints()
{
return new Dictionary<string, Tuple<Hint, List<Player>, long>>(hints);
}

/// <summary>
/// Adds a hint to the display queue, if there is already a hint by this caller, replaces it.
/// </summary>
/// <param name="content">The content of the hint.</param>
/// <param name="duration">The duration in seconds.</param>
/// <param name="players">A list of players to add to the hint.</param>
/// <param name="caller">Do not populate.</param>
public static void Display(string content, float duration, List<Player> players, [CallerMemberName] string caller = "")
{
Hint hint = new()
{
Content = content,
Duration = duration,
};
hints[caller] = new Tuple<Hint, List<Player>, long>(hint, players, DateTimeOffset.UtcNow.ToUnixTimeSeconds());
foreach (Player player in players)
{
playerHints.GetOrAdd(player, () => new List<string>()).Add(caller);
}

hintHandle ??= Timing.RunCoroutine(HintDisplayLoop());
}

private static void Send(string hintText, Player player)
{
HintDisplay hintDisplay = player.ReferenceHub.hints;
if (hintDisplay.isLocalPlayer)
throw new InvalidOperationException("Cannot display a hint to the local player (headless server).");
if (!NetworkServer.active)
return;
NetworkConnection connectionToClient = hintDisplay.netIdentity.connectionToClient;
if (HintDisplay.SuppressedReceivers.Contains(connectionToClient))
return;
TextHint hint = new TextHint(hintText, [new StringHintParameter(hintText)], null);
connectionToClient.Send(new HintMessage(hint));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure to leave a blank line after the returns and the new InvalidOperationException


private static IEnumerator<float> HintDisplayLoop()
{
for (; ;)
{
foreach (KeyValuePair<Player, List<string>> keyValuePair in playerHints)
{
List<ParsedData> parserContexts = [];
foreach (string se in keyValuePair.Value.ToList())
{
Tuple<Hint, List<Player>, long> item = hints[se];
if (!item.Item2.Contains(keyValuePair.Key))
continue;
if ((item.Item3 - DateTimeOffset.UtcNow.ToUnixTimeSeconds()) > item.Item1.Duration)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here for the continue up here

{
hints.Remove(se);
keyValuePair.Value.Remove(se);
continue;
}

parserContexts.Add(Parser.DefaultParser.Parse(item.Item1.Content));
}

string hint = ElemCombiner.Combine(parserContexts);
Send(hint, keyValuePair.Key);
}

if (hints.Count == 0)
{
hintHandle = null;
break;
}

yield return Timing.WaitForSeconds(0.572f);
}
}
}
}
61 changes: 61 additions & 0 deletions Exiled.Hints/Exiled.Hints.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<AssemblyName>Exiled.Hints</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>Debug;Release;Installer</Configurations>
<Platforms>AnyCPU</Platforms>
<TargetFramework>net48</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Exiled.API\Exiled.API.csproj" />
<ProjectReference Include="..\Exiled.CustomModules/Exiled.CustomModules.csproj" />
<ProjectReference Include="..\RueI\RueI.csproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="Assembly-CSharp" HintPath="$(EXILED_REFERENCES)\Assembly-CSharp-Publicized.dll" Private="false" />
<Reference Include="Assembly-CSharp-firstpass" HintPath="$(EXILED_REFERENCES)\Assembly-CSharp-firstpass.dll" Private="false" />
<Reference Include="CommandSystem.Core" HintPath="$(EXILED_REFERENCES)\CommandSystem.Core.dll" Private="false" />
<Reference Include="Mirror" HintPath="$(EXILED_REFERENCES)\Mirror.dll" Private="false" />
<Reference Include="UnityEngine.CoreModule" HintPath="$(EXILED_REFERENCES)\UnityEngine.CoreModule.dll" Private="false" />
<Reference Include="NorthwoodLib" HintPath="$(EXILED_REFERENCES)\NorthwoodLib.dll" Private="false" />
<Reference Include="PluginAPI" HintPath="$(EXILED_REFERENCES)\PluginAPI.dll" Private="false" />
<Reference Include="UnityEngine.PhysicsModule" HintPath="$(EXILED_REFERENCES)\UnityEngine.PhysicsModule.dll" Private="false" />
<Reference Include="YamlDotNet" HintPath="$(EXILED_REFERENCES)\YamlDotNet.dll" Private="false" />
<Reference Include="System.Collections.Immutable">
<HintPath>$(EXILED_REFERENCES)\System.Collections.Immutable.dll</HintPath>
</Reference>
</ItemGroup>

<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resources?


<ItemGroup>
<PackageReference Include="System.Collections.Immutable" Version="8.0.0" />
</ItemGroup>

<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
<PostBuildEvent>if not "$(EXILED_DEV_REFERENCES)"=="" copy /y "$(OutputPath)$(AssemblyName).dll" "$(EXILED_DEV_REFERENCES)\Plugins\"</PostBuildEvent>
</PropertyGroup>
<PropertyGroup Condition=" '$(OS)' == 'Unix' ">
<PostBuildEvent>if [[ ! -z "$EXILED_DEV_REFERENCES" ]]; then cp "$(OutputPath)$(AssemblyName).dll" "$EXILED_DEV_REFERENCES/Plugins/"; fi</PostBuildEvent>
</PropertyGroup>

</Project>
9 changes: 9 additions & 0 deletions Exiled.Hints/HintConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Exiled.API.Interfaces;

namespace Exiled.Hints;

public class HintConfig : IConfig
{
public bool IsEnabled { get; set; }
public bool Debug { get; set; }
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing default values here

38 changes: 38 additions & 0 deletions Exiled.Hints/HintModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Exiled.API.Features;
using Exiled.CustomModules.API.Features;
using HarmonyLib;

namespace Exiled.Hints
{
public class CustomHints : CustomModule
{
public override string Name { get; set; } = "CustomHints";
public override uint Id { get; set; }
public override bool IsEnabled { get; set; }
public override ModulePointer Config { get; set; }
}

public class CustomHintsPlugin : Plugin<HintConfig>
{

private Harmony harmony;

public override void OnEnabled()
{
harmony = new Harmony("exiled.hints");
if (CustomHints.OnEnabled.BoundDelegates.ContainsKey(this)) return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return under the if

CustomHints.OnEnabled += OnModuleEnable;
CustomHints.OnDisabled += OnModuleDisable;
}

private void OnModuleEnable(ModuleInfo info)
{
harmony.PatchAll();
}

private void OnModuleDisable(ModuleInfo info)
{
harmony.UnpatchAll();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

harmony.UnpatchAll(harmony.Id)

}
}
Loading
Loading