Skip to content
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
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
* text=auto eol=crlf

###############################################################################
# Set default behavior for command prompt diff.
Expand Down
1 change: 1 addition & 0 deletions Werewolf for Telegram/Database/Group.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public Group()
public int Id { get; set; }
public string Name { get; set; }
public long GroupId { get; set; }
public Nullable<int> GroupTopicId { get; set; }
public Nullable<bool> Preferred { get; set; }
public string Language { get; set; }
public Nullable<bool> DisableNotification { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion Werewolf for Telegram/Database/WerewolfModel.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Werewolf for Telegram/Database/WerewolfModel.edmx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
<Property Name="Id" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="Name" Type="nvarchar(max)" Nullable="false" />
<Property Name="GroupId" Type="bigint" Nullable="false" />
<Property Name="GroupTopicId" Type="int" />
<Property Name="Preferred" Type="bit" />
<Property Name="Language" Type="nvarchar(max)" />
<Property Name="DisableNotification" Type="bit" />
Expand Down Expand Up @@ -884,6 +885,7 @@ warning 6002: The table/view 'werewolf.dbo.v_IdleKill24HoursMain' does not have
<Property Name="Id" Type="Int32" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Name="Name" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" Nullable="false" />
<Property Name="GroupId" Type="Int64" Nullable="false" />
<Property Name="GroupTopicId" Type="Int32" />
<Property Name="Preferred" Type="Boolean" />
<Property Name="Language" Type="String" MaxLength="Max" FixedLength="false" Unicode="true" />
<Property Name="DisableNotification" Type="Boolean" />
Expand Down Expand Up @@ -1664,6 +1666,7 @@ warning 6002: The table/view 'werewolf.dbo.v_IdleKill24HoursMain' does not have
<ScalarProperty Name="Id" ColumnName="Id" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="GroupId" ColumnName="GroupId" />
<ScalarProperty Name="GroupTopicId" ColumnName="GroupTopicId" />
<ScalarProperty Name="Preferred" ColumnName="Preferred" />
<ScalarProperty Name="Language" ColumnName="Language" />
<ScalarProperty Name="DisableNotification" ColumnName="DisableNotification" />
Expand Down Expand Up @@ -2176,4 +2179,4 @@ warning 6002: The table/view 'werewolf.dbo.v_IdleKill24HoursMain' does not have
<!-- Diagram content (shape and connector positions) -->
<Diagrams></Diagrams>
</Designer>
</edmx:Edmx>
</edmx:Edmx>
5 changes: 5 additions & 0 deletions Werewolf for Telegram/Werewolf Control/Attributes/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,10 @@ public class Command : Attribute
/// Can this command be run by anonymous admins in groups
/// </summary>
public bool AllowAnonymousAdmins { get; set; } = false;

/// <summary>
/// Allow commands to be run outside configured topic in group.
/// </summary>
public bool AllowOutsideConfiguredTopic {get; set; } = false;
}
}
110 changes: 109 additions & 1 deletion Werewolf for Telegram/Werewolf Control/Commands/AdminCommands.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Database;
using Database;
using Newtonsoft.Json;
using System;
using System.Collections;
Expand All @@ -23,6 +23,114 @@ namespace Werewolf_Control
{
public static partial class Commands
{
[Attributes.Command(Trigger = "setgrouptopic", GroupAdminOnly = true, InGroupOnly = true)]
public static void SetGroupTopic(Update update, string[] args)
{
long chatId = update.Message.Chat.Id;
int? topicId = update.Message.MessageThreadId;

int? currentTopicId;

using (var db = new WWContext())
{
currentTopicId = db.Groups
.Where(g => g.GroupId == chatId)
.Select(g => g.GroupTopicId)
.FirstOrDefault();
}

bool inGeneralTopic = topicId == null || topicId == 0;

string infoText = $"Current Topic ID: `{(currentTopicId.HasValue ? currentTopicId.Value.ToString() : "None")}`\n\n";

if (inGeneralTopic)
{
infoText += "This message is in the general topic (no thread ID).\n" +
"You cannot set this as the group topic. Only specific threads can be set.";
}
else
{
infoText += $"> You are currently inside topic ID: `{topicId}`.\n" +
"Choose what you'd like to do:";
}

var buttons = new List<InlineKeyboardButton[]>();

if (!inGeneralTopic)
{
buttons.Add(new[]{
InlineKeyboardButton.WithCallbackData("Set Topic", "setgrouptopic_cmd|set"),
});
}

buttons.Add(new[]{
InlineKeyboardButton.WithCallbackData("Unset Topic", "setgrouptopic_cmd|unset")
});


var inlineKeyboard = new InlineKeyboardMarkup(buttons);

Bot.Send(
infoText,
chatId,
customMenu: inlineKeyboard,
parseMode: ParseMode.Markdown,
messageThreadId: topicId,
forceTopic: false // TODO: use this param in other admin cmd, cmd which admin are allowed to use anywhere
);
}

internal static void SetGroupTopicCallback(CallbackQuery query)
{
var chatId = query.Message.Chat.Id;
var topicId = query.Message.MessageThreadId;

using (var db = new WWContext())
{
var group = db.Groups.FirstOrDefault(g => g.GroupId == chatId);
if (group == null)
{
group = MakeDefaultGroup(chatId, query.Message.Chat.Title, "setgrouptopic_callback");
db.Groups.Add(group);
}

string[] args = query.Data.Split('|');
string action = args.Length > 1 ? args[1] : "";

switch (action)
{
case "set":
if (topicId == null)
{
Bot.ReplyToCallback(query, "This must be used inside a topic/thread.");
return;
}

group.GroupTopicId = topicId;
db.SaveChanges();

Bot.Api.EditMessageTextAsync(chatId, query.Message.MessageId,
"Group topic has been set successfully.");
break;

case "unset":
group.GroupTopicId = null;
db.SaveChanges();

Bot.Api.EditMessageTextAsync(chatId, query.Message.MessageId,
"Group topic has been unset.");
break;

default:
Bot.ReplyToCallback(query, "Invalid topic action.");
break;
}

Bot.Api.AnswerCallbackQueryAsync(query.Id);
}
}


[Attributes.Command(Trigger = "smite", GroupAdminOnly = true, Blockable = true, InGroupOnly = true, AllowAnonymousAdmins = true)]
public static void Smite(Update u, string[] args)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@ public static void Extend(Update update, string[] args)
}
}

