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

2024.3.5.3 #53

Merged
merged 14 commits into from
Apr 10, 2024
24 changes: 24 additions & 0 deletions Modules/GameEventHistory/Event.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Text;

namespace TownOfHost.Modules.GameEventHistory;

public abstract class Event : IHistoryEvent
{
public DateTime UtcTime { get; }
public abstract string Bullet { get; }
protected Event()
{
UtcTime = DateTime.UtcNow;
}

public abstract void AppendDiscordString(StringBuilder builder);

protected void AppendPlayerWithEmoji(StringBuilder builder, EventCommittedPlayer player, bool isAlive)
{
builder.Append(Utils.ColorIdToDiscordEmoji(player.ColorId, isAlive));
builder.Append(" **");
builder.Append(player.Name);
builder.Append("**");
}
}
13 changes: 13 additions & 0 deletions Modules/GameEventHistory/EventCommittedPlayer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using TownOfHost.Roles.Core;

namespace TownOfHost.Modules.GameEventHistory;

public readonly struct EventCommittedPlayer(string name, byte playerId, int colorId, CustomRoles roleId)
{
public string Name { get; init; } = name;
public byte PlayerId { get; init; } = playerId;
public int ColorId { get; init; } = colorId;
public CustomRoles RoleId { get; init; } = roleId;

public EventCommittedPlayer(PlayerControl playerControl) : this(playerControl.GetRealName(), playerControl.PlayerId, playerControl.Data.DefaultOutfit.ColorId, playerControl.GetCustomRole()) { }
}
46 changes: 46 additions & 0 deletions Modules/GameEventHistory/EventHistory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Text;
using TownOfHost.Attributes;

namespace TownOfHost.Modules.GameEventHistory;

