Skip to content
Open
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
21 changes: 21 additions & 0 deletions MiraAPI.Example/CustomChats/ExampleCustomChat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using MiraAPI.CustomChats;
using MiraAPI.Utilities.Assets;
using UnityEngine;

namespace MiraAPI.Example.CustomChats;

public class ExampleCustomChat : AbstractCustomChat
{
public override string Name => "Example Chat";

public override Color ChatBackgroundColor => Color.yellow;

public override LoadableResourceAsset ChatIcon => ExampleAssets.TeleportButton;

public override ChatButtonSprites Sprites => new();

public override bool CanSee()
{
return true;
}
}
32 changes: 32 additions & 0 deletions MiraAPI.Example/CustomChats/ExampleCustomChat2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using MiraAPI.CustomChats;
using MiraAPI.Utilities.Assets;
using UnityEngine;

namespace MiraAPI.Example.CustomChats;

public class ExampleCustomChat2 : AbstractCustomChat
{
public override string Name => "The chat for the mute";

public override Color ChatBackgroundColor => Color.gray;

public override LoadableResourceAsset ChatIcon => ExampleAssets.ExampleButton;

public override ChatButtonSprites Sprites => new()
{
ActiveSprite = ExampleAssets.CallMeetingButton,
InactiveSprite = ExampleAssets.ExampleButton,
OpenedSprite = ExampleAssets.TeleportButton,
NotificationSprite = ExampleAssets.BlueChatBubble,
};

public override bool CanSee()
{
return true;
}

public override bool CanSendMessage()
{
return false;
}
}
1 change: 1 addition & 0 deletions MiraAPI.Example/ExampleAssets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public static class ExampleAssets
// Credit to EpicHorrors for the teleport button asset.
public static LoadableResourceAsset TeleportButton { get; } = new("MiraAPI.Example.Resources.TeleportButton.png");
public static LoadableResourceAsset Banner { get; } = new("MiraAPI.Example.Resources.FortniteBanner.jpeg");
public static LoadableResourceAsset BlueChatBubble { get; } = new("MiraAPI.Example.Resources.BlueChatBubble.png");
}
Binary file added MiraAPI.Example/Resources/BlueChatBubble.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
101 changes: 101 additions & 0 deletions MiraAPI/CustomChats/AbstractCustomChat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using MiraAPI.Utilities.Assets;
using UnityEngine;

namespace MiraAPI.CustomChats;

/// <summary>
/// abstract Class for creating custom chats.
/// </summary>
public abstract class AbstractCustomChat
{
/// <summary>
/// Gets the name of the custom chat.
/// </summary>
public abstract string Name { get; }

/// <summary>
/// Gets the <see cref="Color"/> which the chat background will use.
/// </summary>
public abstract Color ChatBackgroundColor { get; }

/// <summary>
/// Gets the <see cref="LoadableAsset"/> which is used for the chat icon.

Check warning on line 22 in MiraAPI/CustomChats/AbstractCustomChat.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has cref attribute 'LoadableAsset' that could not be resolved
/// </summary>
public abstract LoadableAsset<Sprite> ChatIcon { get; }

/// <summary>
/// Gets the <see cref="ChatButtonSprites"/> which is used for changing the chat button's visual appearance.
/// </summary>
public abstract ChatButtonSprites Sprites { get; }

/// <summary>
/// Gets the audio <see cref="LoadableAsset"/> which is played when a message is sent, if null, it will fall back to the default sound.

Check warning on line 32 in MiraAPI/CustomChats/AbstractCustomChat.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has cref attribute 'LoadableAsset' that could not be resolved
/// </summary>
public virtual LoadableAsset<AudioClip>? MessageSound { get; } = null!;

/// <summary>
/// Determines if the local player can view this chat.
/// </summary>
/// <returns>True if they can view it, false otherwise.</returns>
public abstract bool CanSee();

/// <summary>
/// Determines if the local player can send messages in this chat.
/// </summary>
/// <returns>True if they can send messages, false otherwise.</returns>
public virtual bool CanSendMessage()
{
return CanSee();
}

/// <summary>
/// Callback method for when a message is sent in this custom chat.
/// </summary>
/// <param name="sourcePlayer">The <see cref="PlayerControl"/> who sent the message (can be null when a warning message is sent!).</param>
/// <param name="bubble">the <see cref="ChatBubble"/> instance.</param>
public virtual void OnMessageSent(PlayerControl? sourcePlayer, ChatBubble bubble)
{
}

/// <summary>
/// Callback method for when this chat is being opened.
/// </summary>
/// <param name="chat">The <see cref="ChatController"/> instance.</param>
public virtual void OnChatOpen(ChatController chat)
{
}

/// <summary>
/// Callback method for when this chat is being closed.
/// </summary>
/// <param name="chat">The <see cref="ChatController"/> instance.</param>
public virtual void OnChatClose(ChatController chat)
{
}
}