[Command(Trigger = "stopwaiting", Blockable = true)]
// allowing outside topic, as it doesn't response into topic command was ran. dm user that their next game notification is turned off
[Command(Trigger = "stopwaiting", Blockable = true, AllowOutsideConfiguredTopic = true)]
public static void StopWaiting(Update update, string[] args)
{
long groupid = 0;
Expand Down
50 changes: 47 additions & 3 deletions Werewolf for Telegram/Werewolf Control/Commands/GeneralCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ public static void SetLang(Update update, string[] args)
var curLangFileName = GetLanguage(update.Message.From.Id);
var curLang = langs.First(x => x.FileName == curLangFileName);
Bot.Api.SendTextMessageAsync(chatId: update.Message.From.Id, text: GetLocaleString("WhatLang", curLangFileName, curLang.Base),
replyMarkup: menu);
replyMarkup: menu, messageThreadId: update.Message.MessageThreadId);
if (update.Message.Chat.Type != ChatType.Private)
Send(GetLocaleString("SentPrivate", GetLanguage(update.Message.From.Id)), update.Message.Chat.Id);
Send(GetLocaleString("SentPrivate", GetLanguage(update.Message.From.Id)), update.Message.Chat.Id, messageThreadId: update.Message.MessageThreadId);
}

[Command(Trigger = "start")]
Expand Down Expand Up @@ -239,8 +239,44 @@ public static void Start(Update u, string[] args)
return;
}

// check for force join
bool isForceJoin = false;
if (args[1].StartsWith("forcejoin"))
{
isForceJoin = true;
// remove "force" from starting, so below if statement work for force join also
args[1] = args[1].Substring("force".Length);
}

