siscodeorg / sisbase Goto Github PK
View Code? Open in Web Editor NEWAn easy to use discord bot base for D#+. Discord Link :
Home Page: https://discord.gg/ycvm6xJ
License: MIT License
An easy to use discord bot base for D#+. Discord Link :
Home Page: https://discord.gg/ycvm6xJ
License: MIT License
Proposed implementation: [Vital] attribute
D#+ has some weird design decisions, that had to be completely redesigned on sisbase. If all of DSP's features that we rely upon need complete rework/ constant workarounds it may be beneficial to migrate to another wrapper that provides a purer implementation of the discord api.
This issue was pushed from being a 3.0 Candidate
to a 2.0 Candidate
.
Currently there is no support for Sharding
on a sisbase bot.
DSP has already implemented a DiscordShardedClient
but their implementation would need to be review in order for us to determine if we either just use it or reimplement
it.
Add a SisbaseBot.RegisterCustomConfig<T>(Path) where T:IConfiguration
method so that registering custom configs are easier to the user.
Also look onto converting IConfiguration to an abstract class since most implementations of Create()
and Update()
would look like this :
public void Update() {
File.WriteAllText(Path,JsonConvert.SerializeObject(this,Formatting.Indented));
}
public void Create(string Path) {
if (File.Exists(Path)) {
Data = JsonConvert.DeserializeObject<T>(File.ReadAllText(Path)).Data;
}
else {
//Generate a default.
}
}
The root
of the config.json from 1.0
is the Data
of 2.0 and could easily be converted to.
{
"Token": "token",
"MasterId": 123456789012345678,
"PuppetId": [],
"Prefixes": [
"u!",
"s!"
],
"CustomSettings": {}
}
{
"Path": "C:\\Users\\roridev\\Development\\sisbase\\sisbase.Test\\bin\\Debug\\netcoreapp3.1/Config.json",
"Data": {
"Token": "token",
"MasterId": 123456789012345678,
"PuppetId": [],
"Prefixes": ["s!"],
"CustomSettings": {}
}
}
Suggested default timeout: 5 minutes.
When an interaction expires, it should:
Close
and Dispose
)
Close
be the same as Dispose
? Consider the OnClose
event.Meta-issue with all points on the code base that may need to be looked again. If said issue is big enough another issue may be created because of it. For better organization, new issues must be posted as a comment first then edited on the original message.
Reason : Discord webhook only notifies new comments not edits.
Issues here can range from code quality to major bugs.
NRE
- Can cause / causes a NullReferenceException.
EXC
- Can cause / causes an unhandled exception.
CQ
- Code Quality.
BUG
- Any bug. Includes unexpected behavior.
API
- Issues on the current API design. Should have an proposal that addresses said issue annexed.
Use the copy permalink feature on github and describe the issue on that piece of code.
CQ
| API
- Behaviours
class works like a namespace, unnecessary nesting.
Systems status should be persistent so that disabling a system permanently is possible.
The current license is outdated and relicensing should be considered
Line 3 in 64c33b8
CC BY-NC-SA
Usage: By using InteractionBehaviour.DeleteReaction
As soon as .WaitForReaction
returns said reaction is deleted allowing for multiple button presses.
Another useful behaviour could be DeleteMesage
.
The default behavior would be None
.
Maybe we should remove the string hardcodes from the embedbase, allowing for diferent languages to be used on sisbase?
SystemManager
API specification-- interface IStaticSystem
-- interface IClientSystem
++ abstract class BaseSystem
++ abstract class ClientSystem : BaseSystem
BaseSystem
will expose SisbaseBot SisbaseInstance
ClientSystem
will expose DiscordClient Client
class command : SisbaseCommandModule {
public SystemType System = SisbaseInstance.Systems.Get<>();
}
Here's all dsp.interactivity functions. This issue was created to decide on what to port and what to discontinue support due to how different is the approach for both APIs are.
All functions will be posted as separate comments.
The format for the comments are:
<code block>
function_signature(params)
</code block>
---
Description : [Documentation from dsp if exists]
Status : [Accepted, Postponed (Added if requested in the future), Rejected, Ported]
Reason :
This if accepted would allow for the system, on the startup phase to run some modules asynchronously.
Proposed API :
public Task ExecuteAsync(DiscordClient client);
Current behaviour: The program will crash with an NRE when an invalid config file exists.
Ideal behaviour: The program will backup the existing malformed config file, print a warning, possibly give some information about why it is malformed, and then generate a new file with the default settings
Current setup is convoluted mainly because of the process of adding the d#+ nightly nuget source. Making an wiki entry with a complete tutorial on how to setup a sisbase bot from scratch would make that a trivially easy step-by-step process.
Also include troubleshooting for common issues related to that.
InteractionMessage:
implspec:
concept: interface delegation
class InteractionMessage "imsg" : delegate(DiscordMessage)
val Interaction owner
override DiscordMessage.Edit():
intr.Modify
override DiscordMessage.Delete():
intr.Remove
async waitDelete()
async waitEdit()
async waitReaction{Toggle|Add|Remove}(pred?)
event OnEdit
event OnDelete
event OnReaction{Toggle|Add|Remove}
class Interaction:
async InteractionMessage SendMessage()
async InteractionMessage GetUserResponse()
void Dispatch() {
foreach(message) if(message.wants(event)) message.Dispatch(event)
}
example usages:
intr.Origin.OnReactToggle += async (e) => ...
// instead of
intr.OnOriginReactToggle += ...
var imsg = await intr.SendMessageAsync();
imsg.AddReaction(":trash:");
imsg.OnReactionToggle += async (e) => {
if (e.Emoji != ":trash:") return;
ismg.Delete();
}
InteractionMessageAccessor:
implspec:
class InteractionMessageAccessor:
val Interaction owner
event On...
...
async Wait...
...
void Dispatch(EventArgs)
class ListInteractionAccessor : InteractionMessageAccessor:
mode = User | Bot | All
List<InteractionMessage> Get();
SingleAccessor First, Last
class SingleInteractionAccessor : InteractionMessageAccessor:
val ListAccessor parent
mode = First | Last
InteractionMessage Get();
class Interaction:
ListAccessor BotMessages
ListAccessor UserMessages
ListAccessor AllMessages
SingleAccessor Origin = UserMessages.First
SingleAccessor LatestMessage = AllMessages.Last
void Interaction.Dispatch {
...
foreach (accessor) if (accessor.wants(event)) accessor.Dispatch(event)
}
example usages:
intr.UserMessages.Last.OnReactionAdd += ...
// NOT the same as
var imsg = ... // get latest user message
imsg.OnReactionAdd += ...
depends on #41. fixing once that is merged
This should include a way to enable the D#+ internal logger, as well as an interface to any options for custom logging D#+ has.
No more totally ignored error messages!
feature:interactivity
.
system disable
commandsetmaster
command utilize RequireSystemAttribute
since mastersystem can be disabled.system list
commandIConfig
interface IConfig
interface newline
to EOL
for dsp logger compatibilityvoid
-> Task
on IApplyToClient
sensible indentation
.WhenCanceled
instead of while
on SisbaseBot
Aggregate
queries to string.Join
Use case : Lets suppose you made a Database
as an ISystem
and later use said database connection on a IClientSystem
On the case of said connection not being established the ClientSystem would return an error. Its possible for that to be implemented by the user but that could be added to the SMC codebase as a cleaner api, with the usage of a [Depends]
Attribute.
EmbedBase is the last bit of old unmodified code from the lolibase
era. I really didn't knew any better.
Currently there is no clean way to get an added system to the smc.
The adding on an .GetSystem<T>()
function would make it cleaner to get a specific system.
The current implementation of the api on stable
is outdated compared to release
.
sisbase/Utils/IClientSystem.cs
Line 14 in 12b3113
sisbase/Utils/IClientSystem.cs
Line 15 in 78c52eb
sisbase logging should have multiple logging levels, something similar to dsp.
that would allow for giving more information if said level is one. the current logging behaviour would be the default one.
Sisbase
-> MainConfig
SisbaseBot#StartAsync
-> SisbaseBot#Start
(although its async. revert?)
Sisbase._ctor
doesn't have a MainConfig
override exposed even if MainConfig._ctor
itself is exposed.
var config = new MainConfig();
var sisbase = new SisbaseBot( //CS1503
config
);
IClientSystem
API is outdated - #30 (Fixed)
sisbase/Utils/IClientSystem.cs
Line 14 in 12b3113
Permissions is an ambiguous reference between DSharpPlus.Permissions
and sisbase.Utils.Permissions
- #31
The current bot configuration is drenched in hardcoded values and little to nothing is exposed to the user.
Draft:
a function public Task<DiscordMessage> Interact(DiscordMessage)
, to be used like
var message = PrepareMessage();
var response = await Interact(message);
where response
is the next message sent in the context of message
(In the correct channel, and by the correct user).
For ease of use, also add overloads for any type that can be trivially converted into a DiscordMessage
, such as Interact(DiscordEmbed)
, Interact(string)
, and Interact(Attachment)
.
Implementation notes:
DSharpPlus.Interactivity provides several useful functions to get the next message, but all are at a lower level than the proposed Interact
Add extensions for getting the highest role with a given permission and allow predicates on GetHighestRole
-- Role GetHighestRole(this Member m);
++ Role GetHighestRole(this Member m, Func<Role,bool> pred);
++ Role GetHighestRole(this Member m) => m.GetHighestRole(_ => true);
++ Role GetHighestRoleWithPermission(this Member m , Perm p) => m.GetHighestRole(x => x.HasPermission(p));
Adds a Menu abstraction in order to add create menus with embeds.
Said api must provide support for a discordembed to be used as a display and buttons for the user interaction.
Buttons must be dynamically added and have a limit of 20 buttons (due to discord api limitations).
Proposed usage:
var testMenu = new Menu {
Embed = EmbedBase.OutputEmbed("Test"),
Buttons = new Dictionary<DiscordEmoji, Func<Task>> {
[emojiA] = emojiAClicked,
[emojiB] = emojiBClicked
},
Behaviour = ButtonBehaviour.Action
};
Proposed sisbase Implementation:
class MenuIconActions : IDisposable {
Dictionary<DiscordEmoji, Func<Task>> actions;
DiscordMessage menu;
DiscordClient client;
MenuActionIcons(DiscordClient c, DiscordMessage menumsg) {
menu = menumsg;
client = c;
client.ReactionAddedEvent += Dispatch;
}
async Task Dispatch(ReactionAddedEvent e) {
if(e.Message != menu) return;
var action = actions.TryGetValue(e.Emoji);
if (action = null) return;
await action();
}
void Register(DiscordEmoji emoji, Func<Task> action) => actions[emoji] = action;
void Dispose() {
client.ReactionAddedEvent -= Dispatch;
}
}
(see this comment on #31 for motivating discussion)
Utils/Unicode.cs contains a list of unicode code points and discord emoji names, and provides two dictionaries Emojis
and UnicodeEmojisByDiscordName
that contain the forward and reverse mappings.
Utils/Unicode.cs
to something more specific that indicates the relation to unicode emojis. (see issue #31)DiscordEmojiNameFromUnicodeChar
and UnicodeCharFromDiscordEmojiName
?Explicitly declare DSharpPlus.Permissions
Rename sisbase.Utils.Permissions
to avoid the conflict.
dsp-cnext has a exposed service provider that could be used to use systems inside commands, if that's deemed valid/necessary.
Usage after implemented would be like this
class command:cbm {
prop SystemType System {get;set;}
pat command(cc ctx){
//Use whatever is needed from System.
}
}
Currently on dsp, if a bot attempts to add a role which is higher on the higherarchy then itself an UnauthorizedException
will be thrown.
There exists an int | DiscordMember#Hierarchy
property which gives the position of the member on the role hierarchy, but thats hidden and its more common to see a try-catch
then that property being used.
The creation of an HierarchyUtils
that adds the following functions
DiscordRole GetHighestRole(this DiscordMember m);
bool IsAbove(this DiscordMember m, DiscordRole r);
bool IsAbove(this DiscordRole l, DiscordRole r);
with more being added in the future.
That would allow for the following code
try {
await member.GrantRoleAsync(role);
} catch (UnauthorizedException ex) {
//Send message
}
to be simplified to:
if(bot.IsAbove(role)){
await member.GrantRoleAsync(role);
} else {
//Send message
}
Use case/scenario :
The user already has a config
command/group, the build wouldn't be possible since there are a duplicate command.
With this behaviour implemented, that issue could be fixed since said user would be able to "rename" the sisbase's config
group to E.g. sconfig
, solving the conflict.
In particular, the areas where SisbaseBot.Instance
are currently used are the SMC (being the legacy code that it is), and to access Sisbase infrastructure from commands (which belong to D#+.CommandsNext, and currently have no way to access the bot).
Some embeds may need a newer design.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.