Added Command Resistration - Has bugs

This commit is contained in:
HarryET 2020-12-22 11:33:28 +00:00 committed by Szymon Uglis
parent 92d6f898ac
commit 1d6f937f96
No known key found for this signature in database
GPG key ID: 112376C5BEE91FE2
21 changed files with 1292 additions and 495 deletions

1
.gitignore vendored
View file

@ -30,5 +30,6 @@ pubspec.lock
/test/mirrors.dart
/private
private-*.dart
test-*.dart
[Rr]pc*
**/doc/api/**

View file

@ -1,9 +1,26 @@
library nyxx_interactions;
import 'dart:async';
import "package:logging/logging.dart";
import "package:nyxx/nyxx.dart";
// Root
part "src/Interactions.dart";
// Events
part "src/events/InteractionEvent.dart";
// Internal
part "src/internal/_EventController.dart";
// Models
part "src/models/CommandInteractionData.dart";
part "src/models/CommandInteractionOption.dart";
part "src/models/Interaction.dart";
part "src/models/InteractionResponse/IInteractionResponse.dart";
part "src/models/SlashArg.dart";
part "src/models/SlashCommand.dart";
part "src/models/SlashArgChoice.dart";
// Exceptions
part "src/models/exceptions/AlreadyResponded.dart";
part "src/models/exceptions/InteractionExpired.dart";
part "src/models/exceptions/SlashArgMisconfiguration.dart";
part "src/models/exceptions/ArgLength.dart";

View file

@ -2,8 +2,66 @@ part of nyxx_interactions;
/// Interaction extension for Nyxx. Allows use of: Slash Commands.
class Interactions {
late final Nyxx _client;
final Logger _logger = Logger("Interactions");
late final _EventController _events;
/// Emitted when a a slash command is sent.
late Stream<InteractionEvent> onSlashCommand;
///
Interactions(Nyxx client, [bool force = false]) {
client.shardManager.rawEvent.listen((event) {});
Interactions(Nyxx client) {
client.options.dispatchRawShardEvent = true;
this._client = client;
_events = _EventController(this);
client.onReady.listen((event) {
client.shardManager.rawEvent.listen((event) {
print(event);
if (event.rawData["op"] as int == 0) {
if (event.rawData["t"] as String == "INTERACTION_CREATE") {
_events.onSlashCommand.add(
InteractionEvent._new(
client, event.rawData["d"] as Map<String, dynamic>),
);
}
}
});
_logger.info("Interactions ready");
});
}
Future<SlashCommand> registerSlashGlobal(
String name, String description, List<SlashArg> args) async {
final command =
SlashCommand._new(this._client, name, args, description, null);
final response = await this._client.httpEndpoints.sendRawRequest(
"/applications/${this._client.app.id.toString()}/commands",
"POST",
body: command._build(),
);
if (response is HttpResponseError) {
return Future.error(response);
}
return Future.value(command);
}
Future<SlashCommand> registerSlashGuild(String name, String description,
Snowflake guildId, List<SlashArg> args) async {
final command =
SlashCommand._new(this._client, name, args, description, guildId);
command._build();
final response = await this._client.httpEndpoints.sendRawRequest(
"/applications/${this._client.app.id.toString()}/guilds/${guildId.toString()}/commands",
"POST",
body: command._build(),
);
if (response is HttpResponseError) {
return Future.error(response);
}
return Future.value(command);
}
}

View file

@ -1,3 +1,129 @@
part of nyxx_interactions;
class InteractionEvent {}
class InteractionEvent {
late final Nyxx _client;
late final Interaction interaction;
final DateTime recievedAt = DateTime.now();
bool hasResponded = false;
InteractionEvent._new(Nyxx client, Map<String, dynamic> rawJson) {
this._client = client;
interaction = Interaction._new(client, rawJson);
}
/// Should be sent when you receive a ping from interactions. Used to acknowledge a ping.
Future Pong() {
if (DateTime.now()
.isBefore(this.recievedAt.add(const Duration(minutes: 15)))) {
String url;
if (hasResponded) {
url =
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}";
} else {
url =
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback";
}
final response = this._client.httpEndpoints.sendRawRequest(
url,
"POST",
body: {
"type": 1,
"data": null,
},
);
if (response is HttpResponseError) {
return Future.error(response);
}
if (!hasResponded) {
hasResponded = true;
}
return Future.value(null);
} else {
return Future.error(InteractionExpired());
}
}
/// Used to acknowledge a Interaction but not send any response yet. Once this is sent you can then only send ChannelMessages with or without source.
Future Acknowledge({
bool showSource = false,
}) {
if (DateTime.now()
.isBefore(this.recievedAt.add(const Duration(minutes: 15)))) {
if (hasResponded) {
return Future.error(AlreadyResponded());
}
final url =
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback";
final response = this._client.httpEndpoints.sendRawRequest(
url,
"POST",
body: {
"type": showSource ? 5 : 2,
"data": null,
},
);
if (response is HttpResponseError) {
return Future.error(response);
}
if (!hasResponded) {
hasResponded = true;
}
return Future.value(null);
} else {
return Future.error(InteractionExpired());
}
}
Future Reply({
dynamic content,
EmbedBuilder? embed,
bool? tts,
AllowedMentions? allowedMentions,
bool showSource = false,
}) {
if (DateTime.now()
.isBefore(this.recievedAt.add(const Duration(minutes: 15)))) {
String url;
if (hasResponded) {
url =
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}";
} else {
url =
"/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback";
}
final response = this._client.httpEndpoints.sendRawRequest(
url,
"POST",
body: {
"type": showSource ? 4 : 3,
"data": {
"content": content,
"embeds":
embed != null ? BuilderUtility.buildRawEmbed(embed) : null,
"allowed_mentions": allowedMentions != null
? BuilderUtility.buildRawAllowedMentions(allowedMentions)
: null,
"tts": content != null && tts != null && tts
},
},
);
if (response is HttpResponseError) {
return Future.error(response);
}
if (!hasResponded) {
hasResponded = true;
}
return Future.value(null);
} else {
return Future.error(InteractionExpired());
}
}
}

View file

@ -0,0 +1,16 @@
part of nyxx_interactions;
class _EventController implements Disposable {
/// Emitted when a a slash command is sent.
late final StreamController<InteractionEvent> onSlashCommand;
_EventController(Interactions _client) {
this.onSlashCommand = StreamController.broadcast();
_client.onSlashCommand = this.onSlashCommand.stream;
}
@override
Future<void> dispose() async {
await this.onSlashCommand.close();
}
}

View file

@ -10,7 +10,7 @@ class Interaction extends SnowflakeEntity implements Disposable {
late final Cacheable<Snowflake, Guild> guild;
late final Cacheable<Snowflake, IChannel> channel;
late final Cacheable<Snowflake, TextChannel> channel;
late final Member author;
@ -45,7 +45,7 @@ class Interaction extends SnowflakeEntity implements Disposable {
),
);
this.channel = CacheUtility.createCacheableChannel(
this.channel = CacheUtility.createCacheableTextChannel(
client,
Snowflake(
raw["channel_id"],

View file

@ -0,0 +1,3 @@
part of nyxx_interactions;
abstract class IInteractionResponse implements Disposable {}

View file

@ -0,0 +1,99 @@
part of nyxx_interactions;
/// The type that a user should input for a [SlashArg]
enum SlashArgType {
SUB_COMMAND,
SUB_COMMAND_GROUP,
STRING,
INTEGER,
BOOLEAN,
USER,
CHANNEL,
ROLE,
}
/// An argument for a [SlashCommand].
class SlashArg {
/// The type of arg that will be later changed to an INT value, their values can be seen in the table below:
/// | Name | Value |
/// |-------------------|-------|
/// | SUB_COMMAND | 1 |
/// | SUB_COMMAND_GROUP | 2 |
/// | STRING | 3 |
/// | INTEGER | 4 |
/// | BOOLEAN | 5 |
/// | USER | 6 |
/// | CHANNEL | 7 |
/// | ROLE | 8 |
late final SlashArgType type;
/// The name of your argument / sub-group.
late final String name;
/// The description of your argument / sub-group.
late final String description;
/// If this should be the fist required option the user picks
late final bool defaultArg;
/// If this argument is required
late final bool required;
/// Choices for [SlashArgType.STRING] and [SlashArgType.INTEGER] types for the user to pick from
late final List<SlashArgChoice>? choices;
/// If the option is a subcommand or subcommand group type, this nested options will be the parameters
late final List<SlashArg>? options;
/// Used to create an argument for a [SlashCommand]. Thease are used in [Interactions.registerSlashGlobal] and [Interactions.registerSlashGuild]
SlashArg(this.type, this.name, this.description,
{this.defaultArg = false,
this.required = false,
this.choices,
this.options}) {
if (this.options != null &&
(this.type != SlashArgType.SUB_COMMAND ||
this.type != SlashArgType.SUB_COMMAND_GROUP)) {
throw SlashArgMisconfiguration._new("Options & Type");
}
if (this.choices != null &&
(this.type != SlashArgType.STRING ||
this.type != SlashArgType.INTEGER)) {
throw SlashArgMisconfiguration._new("Choices & Type");
}
if (!this.required && this.defaultArg) {
throw SlashArgMisconfiguration._new("Required & Default Arg");
}
if (this.name.length > 32) {
throw ArgLength._new("SlashArg.name", "1", "32");
}
if (this.description.length > 100) {
throw ArgLength._new("SlashArg.description", "1", "100");
}
}
Map<String, dynamic> _build() {
final subOptions = this.options != null
? List<Map<String, dynamic>>.generate(
this.options!.length, (i) => this.options![i]._build())
: null;
final rawChoices = this.choices != null
? List<Map<String, dynamic>>.generate(
this.choices!.length, (i) => this.choices![i]._build())
: null;
return {
"type": (this.type.index) + 1,
"name": this.name,
"description": this.description,
"default": this.defaultArg,
"required": this.required,
"choices": rawChoices,
"options": subOptions
};
}
}

View file

@ -0,0 +1,31 @@
part of nyxx_interactions;
class SlashArgChoice {
/// This options name.
late final String name;
/// This options int value. If there is an int value there can't be a [SlashArgChoice.stringValue]
late final int? intValue;
/// This options string value. If there is an string value there can't be a [SlashArgChoice.intValue]
late final String? stringValue;
/// A Choice for the user to input in int & string args. You can only have an int or string option.
SlashArgChoice(this.name, {this.intValue, this.stringValue}) {
if(this.intValue != null && this.stringValue != null) {
throw SlashArgMisconfiguration._new("stringValue & intValue");
}
if(this.intValue == null && this.stringValue == null) {
throw "MissingArgError: All SlashArgChoice need an int or string value";
}
if(this.name.length > 100) {
throw ArgLength._new("SlashArgChoice.name", "1", "100");
}
}
Map<String, dynamic> _build() => {
"name": this.name,
"value": this.stringValue ?? this.intValue
};
}

View file

@ -0,0 +1,38 @@
part of nyxx_interactions;
/// This class contains data about a slash command and is returned after registering one.
class SlashCommand {
/// The name of your command.
late final String name;
/// The description of your command.
late final String description;
/// The args registered for a command
late final List<SlashArg> args;
/// If you command is registered globally
late final bool isGlobal;
/// When you command is only for one guild the [SlashCommand.guild] will contain a [Cacheable] for
late final Cacheable<Snowflake, Guild>? guild;
SlashCommand._new(
Nyxx client, this.name, this.args, this.description, Snowflake? guildId) {
this.isGlobal = guildId == null;
this.guild = guildId != null
? CacheUtility.createCacheableGuild(client, Snowflake(guildId))
: null;
}
Map<String, dynamic> _build() {
final options = List<Map<String, dynamic>>.generate(
this.args.length, (i) => this.args[i]._build());
return {
"name": this.name,
"description": this.description,
"options": options.isNotEmpty ? options : null
};
}
}

View file

@ -0,0 +1,12 @@
part of nyxx_interactions;
/// Thrown when 15 minutes has passed since an interaction was called.
class AlreadyResponded implements Error {
/// Returns a string representation of this object.
@override
String toString() =>
"AlreadyRespondedError: Interaction has already been acknowledged, you can now only send channel messages (with/without source)";
@override
StackTrace? get stackTrace => StackTrace.empty;
}

View file

@ -0,0 +1,23 @@
part of nyxx_interactions;
/// Thrown when your slash are is configured in a way that is not possible
class ArgLength implements Error {
/// The max length for the incorrect length variable/param.
late final String maxLength;
/// The min length for the incorrect length variable/param.
late final String minLength;
/// The name of the incorrect length variable/param.
late final String name;
ArgLength._new(this.name, this.minLength, this.maxLength);
/// Returns a string representation of this object.
@override
String toString() =>
"ArgLengthError: $name isn't the correct length. It must be larger than $minLength and smaller than $maxLength ($minLength-$maxLength)";
@override
StackTrace? get stackTrace => StackTrace.empty;
}

View file

@ -0,0 +1,12 @@
part of nyxx_interactions;
/// Thrown when 15 minutes has passed since an interaction was called.
class InteractionExpired implements Error {
/// Returns a string representation of this object.
@override
String toString() =>
"InteractionExpiredError: Interaction tokens are only valid for 15mins. It has been over 15mins and the token is now invalid.";
@override
StackTrace? get stackTrace => StackTrace.empty;
}

View file

@ -0,0 +1,17 @@
part of nyxx_interactions;
/// Thrown when your slash are is configured in a way that is not possible
class SlashArgMisconfiguration implements Error {
/// The params that are incorrect.
late final String params;
SlashArgMisconfiguration._new(this.params);
/// Returns a string representation of this object.
@override
String toString() =>
"SlashArgMisconfigurationError: ${this.params} are mismatched. Please refer to the nyxx.interaction docs and the discord developer docs to make sure that all your slash args arguments are compatible together.";
@override
StackTrace? get stackTrace => StackTrace.empty;
}

View file

@ -11,7 +11,7 @@ environment:
dependencies:
nyxx: "^1.1.0-dev.1"
http: "^0.13.0-nullsafety-dev"
logging: "^1.0.0-nullsafety.0"
dependency_overrides:
http:
@ -21,4 +21,4 @@ dependency_overrides:
git:
url: git://github.com/dart-lang/http_parser.git
nyxx:
path: "../nyxx"
path: "../nyxx"

View file

@ -8,166 +8,137 @@ import "dart:convert";
import "dart:io";
import "dart:isolate"; // Used to discard errors on vm to continue working even if error occurred
import "package:logging/logging.dart";
import "package:http/http.dart" as http;
import "package:logging/logging.dart";
import "package:path/path.dart" as path_utils;
part "src/ClientOptions.dart";
// BASE
part "src/Nyxx.dart";
part "src/ClientOptions.dart";
// INTERNAL
part "src/internal/exceptions/MissingTokenError.dart";
part "src/internal/exceptions/EmbedBuilderArgumentException.dart";
part "src/internal/exceptions/InvalidShardException.dart";
part "src/internal/exceptions/InvalidSnowflakeException.dart";
part "src/internal/exceptions/HttpClientException.dart";
part "src/internal/shard/Shard.dart";
part "src/internal/shard/ShardManager.dart";
part "src/internal/shard/shardHandler.dart";
part "src/internal/_Constants.dart";
part "src/internal/_EventController.dart";
part "src/internal/_ConnectionManager.dart";
part "src/internal/_HttpEndpoints.dart";
part "src/internal/http/_HttpClient.dart";
part "src/internal/http/HttpBucket.dart";
part "src/internal/cache/CachePolicy.dart";
part "src/internal/cache/Cache.dart";
part "src/internal/cache/_SnowflakeCache.dart";
part "src/internal/cache/ChannelCache.dart";
part "src/internal/cache/MessageCache.dart";
part "src/internal/cache/Cacheable.dart";
part "src/internal/http/HttpHandler.dart";
part "src/internal/http/HttpRequest.dart";
part "src/internal/http/HttpResponse.dart";
part "src/internal/interfaces/Disposable.dart";
part "src/internal/interfaces/IMessageAuthor.dart";
part "src/internal/interfaces/Convertable.dart";
part "src/internal/interfaces/ISend.dart";
part "src/internal/interfaces/Mentionable.dart";
// EVENTS
part "src/events/RawEvent.dart";
part "src/events/MemberChunkEvent.dart";
part "src/events/DisconnectEvent.dart";
part "src/events/PresenceUpdateEvent.dart";
part "src/events/RatelimitEvent.dart";
part "src/events/ReadyEvent.dart";
part "src/events/TypingEvent.dart";
part "src/events/VoiceServerUpdateEvent.dart";
part "src/events/VoiceStateUpdateEvent.dart";
part "src/events/UserUpdateEvent.dart";
part "src/events/MessageEvents.dart";
part "src/events/HttpEvents.dart";
part "src/events/ChannelEvents.dart";
part "src/events/GuildEvents.dart";
part "src/events/InviteEvents.dart";
// BUILDERS
part "src/utils/builders/Builder.dart";
part "src/utils/builders/ReplyBuilder.dart";
part "src/utils/builders/PresenceBuilder.dart";
part "src/utils/builders/AttachmentBuilder.dart";
part "src/utils/builders/PermissionsBuilder.dart";
part "src/utils/builders/EmbedBuilder.dart";
part "src/utils/builders/EmbedAuthorBuilder.dart";
part "src/utils/builders/EmbedFieldBuilder.dart";
part "src/utils/builders/EmbedFooterBuilder.dart";
part "src/utils/builders/GuildBuilder.dart";
part "src/utils/builders/MessageBuilder.dart";
part "src/utils/extensions.dart";
part "src/utils/CacheUtility.dart";
part "src/utils/EntityUtility.dart";
// OBJECTS
part "src/core/AllowedMentions.dart";
part "src/core/DiscordColor.dart";
part "src/core/SnowflakeEntity.dart";
part "src/core/Snowflake.dart";
part "src/core/guild/Webhook.dart";
part "src/core/voice/VoiceState.dart";
part "src/core/voice/VoiceRegion.dart";
part "src/core/Invite.dart";
part "src/core/auditlogs/AuditLog.dart";
part "src/core/auditlogs/AuditLogEntry.dart";
part "src/core/auditlogs/AuditLogChange.dart";
part "src/core/channel/guild/CategoryGuildChannel.dart";
part "src/core/channel/guild/GuildChannel.dart";
part "src/core/channel/guild/TextGuildChannel.dart";
part "src/core/channel/guild/VoiceChannel.dart";
part "src/core/channel/Channel.dart";
part "src/core/channel/DMChannel.dart";
part "src/core/channel/TextChannel.dart";
part "src/core/embed/EmbedField.dart";
part "src/core/embed/EmbedAuthor.dart";
part "src/core/embed/EmbedFooter.dart";
part "src/core/embed/EmbedVideo.dart";
part "src/core/embed/Embed.dart";
part "src/core/embed/EmbedProvider.dart";
part "src/core/embed/EmbedThumbnail.dart";
part "src/core/guild/ClientUser.dart";
part "src/core/guild/Guild.dart";
part "src/core/guild/GuildFeature.dart";
part "src/core/user/Presence.dart";
part "src/core/user/Member.dart";
part "src/core/guild/Status.dart";
part "src/core/guild/Role.dart";
part "src/core/user/User.dart";
part "src/core/user/UserFlags.dart";
part "src/core/user/NitroType.dart";
part "src/core/guild/Ban.dart";
part "src/core/guild/PremiumTier.dart";
part "src/core/guild/GuildPreview.dart";
part "src/core/message/UnicodeEmoji.dart";
part "src/core/message/GuildEmoji.dart";
part "src/core/message/Emoji.dart";
part "src/core/message/Reaction.dart";
part "src/core/message/Message.dart";
part "src/core/message/Sticker.dart";
part "src/core/message/Attachment.dart";
part "src/core/message/MessageFlags.dart";
part "src/core/message/MessageReference.dart";
part "src/core/message/MessageType.dart";
part "src/core/message/ReferencedMessage.dart";
part "src/core/Snowflake.dart";
part "src/core/SnowflakeEntity.dart";
part "src/core/application/AppTeam.dart";
part "src/core/application/ClientOAuth2Application.dart";
part "src/core/application/OAuth2Application.dart";
part "src/core/application/OAuth2Guild.dart";
part "src/core/application/OAuth2Info.dart";
part "src/core/application/AppTeam.dart";
part "src/core/permissions/Permissions.dart";
part "src/core/auditlogs/AuditLog.dart";
part "src/core/auditlogs/AuditLogChange.dart";
part "src/core/auditlogs/AuditLogEntry.dart";
part "src/core/channel/Channel.dart";
part "src/core/channel/DMChannel.dart";
part "src/core/channel/TextChannel.dart";
part "src/core/channel/guild/CategoryGuildChannel.dart";
part "src/core/channel/guild/GuildChannel.dart";
part "src/core/channel/guild/TextGuildChannel.dart";
part "src/core/channel/guild/VoiceChannel.dart";
part "src/core/embed/Embed.dart";
part "src/core/embed/EmbedAuthor.dart";
part "src/core/embed/EmbedField.dart";
part "src/core/embed/EmbedFooter.dart";
part "src/core/embed/EmbedProvider.dart";
part "src/core/embed/EmbedThumbnail.dart";
part "src/core/embed/EmbedVideo.dart";
part "src/core/guild/Ban.dart";
part "src/core/guild/ClientUser.dart";
part "src/core/guild/Guild.dart";
part "src/core/guild/GuildFeature.dart";
part "src/core/guild/GuildPreview.dart";
part "src/core/guild/PremiumTier.dart";
part "src/core/guild/Role.dart";
part "src/core/guild/Status.dart";
part "src/core/guild/Webhook.dart";
part "src/core/message/Attachment.dart";
part "src/core/message/Emoji.dart";
part "src/core/message/GuildEmoji.dart";
part "src/core/message/Message.dart";
part "src/core/message/MessageFlags.dart";
part "src/core/message/MessageReference.dart";
part "src/core/message/MessageType.dart";
part "src/core/message/Reaction.dart";
part "src/core/message/ReferencedMessage.dart";
part "src/core/message/Sticker.dart";
part "src/core/message/UnicodeEmoji.dart";
part "src/core/permissions/PermissionOverrides.dart";
part "src/core/permissions/Permissions.dart";
part "src/core/permissions/PermissionsConstants.dart";
part "src/core/user/Member.dart";
part "src/core/user/NitroType.dart";
part "src/core/user/Presence.dart";
part "src/core/user/User.dart";
part "src/core/user/UserFlags.dart";
part "src/core/voice/VoiceRegion.dart";
part "src/core/voice/VoiceState.dart";
part "src/events/ChannelEvents.dart";
part "src/events/DisconnectEvent.dart";
part "src/events/GuildEvents.dart";
part "src/events/HttpEvents.dart";
part "src/events/InviteEvents.dart";
part "src/events/MemberChunkEvent.dart";
part "src/events/MessageEvents.dart";
part "src/events/PresenceUpdateEvent.dart";
part "src/events/RatelimitEvent.dart";
// EVENTS
part "src/events/RawEvent.dart";
part "src/events/ReadyEvent.dart";
part "src/events/TypingEvent.dart";
part "src/events/UserUpdateEvent.dart";
part "src/events/VoiceServerUpdateEvent.dart";
part "src/events/VoiceStateUpdateEvent.dart";
part "src/internal/_ConnectionManager.dart";
part "src/internal/_Constants.dart";
part "src/internal/_EventController.dart";
part "src/internal/_HttpEndpoints.dart";
part "src/internal/cache/Cache.dart";
part "src/internal/cache/CachePolicy.dart";
part "src/internal/cache/Cacheable.dart";
part "src/internal/cache/ChannelCache.dart";
part "src/internal/cache/MessageCache.dart";
part "src/internal/cache/_SnowflakeCache.dart";
part "src/internal/exceptions/EmbedBuilderArgumentException.dart";
part "src/internal/exceptions/HttpClientException.dart";
part "src/internal/exceptions/InvalidShardException.dart";
part "src/internal/exceptions/InvalidSnowflakeException.dart";
// INTERNAL
part "src/internal/exceptions/MissingTokenError.dart";
part "src/internal/http/HttpBucket.dart";
part "src/internal/http/HttpHandler.dart";
part "src/internal/http/HttpRequest.dart";
part "src/internal/http/HttpResponse.dart";
part "src/internal/http/_HttpClient.dart";
part "src/internal/interfaces/Convertable.dart";
part "src/internal/interfaces/Disposable.dart";
part "src/internal/interfaces/IMessageAuthor.dart";
part "src/internal/interfaces/ISend.dart";
part "src/internal/interfaces/Mentionable.dart";
part "src/internal/shard/Shard.dart";
part "src/internal/shard/ShardManager.dart";
part "src/internal/shard/shardHandler.dart";
part "src/utils/CacheUtility.dart";
part "src/utils/BuilderUtility.dart";
part "src/utils/EntityUtility.dart";
part "src/utils/IEnum.dart";
part "src/utils/builders/AttachmentBuilder.dart";
// BUILDERS
part "src/utils/builders/Builder.dart";
part "src/utils/builders/EmbedAuthorBuilder.dart";
part "src/utils/builders/EmbedBuilder.dart";
part "src/utils/builders/EmbedFieldBuilder.dart";
part "src/utils/builders/EmbedFooterBuilder.dart";
part "src/utils/builders/GuildBuilder.dart";
part "src/utils/builders/MessageBuilder.dart";
part "src/utils/builders/PermissionsBuilder.dart";
part "src/utils/builders/PresenceBuilder.dart";
part "src/utils/builders/ReplyBuilder.dart";
part "src/utils/extensions.dart";
part "src/utils/permissions.dart";
part "src/utils/utils.dart";
part "src/utils/IEnum.dart";

View file

@ -66,6 +66,8 @@ class ClientOptions {
/// Allows to enable receiving raw gateway event
bool dispatchRawShardEvent;
/// Makes a new `ClientOptions` object.
ClientOptions(
{this.allowedMentions,

View file

@ -183,17 +183,26 @@ class Nyxx implements Disposable {
/// Gets an bot invite link with zero permissions
String get inviteLink => app.getInviteUrl();
/// Can be used to edit options after client initialised. Used by Nyxx.interactions to enable raw events
ClientOptions get options => this._options;
/// Returns handler for all available REST API action.
IHttpEndpoints get httpEndpoints => this._httpEndpoints;
/// Creates and logs in a new client. If [ignoreExceptions] is true (by default is)
/// isolate will ignore all exceptions and continue to work.
Nyxx(this._token, this.intents, {ClientOptions? options, CacheOptions? cacheOptions, bool ignoreExceptions = true, bool useDefaultLogger = true, Level? defaultLoggerLogLevel}) {
if(useDefaultLogger) {
Nyxx(this._token, this.intents,
{ClientOptions? options,
CacheOptions? cacheOptions,
bool ignoreExceptions = true,
bool useDefaultLogger = true,
Level? defaultLoggerLogLevel}) {
if (useDefaultLogger) {
Logger.root.level = defaultLoggerLogLevel ?? Level.ALL;
Logger.root.onRecord.listen((LogRecord rec) {
print("[${rec.time}] [${rec.level.name}] [${rec.loggerName}] ${rec.message}");
print(
"[${rec.time}] [${rec.level.name}] [${rec.loggerName}] ${rec.message}");
});
}
@ -203,7 +212,7 @@ class Nyxx implements Disposable {
throw MissingTokenError();
}
if(!Platform.isWindows) {
if (!Platform.isWindows) {
ProcessSignal.sigterm.watch().forEach((event) async {
await this.dispose();
});
@ -234,9 +243,12 @@ class Nyxx implements Disposable {
this._httpEndpoints = _HttpEndpoints._new(this);
this._events = _EventController(this);
this.onSelfMention = this.onMessageReceived.where((event) => event.message.mentions.contains(this.self));
this.onDmReceived = this.onMessageReceived.where((event) => event.message is DMMessage);
this.onSelfMention = this
.onMessageReceived
.where((event) => event.message.mentions.contains(this.self));
this.onDmReceived =
this.onMessageReceived.where((event) => event.message is DMMessage);
this._ws = _ConnectionManager(this);
}
@ -249,7 +261,8 @@ class Nyxx implements Disposable {
/// Returns guild even if the user is not in the guild.
/// This endpoint is only for Public guilds.
Future<GuildPreview> getGuildPreview(Snowflake guildId) async {
final response = await _http._execute(BasicRequest._new("/guilds/$guildId/preview"));
final response =
await _http._execute(BasicRequest._new("/guilds/$guildId/preview"));
if (response is HttpResponseSuccess) {
return GuildPreview._new(this, response.jsonBody as Map<String, dynamic>);
@ -260,21 +273,21 @@ class Nyxx implements Disposable {
/// Returns guild with given [guildId]
Future<Guild> fetchGuild(Snowflake guildId) =>
this._httpEndpoints.fetchGuild(guildId);
this._httpEndpoints.fetchGuild(guildId);
/// Returns channel with specified id.
/// ```
/// var channel = await client.getChannel<TextChannel>(Snowflake("473853847115137024"));
/// ```
Future<T> fetchChannel<T extends IChannel>(Snowflake channelId) =>
this._httpEndpoints.fetchChannel(channelId);
this._httpEndpoints.fetchChannel(channelId);
/// Get user instance with specified id.
/// ```
/// var user = client.getUser(Snowflake("302359032612651009"));
/// ``
Future<User> fetchUser(Snowflake userId) =>
this._httpEndpoints.fetchUser(userId);
this._httpEndpoints.fetchUser(userId);
// /// Creates new guild with provided builder.
// /// Only for bots with less than 10 guilds otherwise it will return Future with error.
@ -311,7 +324,7 @@ class Nyxx implements Disposable {
/// var inv = client.getInvite("YMgffU8");
/// ```
Future<Invite> getInvite(String code) =>
this._httpEndpoints.fetchInvite(code);
this._httpEndpoints.fetchInvite(code);
/// Returns number of shards
int get shards => this.shardManager._shards.length;
@ -338,7 +351,7 @@ class Nyxx implements Disposable {
Future<void> dispose() async {
this._logger.info("Disposing and closing bot...");
if(this._options.shutdownHook != null) {
if (this._options.shutdownHook != null) {
await this._options.shutdownHook!(this);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
part of nyxx;
class BuilderUtility {
static Map<String, dynamic> buildRawEmbed(EmbedBuilder embed) =>
embed._build();
static Map<String, dynamic> buildRawAllowedMentions(
AllowedMentions mentions) =>
mentions._build();
}

View file

@ -43,7 +43,7 @@ class CacheUtility {
Nyxx client, Snowflake id, Cacheable<Snowflake, Guild> guild) =>
_RoleCacheable(client, id, guild);
/// Retrieves a cached Role.
/// Retrieves a cached IChannel. Can be cast.
/// ```dart
/// void main() {
/// var bot = Nyxx("TOKEN");
@ -54,6 +54,39 @@ class CacheUtility {
Nyxx client, Snowflake id) =>
_ChannelCacheable(client, id);
/// Retrieves a cached TextChannel.
/// ```dart
/// void main() {
/// var bot = Nyxx("TOKEN");
/// Cacheable<Snowflake, TextChannel> cachedChannel = CacheUtility.createCacheableTextChannel(bot, Snowflake(''));
/// }
/// ```
static Cacheable<Snowflake, TextChannel> createCacheableTextChannel(
Nyxx client, Snowflake id) =>
_ChannelCacheable(client, id);
/// Retrieves a cached VoiceChannel.
/// ```dart
/// void main() {
/// var bot = Nyxx("TOKEN");
/// Cacheable<Snowflake, VoiceGuildChannel> cachedChannel = CacheUtility.createCacheableVoiceChannel(bot, Snowflake(''));
/// }
/// ```
static Cacheable<Snowflake, VoiceGuildChannel> createCacheableVoiceChannel(
Nyxx client, Snowflake id) =>
_ChannelCacheable(client, id);
/// Retrieves a cached DMChannel.
/// ```dart
/// void main() {
/// var bot = Nyxx("TOKEN");
/// Cacheable<Snowflake, DMChannel> cachedChannel = CacheUtility.createCacheableDMChannel(bot, Snowflake(''));
/// }
/// ```
static Cacheable<Snowflake, DMChannel> createCacheableDMChannel(
Nyxx client, Snowflake id) =>
_ChannelCacheable(client, id);
/// Retrieves a cached Guild Member.
/// ```dart
/// void main() {
@ -66,7 +99,7 @@ class CacheUtility {
Nyxx client, Snowflake id, Cacheable<Snowflake, Guild> guild) =>
_MemberCacheable(client, id, guild);
/// Retrieves a cached Guild Member.
/// Retrieves a cached Guild Message.
/// ```dart
/// void main() {
/// var bot = Nyxx("TOKEN");