public sealed class EventHistory : IHistoryEvent
{
public static EventHistory CurrentInstance { get; private set; }

[GameModuleInitializer]
public static void NewGame()
{
CurrentInstance = new();
}

private readonly List<Event> events = [];

public void AddEvent(Event @event)
{
events.Add(@event);
}
public void AppendDiscordString(StringBuilder builder)
{
foreach (var @event in events)
{
builder.Append(@event.Bullet);
builder.Append(' ');
builder.Append("<t:");
var unixTime = (long)@event.UtcTime.Subtract(Epoch).TotalSeconds;
builder.Append(unixTime);
builder.Append(":T> ");
@event.AppendDiscordString(builder);
builder.AppendLine();
}
}
public string ToDiscordString()
{
var builder = new StringBuilder();
AppendDiscordString(builder);
return builder.ToString();
}

private readonly static DateTime Epoch = new(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
}
15 changes: 15 additions & 0 deletions Modules/GameEventHistory/Events/CrewTaskFinishEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Text;

namespace TownOfHost.Modules.GameEventHistory.Events;

public sealed class CrewTaskFinishEvent(EventCommittedPlayer player) : Event
{
public override string Bullet { get; } = ":blue_circle:";
public EventCommittedPlayer Player { get; } = player;

public override void AppendDiscordString(StringBuilder builder)
{
builder.Append("**タスク完了:** ");
AppendPlayerWithEmoji(builder, Player, true);
}
}
15 changes: 15 additions & 0 deletions Modules/GameEventHistory/Events/GameEndEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Text;

namespace TownOfHost.Modules.GameEventHistory.Events;

public sealed class GameEndEvent(string winsText) : Event
{
public override string Bullet { get; } = ":green_circle:";
public string WinsText { get; } = winsText;

public override void AppendDiscordString(StringBuilder builder)
{
builder.Append("**ゲーム終了:** ");
builder.Append(WinsText);
}
}
13 changes: 13 additions & 0 deletions Modules/GameEventHistory/Events/GameStartEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Text;

namespace TownOfHost.Modules.GameEventHistory.Events;

public sealed class GameStartEvent : Event
{
public override string Bullet { get; } = ":green_circle:";

public override void AppendDiscordString(StringBuilder builder)
{
builder.Append("**ゲーム開始**");
}
}
39 changes: 39 additions & 0 deletions Modules/GameEventHistory/Events/MeetingCallEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Text;

namespace TownOfHost.Modules.GameEventHistory.Events;

public sealed class MeetingCallEvent(EventCommittedPlayer reporter) : Event
{
public override string Bullet { get; } = ":green_circle:";
public EventCommittedPlayer Reporter { get; } = reporter;
public EventCommittedPlayer? Dead { get; } = null;

public MeetingCallEvent(EventCommittedPlayer reporter, EventCommittedPlayer dead) : this(reporter)
{
Dead = dead;
}

public override void AppendDiscordString(StringBuilder builder)
{
if (Dead.HasValue)
{
AppendDiscordReport(builder);
}
else
{
AppendDiscordEmergency(builder);
}
}
private void AppendDiscordReport(StringBuilder builder)
{
builder.Append("**通報:** ");
AppendPlayerWithEmoji(builder, Reporter, true);
builder.Append(" → ");
AppendPlayerWithEmoji(builder, Dead.Value, false);
}
private void AppendDiscordEmergency(StringBuilder builder)
{
builder.Append("**緊急会議:** ");
AppendPlayerWithEmoji(builder, Reporter, true);
}
}
27 changes: 27 additions & 0 deletions Modules/GameEventHistory/Events/MeetingEndEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Text;

namespace TownOfHost.Modules.GameEventHistory.Events;

public sealed class MeetingEndEvent() : Event
{
public override string Bullet { get; } = ":green_circle:";
public EventCommittedPlayer? Exiled { get; } = null;

public MeetingEndEvent(EventCommittedPlayer exiled) : this()
{
Exiled = exiled;
}

public override void AppendDiscordString(StringBuilder builder)
{
builder.Append("**会議結果:** 追放者 ");
if (Exiled.HasValue)
{
AppendPlayerWithEmoji(builder, Exiled.Value, false);
}
else
{
builder.Append("なし");
}
}
}
40 changes: 40 additions & 0 deletions Modules/GameEventHistory/Events/MurderEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Text;
using TownOfHost.Roles.Core;

namespace TownOfHost.Modules.GameEventHistory.Events;

public sealed class MurderEvent(EventCommittedPlayer killer, EventCommittedPlayer victim, SystemTypes room) : Event
{
public override string Bullet { get; } = killer.RoleId is CustomRoles.Sheriff ? ":yellow_square:" : ":red_square:";
public EventCommittedPlayer Killer { get; } = killer;
public EventCommittedPlayer Victim { get; } = victim;
public SystemTypes Room { get; } = room;

public override void AppendDiscordString(StringBuilder builder)
{
if (Killer.PlayerId == Victim.PlayerId)
{
AppendDiscordSuicide(builder);
}
else
{
AppendDiscordMurder(builder);
}
}
private void AppendDiscordSuicide(StringBuilder builder)
{
builder.Append("**自爆:** ");
AppendPlayerWithEmoji(builder, Killer, false);
builder.Append(" @");
builder.Append(DestroyableSingleton<TranslationController>.Instance.GetString(Room));
}
private void AppendDiscordMurder(StringBuilder builder)
{
builder.Append("**キル:** ");
AppendPlayerWithEmoji(builder, Killer, true);
builder.Append(" → ");
AppendPlayerWithEmoji(builder, Victim, false);
builder.Append(" @");
builder.Append(DestroyableSingleton<TranslationController>.Instance.GetString(Room));
}
}
18 changes: 18 additions & 0 deletions Modules/GameEventHistory/Events/RevengeEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text;

namespace TownOfHost.Modules.GameEventHistory.Events;

public sealed class RevengeEvent(EventCommittedPlayer cat, EventCommittedPlayer victim) : Event
{
public override string Bullet { get; } = ":red_circle:";
public EventCommittedPlayer Cat { get; } = cat;
public EventCommittedPlayer Victim { get; } = victim;

public override void AppendDiscordString(StringBuilder builder)
{
builder.Append("**道連れ:** ");
AppendPlayerWithEmoji(builder, Cat, true);
builder.Append(" → ");
AppendPlayerWithEmoji(builder, Victim, false);
}
}
21 changes: 21 additions & 0 deletions Modules/GameEventHistory/Events/RoleChangeEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Text;
using TownOfHost.Roles.Core;

namespace TownOfHost.Modules.GameEventHistory.Events;

public sealed class RoleChangeEvent(EventCommittedPlayer player, CustomRoles to) : Event
{
public override string Bullet { get; } = ":green_circle:";
public EventCommittedPlayer Player { get; } = player;
public CustomRoles To { get; } = to;

public override void AppendDiscordString(StringBuilder builder)
{
builder.Append("**ロール変更:** ");
AppendPlayerWithEmoji(builder, Player, true);
builder.Append(" ");
builder.Append(Translator.GetRoleString(Player.RoleId.ToString()));
builder.Append(" → ");
builder.Append(Translator.GetRoleString(To.ToString()));
}
}
8 changes: 8 additions & 0 deletions Modules/GameEventHistory/IHistoryEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Text;

namespace TownOfHost.Modules.GameEventHistory;

public interface IHistoryEvent
{
public void AppendDiscordString(StringBuilder builder);
}
7 changes: 6 additions & 1 deletion Modules/GameState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

using TownOfHost.Attributes;
using TownOfHost.Roles.Core;
using TownOfHost.Modules.GameEventHistory;
using TownOfHost.Modules.GameEventHistory.Events;

namespace TownOfHost
{
Expand Down Expand Up @@ -98,9 +100,12 @@ public void RemoveSubRole(CustomRoles role)
}
public void ChangeMainRole(CustomRoles role)
{
var player = Utils.GetPlayerById(PlayerId);

EventHistory.CurrentInstance?.AddEvent(new RoleChangeEvent(new(player), role));

this.PreviousRoles.Add(this.MainRole);
this.SetMainRole(role);
var player = Utils.GetPlayerById(PlayerId);
player.GetRoleClass()?.Dispose();
CustomRoleManager.CreateInstance(role, player);
}
Expand Down
5 changes: 5 additions & 0 deletions Modules/MeetingVoteManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Linq;
using System.Collections.Generic;
using TownOfHost.Roles.Core;
using TownOfHost.Modules.GameEventHistory;
using TownOfHost.Modules.GameEventHistory.Events;

namespace TownOfHost.Modules;

Expand Down Expand Up @@ -112,6 +114,9 @@ public void CheckAndEndMeeting()
public void EndMeeting(bool applyVoteMode = true)
{
var result = CountVotes(applyVoteMode);

EventHistory.CurrentInstance?.AddEvent(result.Exiled == null ? new MeetingEndEvent() : new MeetingEndEvent(new(result.Exiled.Object)));

var logName = result.Exiled == null ? (result.IsTie ? "同数" : "スキップ") : result.Exiled.Object.GetNameWithRole();
logger.Info($"追放者: {logName} で会議を終了します");

Expand Down
44 changes: 0 additions & 44 deletions Modules/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1130,50 +1130,6 @@ public static void FlashColor(Color color, float duration = 1f)
obj.GetComponent<SpriteRenderer>().color = new(color.r, color.g, color.b, Mathf.Clamp01((-2f * Mathf.Abs(t - 0.5f) + 1) * color.a)); //アルファ値を0→目標→0に変化させる
})));
}
public static void MakeWebhookUrlFile()
{
Logger.Info("WebhookUrl.txtを作成", "Webhook");
try
{
File.WriteAllText("WebhookUrl.txt", "この文章を削除してウェブフックのURLを記述/Remove this text and enter Webhook url");
}
catch (Exception ex)
{
Logger.Error(ex.ToString(), "Webhook");
}
}
public static void SendWebhook(string text, string userName = "Town Of Host")
{
if (!File.Exists("WebhookUrl.txt"))
MakeWebhookUrlFile();
HttpClient client = new();
Dictionary<string, string> message = new()
{
{ "content", text },
{ "username", userName },
{ "avatar_url", "https://raw.githubusercontent.com/tukasa0001/TownOfHost/main/Resources/TabIcon_MainSettings.png" }
};
using StreamReader sr = new("WebhookUrl.txt", Encoding.UTF8);
string webhookUrl = sr.ReadLine();
if (!Regex.IsMatch(webhookUrl, "^(https://(ptb.|canary.)?discord(app)?.com/api/webhooks/)")) // ptbとcanaryとappはあってもなくてもいい
{
Logger.Info("WebhookUrl.txtの内容がdiscordのウェブフックurlではなかったためウェブフックの送信をキャンセル", "Webhook");
return;
}
try
{
TaskAwaiter<HttpResponseMessage> awaiter = client.PostAsync(webhookUrl, new FormUrlEncodedContent(message)).GetAwaiter();
var response = awaiter.GetResult();
Logger.Info("ウェブフックを送信しました", "Webhook");
if (!response.IsSuccessStatusCode)
Logger.Warn("応答が異常です", "Webhook");
Logger.Info($"{(int)response.StatusCode} {response.ReasonPhrase}", "Webhook"); // 正常な応答: 204 No Content
}
catch (Exception ex)
{
Logger.Error(ex.ToString(), "Webhook");
}
}
public static string ColorIdToDiscordEmoji(int colorId, bool alive)
{
if (alive)
Expand Down
Loading