// handle join command
if (args[1].StartsWith("join") && args[1].Length == 48) // 4 "join" + 22 node id + 22 game id
{
// check if user have validate name
bool isValid;
string msg;
(isValid, msg) = ValidatePlayerName(p.Name);
if(!isValid && !isForceJoin)
{


// TODO: move to string xml file for translation support
string warningMsg = "⚠️ If you join the game using the button below, you can join successfully, " +
"but you may receive a warning if your name is unreadable or invalid.";


string forceJoinURI = $"https://t.me/{Bot.Me.Username}/?start={"force" + args[1]}";

// send user messaage
Bot.Send(msg+"\n\n"+warningMsg, u.Message.Chat.Id, customMenu: new InlineKeyboardMarkup(new[]
{
new[]
{
InlineKeyboardButton.WithUrl("Force Join Game", forceJoinURI)
}
}));
return;
}

//okay, they are joining a game.
string nodeid = "";
string gameid = "";
Expand Down Expand Up @@ -340,6 +376,14 @@ public static void Start(Update u, string[] args)
}

game.AddPlayer(u, gameid);

// notify group about force join
if (isForceJoin) {
// TODO: move to strings xml for translation support
string forceJoinNotice = $"⚠️ Player with name '[{p.Name}](tg://user?id={p.TelegramId})' used force join button, their name is detected as unreadable by bot.";

Bot.Send(forceJoinNotice, game.GroupId, parseMode: ParseMode.Markdown);
}
return;
}
catch (AggregateException e)
Expand Down Expand Up @@ -581,7 +625,7 @@ public static void MyIdles(Update update, string[] args)

try
{
var result = Bot.Api.SendTextMessageAsync(chatId: update.Message.From.Id, text: reply).Result;
var result = Bot.Api.SendTextMessageAsync(chatId: update.Message.From.Id, text: reply, messageThreadId: update.Message.MessageThreadId).Result;
if (update.Message.Chat.Type != ChatType.Private)
Send(GetLocaleString("SentPrivate", GetLanguage(update.Message.From.Id)), update.Message.Chat.Id);
}
Expand Down
22 changes: 11 additions & 11 deletions Werewolf for Telegram/Werewolf Control/Commands/GifCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static void Donate(Update u, string[] args)
{
// Donations disabled as of 2024-06-08
var link = $"<a href=\"https://t.me/greywolfdev/1318\">currently disabled</a>";
Bot.Api.SendTextMessageAsync(chatId: u.Message.Chat.Id, text: $"Donations are {link}, sorry!", parseMode: ParseMode.Html, disableWebPagePreview: true).Wait();
Bot.Api.SendTextMessageAsync(chatId: u.Message.Chat.Id, text: $"Donations are {link}, sorry!", parseMode: ParseMode.Html, disableWebPagePreview: true, messageThreadId: u.Message.MessageThreadId).Wait();
return;

//Bot.Api.SendTextMessageAsync(u.Message.Chat.Id,
Expand Down Expand Up @@ -106,7 +106,7 @@ public static void SetCustomGifs(Update u, string[] args)
"\n\n" +
"PLEASE NOTE: Changing any gifs will automatically remove the approval for your pack, and an admin will need to approve it again\n" +
"Let's begin! Select the situation you want to set a gif for",
replyMarkup: GetGifMenu(data));
replyMarkup: GetGifMenu(data), messageThreadId: u.Message.MessageThreadId);

var msg = "Current Approval Status:\n";
switch (data.Approved)
Expand All @@ -123,7 +123,7 @@ public static void SetCustomGifs(Update u, string[] args)
msg += "Disapproved By " + dby.Name + " for: " + data.DenyReason;
break;
}
Bot.Send(msg, u.Message.From.Id);
Bot.Send(msg, u.Message.From.Id, messageThreadId: u.Message.MessageThreadId);
}

}
Expand Down Expand Up @@ -304,7 +304,7 @@ public static void RequestGif(CallbackQuery q)
Bot.Api.SendTextMessageAsync(chatId: q.From.Id,
text: q.Data.Split('|')[1] + "\nOk, send me the GIF you want to use for this situation, as a reply\n" +
"#" + choice,
replyMarkup: new ForceReplyMarkup());
replyMarkup: new ForceReplyMarkup(), messageThreadId: q.Message.MessageThreadId);
}

