PlayerChannel Plugin

This commit is contained in:
linmeideli committed 2026-05-17 18:15:10 +08:00
1 parent 62d3bc0480
commit ebe5bb209d
12 files changed
+325 -2

No files matched your search

Binary file not shown.
+13
View File
@@ -89,6 +89,19 @@
"download_url": "https://raw.githubusercontent.com/Empostor/Empostor/master/marketplace/Impostor.Plugins.Titles.dll"
}
]
},
{
"id": "cn.hayashiume.playerchannel",
"name": "Player Channel",
"description": "using /s <text> to send an only channel message by friendcode",
"author": "HayashiUme",
"versions": [
{
"version": "1.0.0",
"impostor_version": "2.0.0",
"download_url": "https://raw.githubusercontent.com/Empostor/Empostor/master/marketplace/Impostor.Plugins.PlayerChannel.dll"
}
]
},
{
"id": "cn.hayashiume.qqverify",
@@ -150,6 +150,7 @@
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
}
}
},
".NETStandard,Version=v2.0/linux-x64": {}
}
}
+8 -1
View File
@@ -34,6 +34,12 @@
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
}
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[8.0.27, )",
"resolved": "8.0.27",
"contentHash": "rQi9TxifHRnXP7lVRZH05DxD2/XGbJp12q0ozcbrlBlBnyyzssFTH/2vLhtKWUp2CT1qVscTrcYTFiwTyKPKRg=="
},
"StyleCop.Analyzers": {
"type": "Direct",
"requested": "[1.2.0-beta.556, )",
@@ -139,6 +145,7 @@
"NextFast.Hazel.Abstractions": {
"type": "Project"
}
}
},
"net8.0/linux-x64": {}
}
}
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>Impostor.Plugins.PlayerChannel</AssemblyName>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Impostor.Api\Impostor.Api.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Impostor.Api.Commands;
namespace Impostor.Plugins.PlayerChannel;
public sealed class PlayerChannelCommand : ICommand
{
private readonly Dictionary<string, ChannelEntry> _fcToChannel;
public PlayerChannelCommand(PlayerChannelConfig config)
{
_fcToChannel = new Dictionary<string, ChannelEntry>(StringComparer.OrdinalIgnoreCase);
foreach (var channel in config.Channels)
{
foreach (var fc in channel.FriendCodes)
{
if (!string.IsNullOrWhiteSpace(fc))
_fcToChannel[fc] = channel;
}
}
}
public string Name => "s";
public string Description => "Send a message to your player channel.";
public string Usage => "s <message>";
public async ValueTask<bool> ExecuteAsync(CommandContext ctx)
{
var text = ctx.RawArgs;
if (string.IsNullOrWhiteSpace(text))
return false;
var senderFc = ctx.Sender.Client.FriendCode;
if (string.IsNullOrEmpty(senderFc))
{
await ctx.PlayerControl.SendChatToPlayerAsync(
"[Refuse Channel] Unnkown Friendcode", ctx.PlayerControl);
return true;
}
if (!_fcToChannel.TryGetValue(senderFc, out var channel))
{
await ctx.PlayerControl.SendChatToPlayerAsync(
"[Refuse Channel] No exsit in any Channnel", ctx.PlayerControl);
return true;
}
var prefixed = $"[{channel.Name}] {text}";
foreach (var player in ctx.Game.Players)
{
var fc = player.Client.FriendCode;
if (string.IsNullOrEmpty(fc)) continue;
if (!channel.FriendCodes.Contains(fc)) continue;
var targetCtrl = player.Character;
if (targetCtrl == null) continue;
await ctx.PlayerControl.SendChatToPlayerAsync(prefixed, targetCtrl);
}
return true;
}
}
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace Impostor.Plugins.PlayerChannel;
public sealed class PlayerChannelConfig
{
[JsonPropertyName("channels")]
public List<ChannelEntry> Channels { get; set; } = new()
{
new ChannelEntry
{
Name = "Example Channel",
FriendCodes = new List<string> { "kami#1337", "nofinalsus#8469" },
},
};
}
public sealed class ChannelEntry
{
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("friendCodes")]
public List<string> FriendCodes { get; set; } = new();
}
@@ -0,0 +1,24 @@
using System.Threading.Tasks;
using Impostor.Api.Plugins;
using Microsoft.Extensions.Logging;
namespace Impostor.Plugins.PlayerChannel;
[ImpostorPlugin("cn.hayashiume.playerchannel", "Player Channel", "HayashiUme", "1.0.0")]
public sealed class PlayerChannelPlugin : PluginBase
{
private readonly ILogger<PlayerChannelPlugin> _logger;
public PlayerChannelPlugin(ILogger<PlayerChannelPlugin> logger)
{
_logger = logger;
}
public override ValueTask EnableAsync()
{
_logger.LogInformation("[PlayerChannel] Enabled.");
return default;
}
public override ValueTask DisableAsync() => default;
}
@@ -0,0 +1,24 @@
using Impostor.Api.Commands;
using Impostor.Api.Plugins;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Impostor.Plugins.PlayerChannel;
public sealed class PlayerChannelStartup : IPluginStartup
{
private string _configPath = "[Player Channel]Config.json";
public void SetConfigPath(string configPath) => _configPath = configPath;
public void ConfigureHost(IHostBuilder host) { }
public void ConfigureServices(IServiceCollection services)
{
var config = PluginConfigLoader.Load<PlayerChannelConfig>(_configPath);
services.AddSingleton(config);
services.AddSingleton<PlayerChannelCommand>();
services.AddSingleton<ICommand, PlayerChannelCommand>(
sp => sp.GetRequiredService<PlayerChannelCommand>());
}
}
@@ -0,0 +1,137 @@
{
"version": 1,
"dependencies": {
"net8.0": {
"BouncyCastle.Cryptography": {
"type": "Transitive",
"resolved": "2.6.1",
"contentHash": "vZsG2YILhthgRqO+ZVgRff4ZFKKTl0v7kqaVBLCtRvpREhfBP33pcWrdA3PRYgWuFL1RxiUFvjMUHTdBZlJcoA=="
},
"Microsoft.AspNetCore.Http.Abstractions": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "Nxs7Z1q3f1STfLYKJSVXCs1iBl+Ya6E8o4Oy1bCxJ/rNI44E/0f6tbsrVqAWfB7jlnJfyaAtIalBVxPKUPQb4Q==",
"dependencies": {
"Microsoft.AspNetCore.Http.Features": "2.2.0",
"System.Text.Encodings.Web": "4.5.0"
}
},
"Microsoft.AspNetCore.Http.Features": {
"type": "Transitive",
"resolved": "2.2.0",
"contentHash": "ziFz5zH8f33En4dX81LW84I6XrYXKf9jg6aM39cM+LffN9KJahViKZ61dGMSO2gd3e+qe5yBRwsesvyqlZaSMg==",
"dependencies": {
"Microsoft.Extensions.Primitives": "2.2.0"
}
},
"Microsoft.Extensions.Configuration.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "9.0.6",
"contentHash": "0Zn6nR/6g+90MxskZyOOMPQvnPnrrGu6bytPwkV+azDcTtCSuQ1+GJUrg8Klmnrjk1i6zMpw2lXijl+tw7Q3kA=="
},
"Microsoft.Extensions.Diagnostics.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "JHYCQG7HmugNYUhOl368g+NMxYE/N/AiclCYRNlgCY9eVyiBkOHMwK4x60RYMxv9EL3+rmj1mqHvdCiPpC+D4Q==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Options": "8.0.0",
"System.Diagnostics.DiagnosticSource": "8.0.0"
}
},
"Microsoft.Extensions.FileProviders.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "ZbaMlhJlpisjuWbvXr4LdAst/1XxH3vZ6A0BsgTphZ2L4PGuxRLz7Jr/S7mkAAnOn78Vu0fKhEgNF5JO3zfjqQ==",
"dependencies": {
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Hosting.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "AG7HWwVRdCHlaA++1oKDxLsXIBxmDpMPb3VoyOoAghEWnkUvEAdYQUwnV4jJbAaa/nMYNiEh5ByoLauZBEiovg==",
"dependencies": {
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Diagnostics.Abstractions": "8.0.0",
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
"Microsoft.Extensions.Logging.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
}
},
"Microsoft.Extensions.ObjectPool": {
"type": "Transitive",
"resolved": "8.0.1",
"contentHash": "X21b8D6z58EG34OMLH955750mFaEaGs5xLGe9Vyi3059Cgb3sk+p2k/JlQXaieEBRrk+SVlFzDei3Q6PdVzJOA=="
},
"Microsoft.Extensions.Options": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "JOVOfqpnqlVLUzINQ2fox8evY2SKLYJ3BV8QDe/Jyp21u1T7r45x/R/5QdteURMR5r01GxeJSBBUOCOyaNXA3g==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
"Microsoft.Extensions.Primitives": "8.0.0"
}
},
"Microsoft.Extensions.Primitives": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g=="
},
"Serilog": {
"type": "Transitive",
"resolved": "4.3.1-dev-02373",
"contentHash": "f0HNPaleOox5++8zqxAdi9afnUUkoznLOmd0ur/UnLbzl8bIaPyyBGOpbIJmC1kz2vHfkQ0fXh6KXMdlz7bcLQ=="
},
"System.Diagnostics.DiagnosticSource": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ=="
},
"System.Text.Encodings.Web": {
"type": "Transitive",
"resolved": "4.5.0",
"contentHash": "Xg4G4Indi4dqP1iuAiMSwpiWS54ZghzR644OtsRCm/m/lBMG8dUBhLVN7hLm8NNrNTR+iGbshCPTwrvxZPlm4g=="
},
"impostor.api": {
"type": "Project",
"dependencies": {
"Microsoft.AspNetCore.Http.Abstractions": "[2.2.0, )",
"Microsoft.Extensions.Hosting.Abstractions": "[8.0.0, )",
"Microsoft.Extensions.Logging.Abstractions": "[8.0.0, )",
"NextFast.Hazel": "[1.0.2-dev, )",
"NextFast.Hazel.Abstractions": "[1.0.2-dev, )"
}
},
"NextFast.Hazel": {
"type": "Project",
"dependencies": {
"BouncyCastle.Cryptography": "[2.6.1, )",
"Microsoft.Extensions.DependencyInjection.Abstractions": "[9.0.6, )",
"Microsoft.Extensions.ObjectPool": "[8.0.1, )",
"NextFast.Hazel.Abstractions": "[1.0.2-dev, )",
"Serilog": "[4.3.1-dev-02373, )"
}
},
"NextFast.Hazel.Abstractions": {
"type": "Project"
}
}
}
}
+6
View File
@@ -58,6 +58,12 @@
"resolved": "8.0.1",
"contentHash": "X21b8D6z58EG34OMLH955750mFaEaGs5xLGe9Vyi3059Cgb3sk+p2k/JlQXaieEBRrk+SVlFzDei3Q6PdVzJOA=="
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[8.0.27, )",
"resolved": "8.0.27",
"contentHash": "rQi9TxifHRnXP7lVRZH05DxD2/XGbJp12q0ozcbrlBlBnyyzssFTH/2vLhtKWUp2CT1qVscTrcYTFiwTyKPKRg=="
},
"Serilog.Extensions.Hosting": {
"type": "Direct",
"requested": "[8.0.0, )",
+7
View File
@@ -28,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Impostor.Plugins.Titles", "
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Impostor.Plugins.QqVerify", "Impostor.Plugins.QqVerify\Impostor.Plugins.QqVerify.csproj", "{B8A5D7C3-1F4E-4A2B-9C6D-8E3F5A7B1D2E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Impostor.Plugins.PlayerChannel", "Impostor.Plugins.PlayerChannel\Impostor.Plugins.PlayerChannel.csproj", "{D4B6C8A2-5F3E-4C1D-9B7A-6E2F8A4C1D3F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -78,6 +80,10 @@ Global
{B8A5D7C3-1F4E-4A2B-9C6D-8E3F5A7B1D2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8A5D7C3-1F4E-4A2B-9C6D-8E3F5A7B1D2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8A5D7C3-1F4E-4A2B-9C6D-8E3F5A7B1D2E}.Release|Any CPU.Build.0 = Release|Any CPU
{D4B6C8A2-5F3E-4C1D-9B7A-6E2F8A4C1D3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4B6C8A2-5F3E-4C1D-9B7A-6E2F8A4C1D3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4B6C8A2-5F3E-4C1D-9B7A-6E2F8A4C1D3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4B6C8A2-5F3E-4C1D-9B7A-6E2F8A4C1D3F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -91,6 +97,7 @@ Global
{70CD7AC9-1DE3-CD23-602A-EFD504B91450} = {E0009DCB-32A6-45C4-A06C-7F62D4091A29}
{3038597E-E1A1-2958-1CF7-C4203A85F424} = {E0009DCB-32A6-45C4-A06C-7F62D4091A29}
{B8A5D7C3-1F4E-4A2B-9C6D-8E3F5A7B1D2E} = {E0009DCB-32A6-45C4-A06C-7F62D4091A29}
{D4B6C8A2-5F3E-4C1D-9B7A-6E2F8A4C1D3F} = {E0009DCB-32A6-45C4-A06C-7F62D4091A29}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DAF5625C-7E46-4DCC-AF2C-11D20D965454}