/// <summary>
/// a Class for defining how the chat button looks.
/// </summary>
public class ChatButtonSprites
{
/// <summary>
/// Gets the inactive <see cref="LoadableAsset"/> for the Chat Button.

Check warning on line 83 in MiraAPI/CustomChats/AbstractCustomChat.cs

View workflow job for this annotation

GitHub Actions / build

XML comment has cref attribute 'LoadableAsset' that could not be resolved
/// </summary>
public LoadableAsset<Sprite> InactiveSprite = MiraAssets.NormalChatIdle;

/// <summary>
/// Gets the active <see cref="LoadableAsset"/> for the Chat Button.
/// </summary>
public LoadableAsset<Sprite> ActiveSprite = MiraAssets.NormalChatHover;

/// <summary>
/// Gets the opened <see cref="LoadableAsset"/> for the Chat Button.
/// </summary>
public LoadableAsset<Sprite> OpenedSprite = MiraAssets.NormalChatOpen;

/// <summary>
/// Gets the notification dot <see cref="LoadableAsset"/> for the Chat Button.
/// </summary>
public LoadableAsset<Sprite> NotificationSprite = MiraAssets.ChatNormalBubble;
}
30 changes: 30 additions & 0 deletions MiraAPI/CustomChats/CustomChatManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using MiraAPI.PluginLoading;

namespace MiraAPI.CustomChats;

/// <summary>
/// Manages custom chats.
/// </summary>
public static class CustomChatManager
{
/// <summary>
/// Gets a list of all registered <see cref="AbstractCustomChat"/>s.
/// </summary>
public static readonly List<AbstractCustomChat> Chats = [new DefaultChat()];

internal static bool RegisterCustomChat(Type type, MiraPluginInfo info)
{
if (!typeof(AbstractCustomChat).IsAssignableFrom(type))
{
return false;
}

AbstractCustomChat? chat = Activator.CreateInstance(type) as AbstractCustomChat;
if (chat == null) return false;
Chats.Add(chat);
info.InternalChats.Add(chat);
return true;
}
}
19 changes: 19 additions & 0 deletions MiraAPI/CustomChats/CustomChatSingleton.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Linq;

namespace MiraAPI.CustomChats;

/// <summary>
/// Singleton for accessing custom chats.
/// </summary>
/// <typeparam name="T">The custom chat type.</typeparam>
public static class CustomChatSingleton<T> where T : AbstractCustomChat
{
private static T? _instance;

/// <summary>
/// Gets the instance of the option group.
/// </summary>
#pragma warning disable CA1000
public static T Instance => _instance ??= CustomChatManager.Chats.OfType<T>().Single();
#pragma warning restore CA1000
}
26 changes: 26 additions & 0 deletions MiraAPI/CustomChats/DefaultChat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using MiraAPI.CustomChats;
using MiraAPI.Utilities.Assets;
using UnityEngine;

namespace MiraAPI.CustomChats;

/// <summary>
/// The default <see cref="AbstractCustomChat"/>.
/// </summary>
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public class DefaultChat : AbstractCustomChat
{
public override string Name => "Default Chat";

public override Color ChatBackgroundColor => Color.white;

public override LoadableResourceAsset ChatIcon => MiraAssets.DefaultChatIcon;

public override ChatButtonSprites Sprites => new();

public override bool CanSee()
{
return true;
}
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
38 changes: 38 additions & 0 deletions MiraAPI/Networking/CustomChatConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using Hazel;
using InnerNet;
using MiraAPI.CustomChats;
using MiraAPI.Modifiers;
using Reactor.Networking.Attributes;
using Reactor.Networking.Serialization;

namespace MiraAPI.Networking;

/// <summary>
/// Converter for serializing and deserializing <see cref="AbstractCustomChat"/> objects.
/// </summary>
[MessageConverter]
public class CustomChatConverter : MessageConverter<AbstractCustomChat>
{
/// <summary>
/// Writes a <see cref="AbstractCustomChat"/> to the writer.
/// </summary>
/// <param name="writer">The writer to write to.</param>
/// <param name="value">The <see cref="AbstractCustomChat"/> to write.</param>
public override void Write(MessageWriter writer, AbstractCustomChat value)
{
writer.Write(CustomChatManager.Chats.IndexOf(value));
}

/// <summary>
/// Reads a <see cref="AbstractCustomChat"/> from the reader.
/// </summary>
/// <param name="reader">The reader to read from.</param>
/// <param name="objectType">The type of the object to read.</param>
/// <returns>The <see cref="AbstractCustomChat"/> that was read.</returns>
/// <exception cref="InvalidOperationException">Thrown if the custom chat is not found.</exception>
public override AbstractCustomChat Read(MessageReader reader, Type objectType)
{
return CustomChatManager.Chats[reader.ReadInt32()];
}
}
23 changes: 23 additions & 0 deletions MiraAPI/Networking/CustomSendChatRpc.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using MiraAPI.CustomChats;
using MiraAPI.Utilities;
using Reactor.Networking.Attributes;
using Reactor.Networking.Rpc;

namespace MiraAPI.Networking;

/// <summary>
/// Custom SendChat RPC adapted for custom chats.
/// </summary>
public static class CustomSendChatRpc
{
[MethodRpc((uint)MiraRpc.SendChat, LocalHandling = RpcLocalHandling.Before)]
public static void RpcCustomSendChat(
this PlayerControl source,
string chatText,
AbstractCustomChat chat)
{
if (!chat.CanSee()) return;

HudManager.Instance.Chat.CustomAddChat(source, chatText, chat);
}
}
5 changes: 5 additions & 0 deletions MiraAPI/Networking/MiraRpc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,9 @@ public enum MiraRpc : uint
/// Custom RPC to replace Among Us CastVote.
/// </summary>
CastVote,

/// <summary>
/// Custom RPC to replace Among Us SendChat.
/// </summary>
SendChat,
}
Loading
Loading