public static void AddGif(Message m)
Expand Down Expand Up @@ -337,14 +337,14 @@ public static void AddGif(Message m)
"users are unable to view them, we require you to use telegram's " +
"[new GIFs in .mp4 format](https://telegram.org/blog/gif-revolution). " +
"To fix this, try reuploading the GIF, your telegram app should then render it as .mp4. " +
"Please send me the GIF you want to use for this situation, as a reply\n#" + gifchoice, replyMarkup: new ForceReplyMarkup(), parseMode: ParseMode.Markdown);
"Please send me the GIF you want to use for this situation, as a reply\n#" + gifchoice, replyMarkup: new ForceReplyMarkup(), parseMode: ParseMode.Markdown, messageThreadId: m.MessageThreadId);
return;
}
if (m.Animation.FileSize >= 1048576) // Maximum size is 1 MB
{
Bot.Api.SendTextMessageAsync(chatId: m.From.Id, text: "This GIF is too large, the maximum allowed size is 1MB.\n\n" +
"Please send me the GIF you want to use for this situation, as a reply\n#" + gifchoice,
replyMarkup: new ForceReplyMarkup());
replyMarkup: new ForceReplyMarkup(), messageThreadId: m.MessageThreadId);
return;
}

Expand Down Expand Up @@ -431,7 +431,7 @@ public static void GetXsollaLink(CallbackQuery q = null, Message m = null)
{
// Donations disabled as of 2024-06-08
var link = $"<a href=\"https://t.me/greywolfdev/1318\">currently disabled</a>";
Bot.Api.SendTextMessageAsync(chatId: (q?.Message ?? m).Chat.Id, text: $"Donations are {link}, sorry!", parseMode: ParseMode.Html, disableWebPagePreview: true).Wait();
Bot.Api.SendTextMessageAsync(chatId: (q?.Message ?? m).Chat.Id, text: $"Donations are {link}, sorry!", parseMode: ParseMode.Html, disableWebPagePreview: true, messageThreadId: (q?.Message ?? m).MessageThreadId).Wait();
return;

var from = q?.From ?? m?.From;
Expand Down Expand Up @@ -465,13 +465,13 @@ public static void GetDonationInfo(CallbackQuery q = null, Message m = null)
{
// Donations disabled as of 2024-06-08
var link = $"<a href=\"https://t.me/greywolfdev/1318\">currently disabled</a>";
Bot.Api.SendTextMessageAsync(chatId: q?.From.Id ?? m.From.Id, text: $"Donations are {link}, sorry!", parseMode: ParseMode.Html, disableWebPagePreview: true).Wait();
Bot.Api.SendTextMessageAsync(chatId: q?.From.Id ?? m.From.Id, text: $"Donations are {link}, sorry!", parseMode: ParseMode.Html, disableWebPagePreview: true, messageThreadId: q.Message.MessageThreadId).Wait();
return;

var menu = new Menu();
Bot.Api.SendTextMessageAsync(chatId: q?.From.Id ?? m.From.Id,
text: "How much would you like to donate? Please enter a whole number, in US Dollars (USD), in reply to this message",
replyMarkup: new ForceReplyMarkup());
replyMarkup: new ForceReplyMarkup(), messageThreadId: (q?.Message ?? m).MessageThreadId);
}

public static void ValidateDonationAmount(Message m)
Expand All @@ -488,14 +488,14 @@ public static void ValidateDonationAmount(Message m)
var api = RegHelper.GetRegValue("MainStripeProdAPI");
#endif
Bot.Api.SendInvoiceAsync(chatId: m.From.Id, title: "Werewolf Donation", description: "Make a donation to Werewolf to help keep us online", payload: "somepayloadtest", providerToken: api,
currency: "USD", prices: new[] { new LabeledPrice("Donation", amt * 100) }, startParameter: "donatetg").Wait();
currency: "USD", prices: new[] { new LabeledPrice("Donation", amt * 100) }, startParameter: "donatetg", messageThreadId: m.MessageThreadId).Wait();
}
else
{
Bot.Api.SendTextMessageAsync(chatId: m.From.Id,
text: "Invalid input.\n" +
"How much would you like to donate? Please enter a whole number, in US Dollars (USD), in reply to this message",
replyMarkup: new ForceReplyMarkup());
replyMarkup: new ForceReplyMarkup(), messageThreadId: m.MessageThreadId);
}

}
Expand Down
Loading