diff --git a/RueI/Main.cs b/RueI/Main.cs
index 0b0e086..e673dfc 100644
--- a/RueI/Main.cs
+++ b/RueI/Main.cs
@@ -1,6 +1,5 @@
namespace RueI;
-using System.Reflection;
using System.Runtime.CompilerServices;
/*********\
diff --git a/RueI/RueI/Displays/AutoGiving/AutoGivers.cs b/RueI/RueI/Displays/AutoGiving/AutoGivers.cs
index 31334e5..82ba14f 100644
--- a/RueI/RueI/Displays/AutoGiving/AutoGivers.cs
+++ b/RueI/RueI/Displays/AutoGiving/AutoGivers.cs
@@ -3,6 +3,7 @@
using PlayerRoles;
using RueI.Displays;
+using RueI.Displays.Scheduling;
using RueI.Elements;
///
@@ -27,12 +28,16 @@ public record ElemRefResolver(IElemReference elemRef, Func creator)
///
public class AutoElement
{
+ private record PeriodicUpdate(TimeSpan time, int priority, JobToken token);
+
private static readonly List AutoGivers = new();
private readonly Element? element;
private readonly Func? creator;
- private readonly IElemReference? reference;
+ private readonly IElemReference reference;
+
+ private PeriodicUpdate? periodicUpdate;
static AutoElement()
{
@@ -58,10 +63,12 @@ private AutoElement(Roles roles, IElemReference reference, Func class.
///
/// The to use for the .
+ /// The to use.
/// The element to automatically give.
- private AutoElement(Roles roles, Element element)
+ private AutoElement(Roles roles, IElemReference reference, Element element)
{
this.element = element;
+ this.reference = reference;
Roles = roles;
AutoGivers.Add(this);
@@ -82,7 +89,7 @@ private AutoElement(Roles roles, Element element)
public static AutoElement Create(Roles roles, T element)
where T : Element
{
- return new AutoElement(roles, element);
+ return new AutoElement(roles, DisplayCore.GetReference(), element);
}
///
@@ -90,13 +97,12 @@ public static AutoElement Create(Roles roles, T element)
///
/// The type of the .
/// The to use for the .
- /// The to use.
/// A that creates the elements.
/// A new .
- public static AutoElement Create(Roles roles, IElemReference reference, Func creator)
+ public static AutoElement Create(Roles roles, Func creator)
where T : Element
{
- return new AutoElement(roles, reference, (core) => creator(core));
+ return new AutoElement(roles, DisplayCore.GetReference(), (core) => creator(core));
}
///
@@ -107,22 +113,37 @@ public virtual void Disable()
AutoGivers.Remove(this);
}
+ ///
+ /// Schedules an update for all players with one of the every .
+ ///
+ /// How often to schedule an update.
+ /// The priority of the update.
+ /// A reference to this .
+ public AutoElement UpdateEvery(TimeSpan span, int priority = 35)
+ {
+ periodicUpdate = new(span, priority, new());
+ return this;
+ }
+
///
/// Gives this to a .
///
/// The to give to.
protected virtual void GiveTo(DisplayCore core)
{
+ ServerConsole.AddLog("Hello");
if (element != null)
{
- if (!core.AnonymousDisplay.Elements.Contains(element))
- {
- core.AnonymousDisplay.Elements.Add(element);
- }
+ core.AddAsReference(reference, element);
}
else
{
- core.AddAsReference(reference!, creator!(core));
+ core.AddAsReference(reference, creator!(core));
+ }
+
+ if (periodicUpdate != null)
+ {
+ ScheduleUpdate(core, periodicUpdate);
}
}
@@ -132,13 +153,11 @@ protected virtual void GiveTo(DisplayCore core)
/// The to give to.
protected virtual void RemoveFrom(DisplayCore core)
{
- if (element != null)
- {
- core.AnonymousDisplay.Elements.Remove(element);
- }
- else
+ core.RemoveReference(reference);
+
+ if (periodicUpdate != null)
{
- core.RemoveReference(reference!);
+ core.Scheduler.KillJob(periodicUpdate.token);
}
}
@@ -156,9 +175,16 @@ private static void OnRoleChanged(ReferenceHub hub, PlayerRoleBase prevRole, Pla
}
else
{
-
+ autoElement.RemoveFrom(core);
}
}
+
+ core.Update(35);
}
}
+
+ private static void ScheduleUpdate(DisplayCore core, PeriodicUpdate update)
+ {
+ core.Scheduler.Schedule(update.time, () => ScheduleUpdate(core, update), update.token);
+ }
}
\ No newline at end of file
diff --git a/RueI/RueI/Displays/AutoGiving/Roles.cs b/RueI/RueI/Displays/AutoGiving/Roles.cs
index 03b0926..a09d0c2 100644
--- a/RueI/RueI/Displays/AutoGiving/Roles.cs
+++ b/RueI/RueI/Displays/AutoGiving/Roles.cs
@@ -5,6 +5,11 @@
///
/// Provides a means for describing multiple s.
///
+///
+/// The purpose of the enum is to enable roles to be treated like a enum. Normally,
+/// cannot be treated like bit flags, so this acts as a fast and convenient way to do so.
+///
+///
[Flags]
public enum Roles
{
diff --git a/RueI/RueI/Displays/Display.cs b/RueI/RueI/Displays/Display.cs
index 51e34c2..2ebf58a 100644
--- a/RueI/RueI/Displays/Display.cs
+++ b/RueI/RueI/Displays/Display.cs
@@ -5,9 +5,9 @@
using RueI.Displays.Interfaces;
///
-/// Represents a display attached to a .
+/// Represents a basic display attached to a .
///
-///
+///
public class Display : DisplayBase, IElementContainer
{
///
diff --git a/RueI/RueI/Displays/DisplayCore.cs b/RueI/RueI/Displays/DisplayCore.cs
index 1bc8b49..73dd8c0 100644
--- a/RueI/RueI/Displays/DisplayCore.cs
+++ b/RueI/RueI/Displays/DisplayCore.cs
@@ -5,7 +5,7 @@
using RueI.Extensions;
///
-/// Is responsible for managing all of the s for a .
+/// Manages all of the s for a .
///
public class DisplayCore
{
@@ -33,7 +33,6 @@ protected DisplayCore(ReferenceHub hub)
}
Scheduler = new(this);
- AnonymousDisplay = new(this);
}
///
@@ -46,11 +45,6 @@ protected DisplayCore(ReferenceHub hub)
///
internal static Dictionary DisplayCores { get; } = new();
- ///
- /// Gets a display of anonymous s added to this display.
- ///
- internal Display AnonymousDisplay { get; }
-
///
/// Gets the that this display is for.
///
@@ -96,6 +90,7 @@ public static IElemReference GetReference()
/// The priority of the update - defaults to 100.
public void Update(int priority = 100)
{
+ ServerConsole.AddLog("updating");
if (IgnoreUpdate)
{
return;
@@ -174,6 +169,7 @@ public void RemoveReference(IElemReference reference)
internal void InternalUpdate()
{
string text = ElemCombiner.Combine(GetAllElements());
+ ServerConsole.AddLog(text);
UnityAlternative.Provider.ShowHint(Hub, text);
Events.Events.OnDisplayUpdated(new(this));
}
diff --git a/RueI/RueI/Displays/ElemCombiner.cs b/RueI/RueI/Displays/ElemCombiner.cs
index 1f3faea..7b2bbf6 100644
--- a/RueI/RueI/Displays/ElemCombiner.cs
+++ b/RueI/RueI/Displays/ElemCombiner.cs
@@ -20,6 +20,7 @@ public static class ElemCombiner
/// A with all of the combined s.
public static string Combine(IEnumerable enumElems)
{
+ ServerConsole.AddLog("hello world!!!");
List elements = ListPool.Shared.Rent(enumElems);
if (!elements.Any())
@@ -32,18 +33,19 @@ public static string Combine(IEnumerable enumElems)
float lastPosition = 0;
float lastOffset = 0;
-
+ ServerConsole.AddLog("im kind of a big deal");
elements.Sort(CompareElement);
for (int i = 0; i < elements.Count; i++)
{
Element curElement = elements[i];
-
+ ServerConsole.AddLog(curElement.ZIndex.ToString());
ParsedData parsedData = curElement.GetParsedData();
+ ServerConsole.AddLog(curElement.ZIndex.ToString());
float funcPos = curElement.GetFunctionalPosition();
if (curElement.Options.HasFlagFast(Elements.Enums.ElementOptions.PreserveSpacing))
{
- funcPos -= parsedData.offset;
+ funcPos -= parsedData.Offset;
}
if (i != 0)
@@ -57,16 +59,18 @@ public static string Combine(IEnumerable enumElems)
totalOffset += funcPos;
}
- sb.Append(parsedData.content);
+ sb.Append(parsedData.Content);
- totalOffset += parsedData.offset;
+ totalOffset += parsedData.Offset;
lastPosition = funcPos;
- lastOffset = parsedData.offset;
+ lastOffset = parsedData.Offset;
+ ServerConsole.AddLog("What the fuck");
}
ListPool.Shared.Return(elements);
sb.Insert(0, $"\n");
sb.Append(Constants.ZeroWidthSpace);
+ ServerConsole.AddLog(sb.ToString());
return StringBuilderPool.Shared.ToStringReturn(sb);
}
diff --git a/RueI/RueI/Displays/IDGenerator.cs b/RueI/RueI/Displays/IDGenerator.cs
index e6e0ea5..9ccc9d3 100644
--- a/RueI/RueI/Displays/IDGenerator.cs
+++ b/RueI/RueI/Displays/IDGenerator.cs
@@ -3,13 +3,16 @@
///
/// Generates new, unique IDs.
///
+///
+/// This class is not thread safe.
+///
internal static class IDGenerator
{
private static int nextID = 0;
///
- /// Gets a new ID.
+ /// Gets a new and unique ID.
///
- /// A new ID.
+ /// A new, unique ID.
internal static int GetID() => nextID++;
}
\ No newline at end of file
diff --git a/RueI/RueI/Displays/Scheduling/JobToken.cs b/RueI/RueI/Displays/Scheduling/JobToken.cs
index e6079b9..03d6a47 100644
--- a/RueI/RueI/Displays/Scheduling/JobToken.cs
+++ b/RueI/RueI/Displays/Scheduling/JobToken.cs
@@ -3,6 +3,10 @@
///
/// Represents a reference to any number of .
///
+///
+/// A provides a unique identifier for a within any number of s. In other words, a can reference multiple (or no) , but only a single with the given can exist in a .
+///
+///
public class JobToken
{
///
diff --git a/RueI/RueI/Displays/Scheduling/RateLimiter.cs b/RueI/RueI/Displays/Scheduling/RateLimiter.cs
index 8023bda..4b05613 100644
--- a/RueI/RueI/Displays/Scheduling/RateLimiter.cs
+++ b/RueI/RueI/Displays/Scheduling/RateLimiter.cs
@@ -1,10 +1,9 @@
-using System.Diagnostics;
-
-namespace RueI.Displays.Scheduling;
+namespace RueI.Displays.Scheduling;
///
/// Provides a way to ratelimit actions or detect ratelimits.
///
+///
public class RateLimiter
{
private DateTimeOffset lastConsumed = DateTime.UtcNow;
diff --git a/RueI/RueI/Displays/Scheduling/Records/ScheduledJob.cs b/RueI/RueI/Displays/Scheduling/Records/ScheduledJob.cs
index 09093e3..c8b3948 100644
--- a/RueI/RueI/Displays/Scheduling/Records/ScheduledJob.cs
+++ b/RueI/RueI/Displays/Scheduling/Records/ScheduledJob.cs
@@ -5,6 +5,8 @@
///
/// Defines a scheduled job for a .
///
+///
+///
public class ScheduledJob : IComparable
{
///
diff --git a/RueI/RueI/Displays/Scheduling/Scheduler.cs b/RueI/RueI/Displays/Scheduling/Scheduler.cs
index d6ae45e..09374f5 100644
--- a/RueI/RueI/Displays/Scheduling/Scheduler.cs
+++ b/RueI/RueI/Displays/Scheduling/Scheduler.cs
@@ -1,6 +1,5 @@
namespace RueI.Displays.Scheduling;
-using NorthwoodLib.Pools;
using Utils.NonAllocLINQ;
using eMEC;
@@ -10,9 +9,11 @@
///
/// Provides a means of doing batch operations.
///
+///
+/// The is a powerful class that enables "batch operations". This means that multiple updates to a display can happen at once, helping to avoid the hint ratelimit.
+///
public class Scheduler
{
-
private static readonly TimeSpan MinimumBatch = TimeSpan.FromMilliseconds(625);
private readonly Cooldown rateLimiter = new();
@@ -69,8 +70,11 @@ public static DateTimeOffset CalculateWeighted(IEnumerable jobs)
/// The job to schedule.
public void Schedule(ScheduledJob job)
{
- jobs.Add(job);
- UpdateBatches();
+ if (job.Token == null || !jobs.Any(x => x.Token == job.Token))
+ {
+ jobs.Add(job);
+ UpdateBatches();
+ }
}
///
@@ -157,7 +161,7 @@ private void UpdateBatches()
jobs.Sort();
currentBatches.Clear();
- List currentBatch = ListPool.Shared.Rent(10);
+ List currentBatch = new();
DateTimeOffset currentBatchTime = jobs.First().FinishAt + MinimumBatch;
foreach (ScheduledJob job in jobs)
@@ -170,9 +174,10 @@ private void UpdateBatches()
{
BatchJob finishedBatch = new(currentBatch, CalculateWeighted(currentBatch));
currentBatches.Add(finishedBatch);
- currentBatch = ListPool.Shared.Rent(10);
-
- currentBatch.Add(job);
+ currentBatch = new()
+ {
+ job,
+ };
}
}
@@ -184,7 +189,7 @@ private void UpdateBatches()
}
TimeSpan performAt = (currentBatches.First().PerformAt - Now).MaxIf(rateLimiter.Active, rateLimiter.TimeLeft);
-
+ ServerConsole.AddLog("Starting");
performTask.Start(performAt, PerformFirstBatch);
}
@@ -202,7 +207,6 @@ private void PerformFirstBatch()
}
coordinator.IgnoreUpdate = false;
- ListPool.Shared.Return(batchJob.Jobs);
currentBatches.RemoveAt(0);
rateLimiter.Start(Constants.HintRateLimit);
diff --git a/RueI/RueI/Displays/Scheduling/TimeElemRef.cs b/RueI/RueI/Displays/Scheduling/TimedElemRef.cs
similarity index 70%
rename from RueI/RueI/Displays/Scheduling/TimeElemRef.cs
rename to RueI/RueI/Displays/Scheduling/TimedElemRef.cs
index 46986c5..93a948b 100644
--- a/RueI/RueI/Displays/Scheduling/TimeElemRef.cs
+++ b/RueI/RueI/Displays/Scheduling/TimedElemRef.cs
@@ -6,6 +6,7 @@
/// Represents a with an associated .
///
/// The type of the element.
+/// A is an that also provides a , allowing for both of these to be easily stored together.
public class TimedElemRef : IElemReference
where T : Element
{
diff --git a/RueI/RueI/EffectApplier.cs b/RueI/RueI/EffectApplier.cs
deleted file mode 100644
index 2d22100..0000000
--- a/RueI/RueI/EffectApplier.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace RueI.Displays;
-
-///
-/// Provides a means of doing batch operations.
-///
-public class EffectApplier
-{
-}
diff --git a/RueI/RueI/Elements/DynamicElement.cs b/RueI/RueI/Elements/DynamicElement.cs
index 6d0da2f..5c3d1ec 100644
--- a/RueI/RueI/Elements/DynamicElement.cs
+++ b/RueI/RueI/Elements/DynamicElement.cs
@@ -29,5 +29,5 @@ public DynamicElement(GetContent contentGetter, float position)
public GetContent ContentGetter { get; set; }
///
- protected internal override ParsedData GetParsedData() => Parser.Parse(ContentGetter());
+ protected internal override ParsedData GetParsedData() => Parser.Parse(ContentGetter(), Options);
}
\ No newline at end of file
diff --git a/RueI/RueI/Elements/Element.cs b/RueI/RueI/Elements/Element.cs
index 76f1610..c15c554 100644
--- a/RueI/RueI/Elements/Element.cs
+++ b/RueI/RueI/Elements/Element.cs
@@ -5,7 +5,7 @@ namespace RueI.Elements;
using RueI.Parsing.Records;
///
-/// Represents the base interface for all elements.
+/// Represents the base class for all elements, which are individual 'hints' present within an arbitrary number of s.
///
public abstract class Element
{
@@ -42,7 +42,7 @@ public Element(float position)
///
/// Gets or sets the options for this element.
///
- public ElementOptions Options { get; set; } = ElementOptions.Default;
+ public virtual ElementOptions Options { get; set; } = ElementOptions.Default;
///
/// Gets the data used for parsing.
diff --git a/RueI/RueI/Elements/Enums/ElementOptions.cs b/RueI/RueI/Elements/Enums/ElementOptions.cs
index baea0a9..2aea36a 100644
--- a/RueI/RueI/Elements/Enums/ElementOptions.cs
+++ b/RueI/RueI/Elements/Enums/ElementOptions.cs
@@ -7,9 +7,9 @@
public enum ElementOptions
{
///
- /// Indicates whether or not noparse ignores escape sequences like \r, \u, and \n.
+ /// Indicates whether or not noparse parses escape sequences like \r, \u, and \n.
///
- NoparseIgnoresEscape = 1 << 0,
+ NoparseParsesEscape = 1 << 0,
///
/// Indicates whether or not the vertical spacing of an element affects the baseline.
@@ -24,10 +24,10 @@ public enum ElementOptions
///
/// Gets the default element settings.
///
- Default = NoparseIgnoresEscape,
+ Default = 0,
///
/// Gets the vanilla options for hints.
///
- Vanilla = PreserveSpacing,
+ Vanilla = PreserveSpacing | UseFunctionalPosition | NoparseParsesEscape,
}
\ No newline at end of file
diff --git a/RueI/RueI/Elements/Interfaces/ISettable.cs b/RueI/RueI/Elements/Interfaces/ISettable.cs
index 805a10f..fdba420 100644
--- a/RueI/RueI/Elements/Interfaces/ISettable.cs
+++ b/RueI/RueI/Elements/Interfaces/ISettable.cs
@@ -1,13 +1,12 @@
namespace RueI.Elements.Interfaces;
///
-/// Defines an element that can be set.
+/// Defines an that can be set.
///
public interface ISettable
{
///
- /// Sets the content of this element.
+ /// Gets or sets the content of this element.
///
- /// The new element.
- public void Set(string text);
+ public string Content { get; set; }
}
diff --git a/RueI/RueI/Elements/SetElement.cs b/RueI/RueI/Elements/SetElement.cs
index 6ee6d4e..ff1d6c5 100644
--- a/RueI/RueI/Elements/SetElement.cs
+++ b/RueI/RueI/Elements/SetElement.cs
@@ -1,5 +1,6 @@
namespace RueI.Elements;
+using RueI.Elements.Enums;
using RueI.Elements.Interfaces;
using RueI.Parsing;
using RueI.Parsing.Records;
@@ -9,8 +10,6 @@ namespace RueI.Elements;
///
public class SetElement : Element, ISettable
{
- private ParsedData data;
-
///
/// Initializes a new instance of the class.
///
@@ -20,18 +19,14 @@ public SetElement(float position, string content = "")
: base(position)
{
Position = position;
- data = Parser.Parse(content);
+ Content = content;
}
///
- /// Sets the content of this element.
+ /// Gets or sets the content of this element.
///
- /// The text to set the content to (will be parsed).
- public virtual void Set(string content)
- {
- data = Parser.Parse(content);
- }
+ public virtual string Content { get; set; }
///
- protected internal override ParsedData GetParsedData() => data;
+ protected internal override ParsedData GetParsedData() => Parser.Parse(Content, Options);
}
\ No newline at end of file
diff --git a/RueI/RueI/Extensions/DisplayCoreExtensions.cs b/RueI/RueI/Extensions/DisplayCoreExtensions.cs
index 458a2ad..82c6ffe 100644
--- a/RueI/RueI/Extensions/DisplayCoreExtensions.cs
+++ b/RueI/RueI/Extensions/DisplayCoreExtensions.cs
@@ -22,7 +22,7 @@ public static void SetElementOrNew(this DisplayCore core, IElemReference
public static class HintBuilding
{
+ ///
+ /// Represents all of the options for the alignment of a string of text.
+ ///
+ public enum AlignStyle
+ {
+ ///
+ /// Indicates that the text should be left-aligned.
+ ///
+ Left,
+
+ ///
+ /// Indicates that the text should be center-aligned.
+ ///
+ Center,
+
+ ///
+ /// Indicates that the text should be right-aligned.
+ ///
+ Right,
+
+ ///
+ /// Indicates that every line should be stretched to fill the display area, excluding the last line.
+ ///
+ Justified,
+
+ ///
+ /// Indicates that every line should be stretched to fill the display area. This includes the last line.
+ ///
+ Flush,
+ }
+
///
/// Converts a to a hex code string.
///
@@ -33,6 +64,26 @@ public static string ConvertToHex(Color color)
/// A reference to the original .
public static StringBuilder AddLinebreak(this StringBuilder sb) => sb.Append('\n');
+ ///
+ /// Adds an alignment tag to a .
+ ///
+ /// The to use.
+ /// The to use.
+ /// A reference to the original .
+ public static StringBuilder SetAlignment(this StringBuilder sb, AlignStyle align)
+ {
+ string alignment = align switch
+ {
+ AlignStyle.Left => "left",
+ AlignStyle.Right => "right",
+ AlignStyle.Justified => "justified",
+ AlignStyle.Flush => "flush",
+ _ => "center",
+ };
+
+ return sb.Append($"");
+ }
+
///
/// Adds a size tag to a .
///
@@ -416,6 +467,13 @@ public static StringBuilder AddVOffset(this StringBuilder sb, float offset, Meas
/// A reference to the original .
public static StringBuilder CloseColor(this StringBuilder sb) => sb.Append("");
+ ///
+ /// Adds a closing align tag to a .
+ ///
+ /// The to use.
+ /// A reference to the original .
+ public static StringBuilder CloseAlign(this StringBuilder sb) => sb.Append("");
+
///
/// Adds a closing alpha tag to a .
///
diff --git a/RueI/RueI/Parsing/Parser.cs b/RueI/RueI/Parsing/Parser.cs
index b7149bb..f179040 100644
--- a/RueI/RueI/Parsing/Parser.cs
+++ b/RueI/RueI/Parsing/Parser.cs
@@ -5,16 +5,23 @@
using System.Text;
using NorthwoodLib.Pools;
-
+using RueI.Elements.Enums;
+using RueI.Extensions;
using RueI.Parsing.Enums;
using RueI.Parsing.Records;
using RueI.Parsing.Tags.ConcreteTags;
///
-/// Helps parse the content of elements.
+/// Helps parse the content of elements. This class cannot be inherited.
///
+///
+/// The is a sealed, immutable class that provides APIs for parsing (extracting the information of) hints so that
+/// multiple can be displayed at once, along with the ability to add new s. In order to create new s,
+/// you must use the class.
+///
///
-public class Parser
+///
+public sealed class Parser
{
///
/// Initializes a new instance of the class.
@@ -51,7 +58,8 @@ internal Parser(IEnumerable tags, IEnumerable backups)
///
/// The context of the parser.
/// The character to add.
- public static void AddCharacter(ParserContext context, char ch)
+ /// Whether or not the character should be appended to the 's .
+ public static void AddCharacter(ParserContext context, char ch, bool append = true)
{
float size = CalculateCharacterLength(context, ch);
@@ -83,6 +91,11 @@ public static void AddCharacter(ParserContext context, char ch)
context.BiggestCharSize = context.Size;
}
}
+
+ if (append)
+ {
+ context.ResultBuilder.Append(ch);
+ }
}
///
@@ -210,9 +223,11 @@ public static bool GetTagAttributes(string content, out Dictionary
/// The string to parse.
+ /// The options of the element.
/// A containing information about the string.
- public ParsedData Parse(string text)
+ public ParsedData Parse(string text, ElementOptions options = ElementOptions.Default)
{
+ ServerConsole.AddLog("what");
ParserState currentState = ParserState.CollectingTags;
StringBuilder tagBuffer = StringBuilderPool.Shared.Rent(Constants.MAXTAGNAMESIZE);
@@ -235,17 +250,17 @@ void FailTagMatch() // not a tag, unload buffer
AddCharacter(context, ch);
}
- foreach (char ch in paramBuffer.ToString())
- {
- AddCharacter(context, ch);
- }
-
if (delimiter != null)
{
AddCharacter(context, delimiter.Value);
delimiter = null;
}
+ foreach (char ch in paramBuffer.ToString())
+ {
+ AddCharacter(context, ch);
+ }
+
tagBuffer.Clear();
paramBuffer.Clear();
@@ -257,6 +272,7 @@ void FailTagMatch() // not a tag, unload buffer
char[] chars = text.ToCharArray();
for (int i = 0; i < chars.Length; i++)
{
+ ServerConsole.AddLog(chars[i].ToString());
char ch = chars[i];
if (ch == '\\')
@@ -274,27 +290,34 @@ void FailTagMatch() // not a tag, unload buffer
// detect if an escape sequence is escaped by backslashes
if ((i - original) % 3 == 0)
{
- switch (chars[i])
+ if (context.ShouldParse || options.HasFlagFast(ElementOptions.NoparseParsesEscape))
{
- case 'n':
- CreateLineBreak(context);
- i++;
- break;
- case 'r':
- context.CurrentLineWidth = 0;
- i++;
- break;
- case 'u':
- context.ResultBuilder.Append('\\'); // TODO: add support for unicode literals
- break;
- default:
- break;
+ switch (chars[i])
+ {
+ case 'n':
+ CreateLineBreak(context);
+ i++;
+ break;
+ case 'r':
+ context.CurrentLineWidth = 0;
+ i++;
+ break;
+ case 'u':
+ context.ResultBuilder.Append('\\'); // TODO: add support for unicode literals
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ context.ResultBuilder.Append('\\');
}
}
for (int newIndex = 0; newIndex < times; newIndex++)
{
- AddCharacter(context, chars[i + newIndex]);
+ AddCharacter(context, chars[i + newIndex], false);
}
}
else if (ch == '<') // indicates start of tag
@@ -337,6 +360,13 @@ void FailTagMatch() // not a tag, unload buffer
if (context.ShouldParse || tag is CloseNoparseTag)
{
tag!.HandleTag(context, string.Empty);
+
+ tagBuffer.Clear();
+ paramBuffer.Clear();
+
+ currentTag = null;
+ currentState = ParserState.CollectingTags;
+ tagBufferSize = 0;
continue;
}
else
@@ -396,6 +426,8 @@ void FailTagMatch() // not a tag, unload buffer
delimiter = null;
currentState = ParserState.CollectingTags;
tagBufferSize = 0;
+
+ continue;
}
else
{
@@ -434,7 +466,7 @@ void FailTagMatch() // not a tag, unload buffer
/// Avoids the client TMP matching a tag.
///
/// The context of the parser.
- private static void AvoidMatch(ParserContext context) => context.ResultBuilder.Append("");
+ private static void AvoidMatch(ParserContext context) => context.ResultBuilder.Append(context.IsBold ? "" : "");
///
/// Tries to get a for the given name and .
diff --git a/RueI/RueI/Parsing/ParserContext.cs b/RueI/RueI/Parsing/ParserContext.cs
index 8da4b1b..440af21 100644
--- a/RueI/RueI/Parsing/ParserContext.cs
+++ b/RueI/RueI/Parsing/ParserContext.cs
@@ -39,7 +39,7 @@ public class ParserContext : TextInfo, IDisposable
///
/// Gets the current functional width of the text.
///
- public float FunctionalWidth => DisplayAreaWidth - this.LeftMargin - this.RightMargin;
+ public float FunctionalWidth => DisplayAreaWidth - LeftMargin - RightMargin;
///
/// Gets a stack containing all of the nested sizes.
@@ -141,6 +141,7 @@ public void AddEndingTag(bool allowDuplicates = false)
public void RemoveEndingTag()
where T : NoParamsTag, new()
{
+ ServerConsole.AddLog("doing the thing lol");
endingTags.Remove(SharedTag.Singleton);
}
diff --git a/RueI/RueI/Parsing/Records/ParsedData.cs b/RueI/RueI/Parsing/Records/ParsedData.cs
index cba6a83..900df6a 100644
--- a/RueI/RueI/Parsing/Records/ParsedData.cs
+++ b/RueI/RueI/Parsing/Records/ParsedData.cs
@@ -1,8 +1,39 @@
namespace RueI.Parsing.Records;
///
-/// Defines a record that contains information used for displaying multiple elements.
+/// Defines a class that contains parsed information about a single element, used for displaying multiple at a time.
///
-/// The element's content.
-/// The offset that should be applied. Equivalent to the total linebreaks within the element.
-public record ParsedData(string content, float offset);
+public class ParsedData
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The element's content.
+ /// The offset that should be applied. Equivalent to the total linebreaks within the element.
+ internal ParsedData(string content, float offset)
+ {
+ Content = content;
+ Offset = offset;
+ }
+
+ ///
+ /// Gets the content of the element.
+ ///
+ public string Content { get; }
+
+ ///
+ /// Gets the offset that should be applied to the element.
+ ///
+ public float Offset { get; }
+
+ ///
+ /// Deconstructs this .
+ ///
+ /// The returned new content of the element.
+ /// The returned offset of the element.
+ public void Deconstruct(out string content, out float offset)
+ {
+ content = Content;
+ offset = Offset;
+ }
+}
diff --git a/RueI/RueI/Parsing/Tags/ClosingTag{T}.cs b/RueI/RueI/Parsing/Tags/ClosingTag{T}.cs
index 5ce3723..6e104cd 100644
--- a/RueI/RueI/Parsing/Tags/ClosingTag{T}.cs
+++ b/RueI/RueI/Parsing/Tags/ClosingTag{T}.cs
@@ -19,7 +19,6 @@ public abstract class ClosingTag : NoParamsTag
public sealed override bool HandleTag(ParserContext context)
{
ApplyTo(context);
-
context.ResultBuilder.Append($"<{Name}>");
context.RemoveEndingTag();
return true;
diff --git a/RueI/RueI/Parsing/Tags/ConcreteTags/AlignTag.cs b/RueI/RueI/Parsing/Tags/ConcreteTags/AlignTag.cs
index a438910..c99ed45 100644
--- a/RueI/RueI/Parsing/Tags/ConcreteTags/AlignTag.cs
+++ b/RueI/RueI/Parsing/Tags/ConcreteTags/AlignTag.cs
@@ -9,7 +9,7 @@
public class AlignTag : RichTextTag
{
///
- public override string[] Names { get; } = { "scale" };
+ public override string[] Names { get; } = { "align" };
///
public override TagStyle TagStyle { get; } = TagStyle.ValueParam;
diff --git a/RueI/RueI/Parsing/Tags/NoParamsTag.cs b/RueI/RueI/Parsing/Tags/NoParamsTag.cs
index 68f5eb0..46a6633 100644
--- a/RueI/RueI/Parsing/Tags/NoParamsTag.cs
+++ b/RueI/RueI/Parsing/Tags/NoParamsTag.cs
@@ -11,7 +11,7 @@ public abstract class NoParamsTag : RichTextTag
public sealed override TagStyle TagStyle { get; } = TagStyle.NoParams;
///
- public sealed override bool HandleTag(ParserContext context, string parameters) => HandleTag(context, string.Empty);
+ public sealed override bool HandleTag(ParserContext context, string parameters) => HandleTag(context);
///
/// Applies this tag (without parameters) to a .
diff --git a/RueI/RueI/Utility.cs b/RueI/RueI/Utility.cs
index ab5f7f4..372b281 100644
--- a/RueI/RueI/Utility.cs
+++ b/RueI/RueI/Utility.cs
@@ -12,7 +12,7 @@ public static class Ruetility
/// The cleaned string.
public static string GetCleanText(string text)
{
- string cleanText = text.Replace("", ""); // zero width space is inserted
+ string cleanText = text.Replace("", "rse>");
return $"{cleanText}";
}
diff --git a/RueI/UnityAlternative.cs b/RueI/UnityAlternative.cs
index 6453cb0..50a6d3c 100644
--- a/RueI/UnityAlternative.cs
+++ b/RueI/UnityAlternative.cs
@@ -158,7 +158,21 @@ public class UnityProvider : UnityAlternative
public override IAsyncOperation PerformAsync(TimeSpan span, Action action) => new MECAsyncOperation(span, action);
///
- internal override void ShowHint(ReferenceHub hub, string message) => hub.connectionToClient.Send(new HintMessage(new TextHint(message, new HintParameter[] { new StringHintParameter(message) }, new HintEffect[] { HintEffectPresets.FadeIn(0, 0, 1) }, 99999)));
+ internal override void ShowHint(ReferenceHub hub, string message)
+ {
+ ServerConsole.AddLog("Showing");
+
+ string docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+
+ // Append text to an existing file named "WriteLines.txt".
+ using (StreamWriter outputFile = new(Path.Combine(docPath, "hello.txt"), true))
+ {
+ outputFile.WriteLine(message);
+ }
+
+ hub.connectionToClient.Send(new HintMessage(new TextHint(message, new HintParameter[] { new StringHintParameter(message) }, null, 99999)));
+ Log(message);
+ } // HintEffectPresets.FadeIn(0, 0, 1)
///
/// Represents an async operation using a .
diff --git a/RueI/docs.xml b/RueI/docs.xml
index 4e0b326..cee5eff 100644
--- a/RueI/docs.xml
+++ b/RueI/docs.xml
@@ -13,22 +13,41 @@
-
-
-
- This example demonstrates creating and using a .
-
- Display display = new(referenceHub); // Create a new display from a
-
- SetElement helloElem = new(300, zIndex: 10, "hello").AddTo(display);
- SetElement worldElem = new(250, zIndex: 10, "world").AddTo(display);
- display.Elements.Add(helloElem, worldElem);
+
+
+
+
+ This example shows how can be used to perform bitfield operations with s.
+
+ // the | (pipe) is the bitwise OR operator
+ // it combines the bits of all of the provided fields
+ // 1010 | 1100 -> 1110
+ Roles roles = Roles.CivilianRoles | Roles.FacilityGuard | Roles.ScpsNo0492; // all things that can spawn in at the start of the game
- display.Update(); // Update the display
-
-
-
-
+ // using RueI.Extensions.HasFlagFast because it is much quicker
+ roles.HasFlagFast(Roles.ChaosRifleman); // -> false
+ roles.HasFlagFast(Roles.Scientist); // -> true
+
+
+
+
+
+
+
+ This example demonstrates creating and using a .
+
+ Display display = new(referenceHub); // Create a new display from a ReferenceHub
+
+ SetElement helloElem = new(300, zIndex: 10, "hello").AddTo(display);
+ SetElement worldElem = new(250, zIndex: 10, "world").AddTo(display);
+ display.Elements.Add(helloElem, worldElem);
+
+ display.Update(); // Update the display
+
+
+
+
+