Discord API Data Structures Part 1 #12
17 changed files with 1744 additions and 25 deletions
47
Jenkinsfile
vendored
Normal file
47
Jenkinsfile
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
pipeline {
|
||||
agent {
|
||||
label 'linux'
|
||||
}
|
||||
options {
|
||||
buildDiscarder(
|
||||
logRotator(
|
||||
numToKeepStr: '5'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
stages {
|
||||
|
||||
stage('Build') {
|
||||
steps {
|
||||
script {
|
||||
// Use bash as the shell for these commands
|
||||
sh '''
|
||||
#!/bin/bash
|
||||
unset WORKSPACE
|
||||
unset WORKSPACE_TMP
|
||||
rm -rf doc
|
||||
dart pub get
|
||||
dart doc
|
||||
tar -cvf docs.tgz doc/api/*
|
||||
rm -rf ServerCode
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Deploy') {
|
||||
steps {
|
||||
sh 'flutter pub publish -f --skip-validation'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
post {
|
||||
always {
|
||||
archiveArtifacts artifacts: "*.tgz", fingerprint: true
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
81
lib/discord/networking/application.dart
Normal file
81
lib/discord/networking/application.dart
Normal file
|
@ -0,0 +1,81 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:libac_dart/discord/structures/application.dart';
|
||||
|
||||
import 'endpoints.dart';
|
||||
|
||||
class ApplicationPacket {
|
||||
/// This will request the current application instance.
|
||||
static Future<Application> getCurrentApplication() async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.get(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Applications}${DiscordEndpoints.ME}");
|
||||
String jsonReply = reply.data as String;
|
||||
|
||||
return Application.fromJson(jsonReply);
|
||||
}
|
||||
|
||||
/// This will update the current application instance.
|
||||
static Future<Application> updateApplication(EditApplication app) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.patch(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Applications}${DiscordEndpoints.ME}",
|
||||
data: app.encode());
|
||||
|
||||
String jsonReply = reply.data as String;
|
||||
return Application.fromJson(jsonReply);
|
||||
}
|
||||
}
|
||||
|
||||
class EditApplication {
|
||||
String? customInstallUrl;
|
||||
String? description;
|
||||
String? roleConnectionsVerifyUrl;
|
||||
OAuth2InstallParams? installParams;
|
||||
List<ApplicationIntegrationType>? integrationTypesConfig;
|
||||
int? flags;
|
||||
String? icon;
|
||||
String? coverImage;
|
||||
String? interactionEndpointURL;
|
||||
List<String>? tags;
|
||||
|
||||
EditApplication(
|
||||
{this.customInstallUrl,
|
||||
this.description,
|
||||
this.roleConnectionsVerifyUrl,
|
||||
this.installParams,
|
||||
this.integrationTypesConfig,
|
||||
this.flags,
|
||||
this.icon,
|
||||
this.coverImage,
|
||||
this.interactionEndpointURL,
|
||||
this.tags});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
List<Map<String, dynamic>> AIT = [];
|
||||
if (integrationTypesConfig != null) {
|
||||
for (var entry in integrationTypesConfig!) {
|
||||
AIT.add(entry.toJson());
|
||||
}
|
||||
}
|
||||
return {
|
||||
if (customInstallUrl != null) "custom_install_url": customInstallUrl,
|
||||
if (description != null) "description": description,
|
||||
if (roleConnectionsVerifyUrl != null)
|
||||
"role_connections_verification_url": roleConnectionsVerifyUrl,
|
||||
if (installParams != null) "install_params": installParams!.toJson(),
|
||||
if (integrationTypesConfig != null) "integration_types_config": AIT,
|
||||
if (flags != null) "flags": flags,
|
||||
if (icon != null) "icon": icon,
|
||||
if (coverImage != null) "cover_image": coverImage,
|
||||
if (interactionEndpointURL != null)
|
||||
"interaction_endpoint_url": interactionEndpointURL,
|
||||
if (tags != null) "tags": tags
|
||||
};
|
||||
}
|
||||
}
|
23
lib/discord/networking/endpoints.dart
Normal file
23
lib/discord/networking/endpoints.dart
Normal file
|
@ -0,0 +1,23 @@
|
|||
import 'package:dio/dio.dart';
|
||||
|
||||
/// Contains currently supported endpoints and URLs.
|
||||
class DiscordEndpoints {
|
||||
/// Currently this is set to 10
|
||||
static const APIVersion = 10;
|
||||
|
||||
/// This is the current base URL of all discord API calls per reference.
|
||||
static const BaseURL = "https://discord.com/api/v${APIVersion}";
|
||||
static const ME = "/@me";
|
||||
static const Applications = "/applications";
|
||||
static const Users = "/users";
|
||||
static const Stickers = "/stickers";
|
||||
static const StickerPacks = "/sticker-packs";
|
||||
static const Guilds = "/guilds";
|
||||
}
|
||||
|
||||
class DiscordSessionSettings {
|
||||
static String BOT_TOKEN = "";
|
||||
|
||||
static BaseOptions get getOptions => BaseOptions(
|
||||
headers: {"Authorization": "Bot ${DiscordSessionSettings.BOT_TOKEN}"});
|
||||
}
|
0
lib/discord/networking/guild.dart
Normal file
0
lib/discord/networking/guild.dart
Normal file
96
lib/discord/networking/sticker.dart
Normal file
96
lib/discord/networking/sticker.dart
Normal file
|
@ -0,0 +1,96 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:libac_dart/discord/networking/endpoints.dart';
|
||||
import 'package:libac_dart/structs/Snowflake.dart';
|
||||
|
||||
import '../structures/sticker.dart';
|
||||
|
||||
class StickerPackets {
|
||||
static Future<Sticker> getSticker(Snowflake id) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.get(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Stickers}/${id.toString()}");
|
||||
|
||||
return Sticker.fromJson(reply.data);
|
||||
}
|
||||
|
||||
static Future<List<StickerPack>> getStickerPacks() async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio
|
||||
.get("${DiscordEndpoints.BaseURL}${DiscordEndpoints.StickerPacks}");
|
||||
|
||||
List<StickerPack> stickerPacks = [];
|
||||
var js = json.decode(reply.data);
|
||||
var jsStickerPacks = js['sticker_packs'];
|
||||
|
||||
for (var entry in jsStickerPacks) {
|
||||
stickerPacks.add(StickerPack.decode(entry));
|
||||
}
|
||||
|
||||
return stickerPacks;
|
||||
}
|
||||
|
||||
static Future<List<Sticker>> getGuildStickers(Snowflake guildId) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.get(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Guilds}${guildId.toString()}${DiscordEndpoints.Stickers}");
|
||||
|
||||
List<Sticker> stickers = [];
|
||||
for (var entry in json.decode(reply.data)) {
|
||||
stickers.add(Sticker.decode(entry));
|
||||
}
|
||||
|
||||
return stickers;
|
||||
}
|
||||
|
||||
static Future<Sticker> getGuildSticker(
|
||||
Snowflake guildId, Snowflake id) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.get(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Guilds}${guildId.toString()}${DiscordEndpoints.Stickers}/${id.toString()}");
|
||||
|
||||
return Sticker.fromJson(reply.data);
|
||||
}
|
||||
|
||||
static Future<Sticker> createGuildSticker(Snowflake guildId, String name,
|
||||
String description, String tags, Uint8List fileContents) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var fd = FormData.fromMap({
|
||||
"name": name,
|
||||
"description": description,
|
||||
"tags": tags,
|
||||
"file": MultipartFile.fromBytes(fileContents)
|
||||
});
|
||||
|
||||
var reply = await dio.post(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Guilds}/${guildId.toString()}${DiscordEndpoints.Stickers}",
|
||||
options: Options(contentType: "multipart/form-data"),
|
||||
data: fd);
|
||||
return Sticker.fromJson(reply.data);
|
||||
}
|
||||
|
||||
static Future<Sticker> updateGuildSticker(Snowflake guildId,
|
||||
Snowflake stickerId, String name, String description, String tags) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.patch(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Guilds}/${guildId.toString()}${DiscordEndpoints.Stickers}/${stickerId.toString()}",
|
||||
data: json
|
||||
.encode({"name": name, "description": description, "tags": tags}));
|
||||
|
||||
return Sticker.fromJson(reply.data);
|
||||
}
|
||||
|
||||
static Future<bool> deleteGuildSticker(
|
||||
Snowflake guildId, Snowflake stickerId) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.delete(
|
||||
"${DiscordEndpoints.BaseURL}/${guildId.toString()}${DiscordEndpoints.Stickers}/${stickerId.toString()}");
|
||||
|
||||
if (reply.statusCode == 204) {
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
}
|
60
lib/discord/networking/user.dart
Normal file
60
lib/discord/networking/user.dart
Normal file
|
@ -0,0 +1,60 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:libac_dart/discord/networking/endpoints.dart';
|
||||
|
||||
import '../structures/user.dart';
|
||||
|
||||
class UserPackets {
|
||||
/// Requests the current user from Discord's servers
|
||||
static Future<User> getCurrentUser() async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.get(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Users}${DiscordEndpoints.ME}");
|
||||
|
||||
return User.fromJson(reply.data as String);
|
||||
}
|
||||
|
||||
/// Requests the user from Discord's servers
|
||||
///
|
||||
/// [id] is expected to be a valid Discord User ID
|
||||
static Future<User> getUser(int id) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio
|
||||
.get("${DiscordEndpoints.BaseURL}${DiscordEndpoints.Users}/${id}");
|
||||
|
||||
return User.fromJson(reply.data as String);
|
||||
}
|
||||
|
||||
/// Updates any values that were set in the packet, and returns the updated user
|
||||
///
|
||||
/// Fires a User Update gateway event
|
||||
static Future<User> updateCurrentUser(ModifyCurrentUserPacket mcup) async {
|
||||
Dio dio = Dio(DiscordSessionSettings.getOptions);
|
||||
var reply = await dio.patch(
|
||||
"${DiscordEndpoints.BaseURL}${DiscordEndpoints.Users}${DiscordEndpoints.ME}",
|
||||
data: mcup.encode());
|
||||
|
||||
return User.fromJson(reply.data as String);
|
||||
}
|
||||
}
|
||||
|
||||
class ModifyCurrentUserPacket {
|
||||
String? username;
|
||||
String? avatar;
|
||||
String? banner;
|
||||
|
||||
ModifyCurrentUserPacket({this.username, this.avatar, this.banner});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
if (username != null) "username": username,
|
||||
if (avatar != null) "avatar": avatar,
|
||||
if (banner != null) "banner": banner,
|
||||
};
|
||||
}
|
||||
}
|
158
lib/discord/structures/application.dart
Normal file
158
lib/discord/structures/application.dart
Normal file
|
@ -0,0 +1,158 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:libac_dart/discord/structures/user.dart';
|
||||
import 'package:libac_dart/structs/Snowflake.dart';
|
||||
import 'package:libac_dart/utils/DictTools.dart';
|
||||
|
||||
class Application {
|
||||
bool botPublic;
|
||||
bool botRequiresCodeGrant;
|
||||
String? coverImage;
|
||||
String description;
|
||||
Snowflake? guildId;
|
||||
String? icon;
|
||||
Snowflake id;
|
||||
Map<String, ApplicationIntegrationType>? integrationConfig;
|
||||
String name;
|
||||
User? owner;
|
||||
Snowflake? primarySkuId;
|
||||
String? slug;
|
||||
String summary;
|
||||
|
||||
Application(
|
||||
{required this.botPublic,
|
||||
required this.botRequiresCodeGrant,
|
||||
this.coverImage,
|
||||
required this.description,
|
||||
this.guildId,
|
||||
required this.id,
|
||||
this.integrationConfig,
|
||||
required this.name,
|
||||
this.icon,
|
||||
this.owner,
|
||||
this.primarySkuId,
|
||||
this.slug,
|
||||
required this.summary});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
Map<String, dynamic> itc = {};
|
||||
|
||||
if (integrationConfig != null) {
|
||||
for (MapEntry<String, ApplicationIntegrationType> entry
|
||||
in integrationConfig!.entries) {
|
||||
itc[entry.key] = entry.value.toJson();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"bot_public": botPublic,
|
||||
"bot_require_code_grant": botRequiresCodeGrant,
|
||||
if (coverImage != null) "cover_image": coverImage,
|
||||
"description": description,
|
||||
if (guildId != null) "guild_id": guildId.toString(),
|
||||
"icon": icon,
|
||||
"id": id.toString(),
|
||||
if (integrationConfig != null) "integration_types_config": itc,
|
||||
"name": name,
|
||||
if (owner != null) "owner": owner!.toJson(),
|
||||
if (primarySkuId != null) "primary_sku_id": primarySkuId.toString(),
|
||||
if (slug != null) "slug": slug,
|
||||
"summary": summary,
|
||||
};
|
||||
}
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
factory Application.fromJson(String js) {
|
||||
return Application.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory Application.decode(Map<String, dynamic> js) {
|
||||
Map<String, ApplicationIntegrationType>? itc = null;
|
||||
if (js.containsKey("integration_types_config")) {
|
||||
itc = {};
|
||||
var itc_js = js["integration_types_config"] as Map<String, dynamic>;
|
||||
for (MapEntry<String, dynamic> jsx in itc_js.entries) {
|
||||
itc[jsx.key] = ApplicationIntegrationType.decode(
|
||||
jsx.value as Map<String, dynamic>);
|
||||
}
|
||||
}
|
||||
|
||||
return Application(
|
||||
botPublic: js['bot_public'] as bool,
|
||||
botRequiresCodeGrant: js['bot_require_code_grant'] as bool,
|
||||
coverImage: setor(js, 'cover_image', null),
|
||||
description: js['description'] as String,
|
||||
guildId: js.containsKey("guild_id")
|
||||
? Snowflake.parse(js['guild_id'] as String, Snowflake.DiscordEpoch)
|
||||
: null,
|
||||
id: Snowflake.parse(js['id'] as String, Snowflake.DiscordEpoch),
|
||||
integrationConfig: itc,
|
||||
name: js['name'] as String,
|
||||
owner: User.decode(js['owner']),
|
||||
icon: js['icon'],
|
||||
primarySkuId: js.containsKey("primary_sku_id")
|
||||
? Snowflake.parse(
|
||||
js['primary_sku_id'] as String, Snowflake.DiscordEpoch)
|
||||
: null,
|
||||
slug: setor(js, "slug", null),
|
||||
summary: js['summary']);
|
||||
}
|
||||
}
|
||||
|
||||
class OAuth2InstallParams {
|
||||
List<String> scopes;
|
||||
String permissions;
|
||||
|
||||
OAuth2InstallParams({required this.scopes, required this.permissions});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {"scopes": scopes, "permissions": permissions};
|
||||
}
|
||||
|
||||
factory OAuth2InstallParams.fromJson(String js) {
|
||||
return OAuth2InstallParams.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory OAuth2InstallParams.decode(Map<String, dynamic> js) {
|
||||
return OAuth2InstallParams(
|
||||
scopes: js['scopes'] as List<String>,
|
||||
permissions: js['permissions'] as String);
|
||||
}
|
||||
}
|
||||
|
||||
class ApplicationIntegrationType {
|
||||
OAuth2InstallParams? installParams;
|
||||
|
||||
ApplicationIntegrationType({this.installParams});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {"oauth2_install_params": installParams};
|
||||
}
|
||||
|
||||
factory ApplicationIntegrationType.fromJson(String js) {
|
||||
Map<String, dynamic> jd = json.decode(js);
|
||||
return ApplicationIntegrationType.decode(jd);
|
||||
}
|
||||
|
||||
factory ApplicationIntegrationType.decode(Map<String, dynamic> js) {
|
||||
ApplicationIntegrationType ait = ApplicationIntegrationType();
|
||||
if (js["oauth2_install_params"] == null) {
|
||||
ait = ApplicationIntegrationType(
|
||||
installParams:
|
||||
OAuth2InstallParams.decode(js['oauth2_install_params']));
|
||||
}
|
||||
|
||||
return ait;
|
||||
}
|
||||
}
|
705
lib/discord/structures/guild.dart
Normal file
705
lib/discord/structures/guild.dart
Normal file
|
@ -0,0 +1,705 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:libac_dart/discord/structures/sticker.dart';
|
||||
import 'package:libac_dart/discord/structures/user.dart';
|
||||
import 'package:libac_dart/structs/Bitmasks.dart';
|
||||
import 'package:libac_dart/structs/Snowflake.dart';
|
||||
import 'package:libac_dart/utils/DictTools.dart';
|
||||
|
||||
class Guild {
|
||||
Snowflake id;
|
||||
String name;
|
||||
String? icon;
|
||||
String? icon_hash;
|
||||
String? splash;
|
||||
String? discoverySplash;
|
||||
bool? owner;
|
||||
Snowflake owner_id;
|
||||
BitMask? permissions;
|
||||
String? region;
|
||||
Snowflake? afk_channel_id;
|
||||
int afkTimeout;
|
||||
bool? widgetEnabled;
|
||||
Snowflake? widgetChannelID;
|
||||
int verificationLevel;
|
||||
int defaultMessageNotify;
|
||||
int explicitContentFilter;
|
||||
List<Role> roles;
|
||||
List<Emoji> emojis;
|
||||
List<GuildFeatures> features;
|
||||
int mfaLevel;
|
||||
Snowflake? applicationId;
|
||||
Snowflake? systemChannelId;
|
||||
int systemChannelFlags;
|
||||
Snowflake? rulesChannelId;
|
||||
int? maxPresences;
|
||||
int? maxMembers;
|
||||
String? vanityUrlCode;
|
||||
String? description;
|
||||
String? banner;
|
||||
int premiumTier;
|
||||
int? premiumSubscriptionCount;
|
||||
String preferredLocale;
|
||||
Snowflake? publicUpdateChannelId;
|
||||
int? maxVideoChannelUsers;
|
||||
int? maxStageVideoChannelUsers;
|
||||
int? approximateMemberCount;
|
||||
int? approximatePresenceCount;
|
||||
WelcomeScreen? welcomeScreen;
|
||||
int nsfwLevel;
|
||||
List<Sticker>? stickers;
|
||||
bool premiumProgressBarEnabled;
|
||||
Snowflake? safetyAlertsChannelId;
|
||||
|
||||
Guild(
|
||||
{required this.id,
|
||||
required this.name,
|
||||
required this.icon,
|
||||
this.icon_hash,
|
||||
required this.splash,
|
||||
required this.discoverySplash,
|
||||
this.owner,
|
||||
required this.owner_id,
|
||||
this.permissions,
|
||||
this.region,
|
||||
required this.afk_channel_id,
|
||||
required this.afkTimeout,
|
||||
this.widgetEnabled,
|
||||
this.widgetChannelID,
|
||||
required this.verificationLevel,
|
||||
required this.defaultMessageNotify,
|
||||
required this.explicitContentFilter,
|
||||
required this.roles,
|
||||
required this.emojis,
|
||||
required this.features,
|
||||
required this.mfaLevel,
|
||||
required this.applicationId,
|
||||
required this.systemChannelId,
|
||||
required this.systemChannelFlags,
|
||||
required this.rulesChannelId,
|
||||
this.maxPresences,
|
||||
this.maxMembers,
|
||||
required this.vanityUrlCode,
|
||||
required this.description,
|
||||
required this.banner,
|
||||
required this.premiumTier,
|
||||
this.premiumSubscriptionCount,
|
||||
required this.preferredLocale,
|
||||
required this.publicUpdateChannelId,
|
||||
this.maxVideoChannelUsers,
|
||||
this.maxStageVideoChannelUsers,
|
||||
this.approximateMemberCount,
|
||||
this.approximatePresenceCount,
|
||||
this.welcomeScreen,
|
||||
required this.nsfwLevel,
|
||||
this.stickers,
|
||||
required this.premiumProgressBarEnabled,
|
||||
required this.safetyAlertsChannelId});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
List<Map<String, dynamic>> rolesJs = [];
|
||||
for (Role role in roles) {
|
||||
rolesJs.add(role.toJson());
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> emojiJs = [];
|
||||
for (Emoji emoji in emojis) {
|
||||
emojiJs.add(emoji.toJson());
|
||||
}
|
||||
|
||||
List<String> featureJs = [];
|
||||
for (GuildFeatures feature in features) {
|
||||
featureJs.add(feature.name);
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>>? stickersJs = null;
|
||||
if (stickers != null) {
|
||||
stickersJs = [];
|
||||
|
||||
for (Sticker sticker in stickers!) {
|
||||
stickersJs.add(sticker.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"id": id.toString(),
|
||||
"name": name,
|
||||
"icon": icon ?? null,
|
||||
if (icon_hash != null) "icon_hash": icon_hash,
|
||||
"splash": splash ?? null,
|
||||
"discovery_splash": discoverySplash ?? null,
|
||||
if (owner != null) "owner": owner,
|
||||
"owner_id": owner_id.toString(),
|
||||
if (permissions != null) "permissions": permissions.toString(),
|
||||
if (region != null) "region": region,
|
||||
"afk_channel_id": afk_channel_id ?? null,
|
||||
if (widgetEnabled != null) "widget_enabled": widgetEnabled,
|
||||
if (widgetChannelID != null) "widget_channel_id": widgetChannelID,
|
||||
"verification_level": verificationLevel,
|
||||
"default_message_notifications": defaultMessageNotify,
|
||||
"explicit_content_filter": explicitContentFilter,
|
||||
"roles": rolesJs,
|
||||
"emojis": emojiJs,
|
||||
"features": featureJs,
|
||||
"mfa_level": mfaLevel,
|
||||
"application_id": applicationId == null ? null : applicationId.toString(),
|
||||
"system_channel_id":
|
||||
systemChannelId == null ? null : systemChannelId.toString(),
|
||||
"system_channel_flags": systemChannelFlags,
|
||||
"rules_channel_id":
|
||||
rulesChannelId != null ? rulesChannelId.toString() : null,
|
||||
if (maxPresences != null) "max_presences": maxPresences,
|
||||
if (maxMembers != null) "max_members": maxMembers,
|
||||
"vanity_url_code": vanityUrlCode,
|
||||
"description": description,
|
||||
"banner": banner,
|
||||
"premium_tier": premiumTier,
|
||||
if (premiumSubscriptionCount != null)
|
||||
"premium_subscription_count": premiumSubscriptionCount,
|
||||
"preferred_locale": preferredLocale,
|
||||
"public_updates_channel_id": publicUpdateChannelId == null
|
||||
? null
|
||||
: publicUpdateChannelId.toString(),
|
||||
if (maxVideoChannelUsers != null)
|
||||
"max_video_channel_users": maxVideoChannelUsers,
|
||||
if (maxStageVideoChannelUsers != null)
|
||||
"max_stage_video_channel_users": maxStageVideoChannelUsers,
|
||||
if (approximateMemberCount != null)
|
||||
"approximate_member_count": approximateMemberCount,
|
||||
if (approximatePresenceCount != null)
|
||||
"approximate_presence_count": approximatePresenceCount,
|
||||
if (welcomeScreen != null) "welcome_screen": welcomeScreen!.toJson(),
|
||||
"nsfw_level": nsfwLevel,
|
||||
if (stickers != null) "stickers": stickersJs,
|
||||
"premium_progress_bar_enabled": premiumProgressBarEnabled,
|
||||
"safety_alerts_channel_id": safetyAlertsChannelId == null
|
||||
? null
|
||||
: safetyAlertsChannelId.toString()
|
||||
};
|
||||
}
|
||||
|
||||
factory Guild.fromJson(String js) {
|
||||
return Guild.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory Guild.decode(Map<String, dynamic> js) {
|
||||
List<Role> JsRoles = [];
|
||||
List<Map<String, dynamic>> rolesJs =
|
||||
js['roles'] as List<Map<String, dynamic>>;
|
||||
for (var entry in rolesJs) {
|
||||
JsRoles.add(Role.decode(entry));
|
||||
}
|
||||
|
||||
List<Emoji> JsEmoji = [];
|
||||
for (var entry in js['emojis'] as List<Map<String, dynamic>>) {
|
||||
JsEmoji.add(Emoji.decode(entry));
|
||||
}
|
||||
|
||||
List<GuildFeatures> JsFeatures = [];
|
||||
for (var entry in js['features'] as List<String>) {
|
||||
GuildFeatures? gf = GuildFeatures.byName(entry);
|
||||
if (gf != null) JsFeatures.add(gf);
|
||||
}
|
||||
|
||||
List<Sticker>? JsSStickers = null;
|
||||
if (js.containsKey("stickers")) {
|
||||
JsSStickers = [];
|
||||
for (var entry in js['stickers'] as List<Map<String, dynamic>>) {
|
||||
JsSStickers.add(Sticker.decode(entry));
|
||||
}
|
||||
}
|
||||
|
||||
return Guild(
|
||||
id: Snowflake.parse(js['id'], Snowflake.DiscordEpoch),
|
||||
name: js['name'],
|
||||
icon: js['icon'],
|
||||
icon_hash: setor(js, "icon_hash", null),
|
||||
splash: js['splash'],
|
||||
discoverySplash: js['discovery_splash'],
|
||||
permissions: js.containsKey("permissions")
|
||||
? BitMask.of(int.parse(js['permissions']))
|
||||
: null,
|
||||
owner_id: Snowflake.parse(js['owner_id'], Snowflake.DiscordEpoch),
|
||||
afk_channel_id: js['afk_channel_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(js['afk_channel_id'], Snowflake.DiscordEpoch),
|
||||
afkTimeout: int.parse(js['afk_timeout']),
|
||||
widgetEnabled: js['widget_enabled'] == null
|
||||
? null
|
||||
: bool.parse(js['widget_enabled']),
|
||||
verificationLevel: int.parse(js['verification_level']),
|
||||
defaultMessageNotify: int.parse(js['default_message_notifications']),
|
||||
explicitContentFilter: int.parse(js['explicit_content_filter']),
|
||||
roles: JsRoles,
|
||||
emojis: JsEmoji,
|
||||
features: JsFeatures,
|
||||
mfaLevel: int.parse(js['mfa_level']),
|
||||
applicationId: js['application_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(js['application_id'], Snowflake.DiscordEpoch),
|
||||
systemChannelId: js['system_channel_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(js['system_channel_id'], Snowflake.DiscordEpoch),
|
||||
systemChannelFlags: int.parse(js['system_channel_flags']),
|
||||
rulesChannelId: js['rules_channel_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(js['rules_channel_id'], Snowflake.DiscordEpoch),
|
||||
maxPresences: js.containsKey("max_presences")
|
||||
? int.parse(js['max_presences'])
|
||||
: null,
|
||||
maxMembers:
|
||||
js.containsKey("max_members") ? int.parse(js['max_members']) : null,
|
||||
vanityUrlCode: setor(js, "vanity_url_code", null),
|
||||
description: setor(js, "description", null),
|
||||
banner: setor(js, "banner", null),
|
||||
premiumTier: int.parse(js['premium_tier']),
|
||||
premiumSubscriptionCount: js.containsKey("premium_subscription_count")
|
||||
? int.parse(js['premium_subscription_count'])
|
||||
: null,
|
||||
preferredLocale: js['preferred_locale'],
|
||||
publicUpdateChannelId: js['public_updates_channel_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(
|
||||
js['public_updates_channel_id'], Snowflake.DiscordEpoch),
|
||||
maxVideoChannelUsers: js.containsKey("max_video_channel_users")
|
||||
? int.parse(js['max_video_channel_users'])
|
||||
: null,
|
||||
maxStageVideoChannelUsers:
|
||||
js.containsKey("max_stage_video_channel_users")
|
||||
? int.parse(js['max_stage_video_channel_users'])
|
||||
: null,
|
||||
approximateMemberCount: js.containsKey("approximate_member_count")
|
||||
? int.parse(js['approximate_member_count'])
|
||||
: null,
|
||||
approximatePresenceCount: js.containsKey("approximate_presence_count")
|
||||
? int.parse(js['approximate_presence_count'])
|
||||
: null,
|
||||
welcomeScreen: js.containsKey("welcome_screen")
|
||||
? WelcomeScreen.decode(js['welcome_screen'])
|
||||
: null,
|
||||
nsfwLevel: int.parse(js['nsfw_level']),
|
||||
stickers: JsSStickers,
|
||||
premiumProgressBarEnabled:
|
||||
bool.parse(js['premium_progress_bar_enabled']),
|
||||
safetyAlertsChannelId: js['safety_alerts_channel_id'] != null
|
||||
? Snowflake.parse(
|
||||
js['safety_alerts_channel_id'], Snowflake.DiscordEpoch)
|
||||
: null);
|
||||
}
|
||||
}
|
||||
|
||||
class Role {
|
||||
Snowflake id;
|
||||
String name;
|
||||
int color;
|
||||
bool hoist;
|
||||
String? icon;
|
||||
String? unicodeEmoji;
|
||||
int position;
|
||||
BitMask perms;
|
||||
bool managed;
|
||||
bool mentionable;
|
||||
RoleTags? tags;
|
||||
BitMask flags;
|
||||
|
||||
Role(
|
||||
{required this.id,
|
||||
required this.name,
|
||||
required this.color,
|
||||
required this.hoist,
|
||||
this.icon,
|
||||
this.unicodeEmoji,
|
||||
required this.position,
|
||||
required this.perms,
|
||||
required this.managed,
|
||||
required this.mentionable,
|
||||
this.tags,
|
||||
required this.flags});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"id": id.toString(),
|
||||
"name": name,
|
||||
"color": color,
|
||||
"hoist": hoist,
|
||||
if (icon != null) "icon": icon,
|
||||
if (unicodeEmoji != null) "unicode_emoji": unicodeEmoji,
|
||||
"position": position,
|
||||
"permissions": perms.toString(),
|
||||
"managed": managed,
|
||||
"mentionable": mentionable,
|
||||
if (tags != null) "tags": tags,
|
||||
"flags": flags
|
||||
};
|
||||
}
|
||||
|
||||
factory Role.fromJson(String js) {
|
||||
return Role.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory Role.decode(Map<String, dynamic> js) {
|
||||
return Role(
|
||||
id: Snowflake.parse(js['id'], Snowflake.DiscordEpoch),
|
||||
name: js['name'],
|
||||
color: int.parse(js['color']),
|
||||
hoist: bool.parse(js['hoist']),
|
||||
icon: js['icon'] == null ? null : js['icon'],
|
||||
unicodeEmoji: js['unicode_emoji'] == null ? null : js['unicode_emoji'],
|
||||
position: int.parse(js['position']),
|
||||
perms: BitMask.of(int.parse(js['permissions'])),
|
||||
managed: bool.parse(js['managed']),
|
||||
mentionable: bool.parse(js['mentionable']),
|
||||
tags: js['tags'] == null
|
||||
? null
|
||||
: RoleTags.decode(js['tags'] as Map<String, dynamic>),
|
||||
flags: BitMask.of(int.parse(js['flags'])));
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents one of discord's weird booleans in JSON that is null when true, and not present when false.
|
||||
class NullBool {
|
||||
dynamic getValue() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class RoleTags {
|
||||
Snowflake? bot_id;
|
||||
Snowflake? integrationId;
|
||||
NullBool? premiumSubscriber;
|
||||
Snowflake? subscriptionListingId;
|
||||
NullBool? availableForPurchase;
|
||||
NullBool? guildConnections;
|
||||
|
||||
RoleTags(
|
||||
{this.bot_id,
|
||||
this.integrationId,
|
||||
this.premiumSubscriber,
|
||||
this.subscriptionListingId,
|
||||
this.availableForPurchase,
|
||||
this.guildConnections});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
if (bot_id != null) "bot_id": bot_id.toString(),
|
||||
if (integrationId != null) "integration_id": integrationId.toString(),
|
||||
if (premiumSubscriber != null) "premium_subscriber": null,
|
||||
if (subscriptionListingId != null)
|
||||
"subscription_listing_id": subscriptionListingId.toString(),
|
||||
if (availableForPurchase != null) "available_for_purchase": null,
|
||||
if (guildConnections != null) "guild_connections": null
|
||||
};
|
||||
}
|
||||
|
||||
factory RoleTags.fromJson(String js) {
|
||||
return RoleTags.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory RoleTags.decode(Map<String, dynamic> js) {
|
||||
return RoleTags(
|
||||
bot_id: js['bot_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(js['bot_id'], Snowflake.DiscordEpoch),
|
||||
integrationId: js['integration_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(js['integration_id'], Snowflake.DiscordEpoch),
|
||||
premiumSubscriber:
|
||||
js.containsKey("premium_subscriber") ? NullBool() : null,
|
||||
subscriptionListingId: js['subscription_listing_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(
|
||||
js['subscription_listing_id'], Snowflake.DiscordEpoch),
|
||||
availableForPurchase:
|
||||
js.containsKey("available_for_purchase") ? NullBool() : null,
|
||||
guildConnections:
|
||||
js.containsKey("guild_connections") ? NullBool() : null);
|
||||
}
|
||||
}
|
||||
|
||||
enum PermissionFlags {
|
||||
CREATE_INSTANT_INVITE,
|
||||
KICK_MEMBERS,
|
||||
BAN_MEMBERS,
|
||||
ADMINISTRATOR,
|
||||
MANAGE_CHANNELS,
|
||||
MANAGE_GUILD,
|
||||
ADD_REACTIONS,
|
||||
VIEW_AUDIT_LOGS,
|
||||
PRIORITY_SPEAKER,
|
||||
STREAM,
|
||||
VIEW_CHANNEL,
|
||||
SEND_MESSAGES,
|
||||
SEND_TTS_MESSAGES,
|
||||
MANAGE_MESSAGES,
|
||||
EMBED_LINKS,
|
||||
ATTACH_FILES,
|
||||
READ_MESSAGE_HISTORY,
|
||||
MENTION_EVERYONE,
|
||||
USE_EXTERNAL_EMOJIS,
|
||||
VIEW_GUILD_INSIGHTS,
|
||||
CONNECT,
|
||||
SPEAK,
|
||||
MUTE_MEMBERS,
|
||||
DEAFEN_MEMBERS,
|
||||
MOVE_MEMBERS,
|
||||
USE_VAD,
|
||||
CHANGE_NICKNAME,
|
||||
MANAGE_NICKNAMES,
|
||||
MANAGE_ROLES,
|
||||
MANAGE_WEBHOOKS,
|
||||
MANAGE_GUILD_EXPRESSIONS,
|
||||
USE_APPLICATION_COMMANDS,
|
||||
REQUEST_TO_SPEAK,
|
||||
MANAGE_EVENTS,
|
||||
MANAGE_THREADS,
|
||||
CREATE_PUBLIC_THREADS,
|
||||
CREATE_PRIVATE_THREADS,
|
||||
USE_EXTERNAL_STICKERS,
|
||||
SEND_MESSAGES_IN_THREADS,
|
||||
USE_EMBEDDED_ACTIVITIES,
|
||||
MODERATE_MEMBERS,
|
||||
VIEW_CREATOR_MONETIZATION_ANALYTICS,
|
||||
USE_SOUNDBOARD,
|
||||
CREATE_GUILD_EXPRESSIONS,
|
||||
CREATE_EVENTS,
|
||||
USE_EXTERNAL_SOUNDS,
|
||||
SEND_VOICE_MESSAGES,
|
||||
SEND_POLLS,
|
||||
USE_EXTERNAL_APPS
|
||||
}
|
||||
|
||||
class Emoji {
|
||||
Snowflake id;
|
||||
String? name;
|
||||
List<Role>? roles;
|
||||
User? user;
|
||||
bool? requireColons;
|
||||
bool? managed;
|
||||
bool? animated;
|
||||
bool? available;
|
||||
|
||||
Emoji(
|
||||
{required this.id,
|
||||
required this.name,
|
||||
this.roles,
|
||||
this.user,
|
||||
this.requireColons,
|
||||
this.managed,
|
||||
this.animated,
|
||||
this.available});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
List<Map<String, dynamic>> rolesJs = [];
|
||||
if (roles != null) {
|
||||
for (Role role in roles!) {
|
||||
rolesJs.add(role.toJson());
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
"id": id.toString(),
|
||||
"name": name,
|
||||
if (roles != null) "roles": rolesJs,
|
||||
if (user != null) "user": user!.toJson(),
|
||||
if (requireColons != null) "require_colons": requireColons,
|
||||
if (managed != null) "managed": managed,
|
||||
if (animated != null) "animated": animated,
|
||||
if (available != null) "available": available
|
||||
};
|
||||
}
|
||||
|
||||
factory Emoji.fromJson(String js) {
|
||||
return Emoji.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory Emoji.decode(Map<String, dynamic> js) {
|
||||
List<Role>? JsRoles = null;
|
||||
if (js.containsKey("roles")) {
|
||||
JsRoles = [];
|
||||
for (var entry in js['roles'] as List<Map<String, dynamic>>) {
|
||||
JsRoles.add(Role.decode(entry));
|
||||
}
|
||||
}
|
||||
return Emoji(
|
||||
id: Snowflake.parse(js['id'], Snowflake.DiscordEpoch),
|
||||
name: js['name'],
|
||||
roles: JsRoles,
|
||||
user: js.containsKey("user") ? User.decode(js['user']) : null,
|
||||
requireColons: js.containsKey("require_colons")
|
||||
? bool.parse(js['require_colons'])
|
||||
: null,
|
||||
managed: js.containsKey("managed") ? bool.parse(js['managed']) : null,
|
||||
animated:
|
||||
js.containsKey("animated") ? bool.parse(js['animated']) : null,
|
||||
available:
|
||||
js.containsKey("available") ? bool.parse(js['available']) : null);
|
||||
}
|
||||
}
|
||||
|
||||
/// Values obtained by names
|
||||
enum GuildFeatures {
|
||||
ANIMATED_BANNER,
|
||||
ANIMATED_ICON,
|
||||
APPLICATION_COMMAND_PERMISSIONS_V2,
|
||||
AUTO_MODERATION,
|
||||
BANNER,
|
||||
|
||||
/// Required Administrator
|
||||
COMMUNITY,
|
||||
CREATOR_MONETIZABLE_PROVISIONAL,
|
||||
CREATOR_STORE_PAGE,
|
||||
DEVELOPER_SUPPORT_SERVER,
|
||||
|
||||
/// Required Administrator
|
||||
DISCOVERABLE,
|
||||
FEATURABLE,
|
||||
|
||||
/// Requires Manage Guild
|
||||
INVITES_DISABLED,
|
||||
INVITE_SPLASH,
|
||||
MEMBER_VERIFICATION_GATE_ENABLED,
|
||||
MORE_STICKERS,
|
||||
NEWS,
|
||||
PARTNERED,
|
||||
PREVIEW_ENABLED,
|
||||
|
||||
/// Requires Manage Guild
|
||||
RAID_ALERTS_DISABLED,
|
||||
ROLE_ICONS,
|
||||
ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE,
|
||||
ROLE_SUBSCRIPTIONS_ENABLED,
|
||||
TICKETED_EVENTS_ENABLED,
|
||||
VANITY_URL,
|
||||
VERIFIED,
|
||||
VIP_REGIONS,
|
||||
WELCOME_SCREEN_ENABLED;
|
||||
|
||||
static GuildFeatures? byName(String sName) {
|
||||
for (GuildFeatures gf in GuildFeatures.values) {
|
||||
if (gf.name == sName) return gf;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Flags obtained by value
|
||||
enum SystemChannelFlags {
|
||||
SUPPRESS_JOIN_NOTIFICATIONS,
|
||||
SUPPRESS_PREMIUM_SUBSCRIPTIONS,
|
||||
SUPPRESS_GUILD_REMINDER_NOTIFICATIONS,
|
||||
SUPPRESS_JOIN_NOTIFICATION_REPLIES,
|
||||
SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS,
|
||||
SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATION_REPLIES
|
||||
}
|
||||
|
||||
/// Levels obtained by index
|
||||
enum PremiumTiers { NONE, TIER_1, TIER_2, TIER_3 }
|
||||
|
||||
/// Levels obtained by index
|
||||
enum GuildNSFWLevel { DEFAULT, EXPLICIT, SAFE, AGE_RESTRICTED }
|
||||
|
||||
/// Levels obtained by index
|
||||
enum VerificationLevel { NONE, LOW, MEDIUM, HIGH, VERY_HIGH }
|
||||
|
||||
/// Levels obtained by index
|
||||
enum MFALevel { NONE, ELEVATED }
|
||||
|
||||
/// Levels obtains by index
|
||||
enum ExplicitContentFilterLevels {
|
||||
DISABLED,
|
||||
MEMBERS_WITHOUT_ROLES,
|
||||
ALL_MEMBERS
|
||||
}
|
||||
|
||||
/// Levels obtained via index
|
||||
enum DefaultMessageNotificationLevel { ALL_MESSAGES, ONLY_MEMBERS }
|
||||
|
||||
class WelcomeScreen {
|
||||
String? description;
|
||||
List<WelcomeScreenChannel> welcomeChannels;
|
||||
|
||||
WelcomeScreen({required this.description, required this.welcomeChannels});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
List<Map<String, dynamic>> wscJs = [];
|
||||
for (WelcomeScreenChannel wsc in welcomeChannels) {
|
||||
wscJs.add(wsc.toJson());
|
||||
}
|
||||
|
||||
return {"description": description, "welcome_channels": wscJs};
|
||||
}
|
||||
|
||||
factory WelcomeScreen.fromJson(String js) {
|
||||
return WelcomeScreen.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory WelcomeScreen.decode(Map<String, dynamic> js) {
|
||||
List<WelcomeScreenChannel> wsc = [];
|
||||
for (var entry in js['welcome_channels']) {
|
||||
wsc.add(WelcomeScreenChannel.decode(entry));
|
||||
}
|
||||
|
||||
return WelcomeScreen(description: js['description'], welcomeChannels: wsc);
|
||||
}
|
||||
}
|
||||
|
||||
class WelcomeScreenChannel {
|
||||
Snowflake channelId;
|
||||
String description;
|
||||
Snowflake? emojiId;
|
||||
String? emojiName;
|
||||
|
||||
WelcomeScreenChannel(
|
||||
{required this.channelId,
|
||||
required this.description,
|
||||
required this.emojiId,
|
||||
required this.emojiName});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"channel_id": channelId.toString(),
|
||||
"description": description,
|
||||
"emoji_id": emojiId == null ? null : emojiId.toString(),
|
||||
"emoji_name": emojiName
|
||||
};
|
||||
}
|
||||
|
||||
factory WelcomeScreenChannel.fromJson(String js) {
|
||||
return WelcomeScreenChannel.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory WelcomeScreenChannel.decode(Map<String, dynamic> js) {
|
||||
return WelcomeScreenChannel(
|
||||
channelId: Snowflake.parse(js['channel_id'], Snowflake.DiscordEpoch),
|
||||
description: js['description'],
|
||||
emojiId: js['emoji_id'] == null
|
||||
? null
|
||||
: Snowflake.parse(js['emoji_id'], Snowflake.DiscordEpoch),
|
||||
emojiName: js['emoji_name']);
|
||||
}
|
||||
}
|
176
lib/discord/structures/sticker.dart
Normal file
176
lib/discord/structures/sticker.dart
Normal file
|
@ -0,0 +1,176 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:libac_dart/discord/structures/user.dart';
|
||||
|
||||
import '../../structs/Snowflake.dart';
|
||||
|
||||
class Sticker {
|
||||
Snowflake id;
|
||||
Snowflake? packId;
|
||||
String name;
|
||||
String? description;
|
||||
String tags;
|
||||
String? asset;
|
||||
int type;
|
||||
int formatType;
|
||||
bool? available;
|
||||
Snowflake? guildId;
|
||||
User? user;
|
||||
int? sortValue;
|
||||
|
||||
Sticker(
|
||||
{required this.id,
|
||||
this.packId,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.tags,
|
||||
this.asset,
|
||||
required this.type,
|
||||
required this.formatType,
|
||||
this.available,
|
||||
this.guildId,
|
||||
this.user,
|
||||
this.sortValue});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"id": id.toString(),
|
||||
if (packId != null) "pack_id": packId.toString(),
|
||||
"name": name,
|
||||
"description": description,
|
||||
"tags": tags,
|
||||
if (asset != null) "asset": asset,
|
||||
"type": type,
|
||||
"format_type": formatType,
|
||||
if (available != null) "available": available,
|
||||
if (guildId != null) "guild_id": guildId,
|
||||
if (user != null) "user": user!.toJson(),
|
||||
if (sortValue != null) "sort_value": sortValue
|
||||
};
|
||||
}
|
||||
|
||||
factory Sticker.fromJson(String js) {
|
||||
return Sticker.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory Sticker.decode(Map<String, dynamic> js) {
|
||||
return Sticker(
|
||||
id: Snowflake.parse(js['id'], Snowflake.DiscordEpoch),
|
||||
packId: js.containsKey("pack_id")
|
||||
? Snowflake.parse(js['pack_id'], Snowflake.DiscordEpoch)
|
||||
: null,
|
||||
name: js['name'],
|
||||
description: js['description'],
|
||||
tags: js['tags'],
|
||||
asset: js['asset'],
|
||||
type: js['type'],
|
||||
formatType: js['format_type'],
|
||||
available:
|
||||
js.containsKey("available") ? bool.parse(js['available']) : null,
|
||||
guildId: js.containsKey("guild_id")
|
||||
? Snowflake.parse(js['guild_id'], Snowflake.DiscordEpoch)
|
||||
: null,
|
||||
user: js.containsKey("user") ? User.decode(js['user']) : null,
|
||||
sortValue:
|
||||
js.containsKey("sort_value") ? int.parse(js['sort_value']) : null);
|
||||
}
|
||||
}
|
||||
|
||||
enum StickerType { STANDARD, GUILD }
|
||||
|
||||
enum StickerFormatTypes { PNG, APNG, LOTTIE, GIF }
|
||||
|
||||
class StickerItem {
|
||||
Snowflake id;
|
||||
String name;
|
||||
int formatType;
|
||||
|
||||
StickerItem({required this.id, required this.name, required this.formatType});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {"id": id.toString(), "name": name, "format_type": formatType};
|
||||
}
|
||||
|
||||
factory StickerItem.fromJson(String js) {
|
||||
return StickerItem.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory StickerItem.decode(Map<String, dynamic> js) {
|
||||
return StickerItem(
|
||||
id: Snowflake.parse(js['id'], Snowflake.DiscordEpoch),
|
||||
name: js['name'],
|
||||
formatType: int.parse(js['format_type']));
|
||||
}
|
||||
}
|
||||
|
||||
class StickerPack {
|
||||
Snowflake id;
|
||||
List<Sticker> stickers;
|
||||
String name;
|
||||
Snowflake sku_id;
|
||||
Snowflake? coverStickerId;
|
||||
String description;
|
||||
Snowflake? bannerAssetId;
|
||||
|
||||
StickerPack(
|
||||
{required this.id,
|
||||
required this.stickers,
|
||||
required this.name,
|
||||
required this.sku_id,
|
||||
this.coverStickerId,
|
||||
required this.description,
|
||||
this.bannerAssetId});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
List<Map<String, dynamic>> stickersJs = [];
|
||||
for (Sticker sticker in stickers) {
|
||||
stickersJs.add(sticker.toJson());
|
||||
}
|
||||
|
||||
return {
|
||||
"id": id.toString(),
|
||||
"stickers": stickersJs,
|
||||
"name": name,
|
||||
"sku_id": sku_id.toString(),
|
||||
if (coverStickerId != null) "cover_sticker_id": coverStickerId.toString(),
|
||||
"description": description,
|
||||
if (bannerAssetId != null) "banner_asset_id": bannerAssetId.toString()
|
||||
};
|
||||
}
|
||||
|
||||
factory StickerPack.fromJson(String js) {
|
||||
return StickerPack.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory StickerPack.decode(Map<String, dynamic> js) {
|
||||
List<Sticker> jsStickers = [];
|
||||
for (var entry in js['stickers']) {
|
||||
jsStickers.add(Sticker.decode(entry));
|
||||
}
|
||||
|
||||
return StickerPack(
|
||||
id: Snowflake.parse(js['id'], Snowflake.DiscordEpoch),
|
||||
stickers: jsStickers,
|
||||
name: js['name'],
|
||||
sku_id: Snowflake.parse(js['sku_id'], Snowflake.DiscordEpoch),
|
||||
coverStickerId: js.containsKey("cover_sticker_id")
|
||||
? Snowflake.parse(js['cover_sticker_id'], Snowflake.DiscordEpoch)
|
||||
: null,
|
||||
description: js['description'],
|
||||
bannerAssetId: js.containsKey("banner_asset_id")
|
||||
? Snowflake.parse(js['banner_asset_id'], Snowflake.DiscordEpoch)
|
||||
: null);
|
||||
}
|
||||
}
|
280
lib/discord/structures/user.dart
Normal file
280
lib/discord/structures/user.dart
Normal file
|
@ -0,0 +1,280 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:libac_dart/utils/DictTools.dart';
|
||||
|
||||
import '../../structs/Bitmasks.dart';
|
||||
import '../../structs/Snowflake.dart';
|
||||
|
||||
class User {
|
||||
Snowflake id;
|
||||
String username;
|
||||
String discriminator;
|
||||
String? globalName;
|
||||
String? avatar;
|
||||
bool? bot;
|
||||
bool? system;
|
||||
bool? mfaEnabled;
|
||||
String? banner;
|
||||
int? accentColor;
|
||||
String? locale;
|
||||
bool? verified;
|
||||
String? email;
|
||||
|
||||
/// UserFlags
|
||||
BitMask? flags;
|
||||
|
||||
/// PremiumType
|
||||
BitMask? premiumType;
|
||||
|
||||
/// UserFlags
|
||||
BitMask? publicFlags;
|
||||
AvatarDecorationData? decoration;
|
||||
|
||||
User(
|
||||
{required this.id,
|
||||
required this.username,
|
||||
required this.discriminator,
|
||||
this.globalName,
|
||||
this.avatar,
|
||||
this.bot,
|
||||
this.system,
|
||||
this.mfaEnabled,
|
||||
this.banner,
|
||||
this.accentColor,
|
||||
this.locale,
|
||||
this.verified,
|
||||
this.email,
|
||||
this.flags,
|
||||
this.premiumType,
|
||||
this.publicFlags,
|
||||
this.decoration});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"id": id.toString(),
|
||||
"username": username,
|
||||
"discriminator": discriminator,
|
||||
"global_name": globalName,
|
||||
"avatar": avatar,
|
||||
if (bot != null) "bot": bot,
|
||||
if (system != null) "system": system,
|
||||
if (mfaEnabled != null) "mfa_enabled": mfaEnabled,
|
||||
if (banner != null) "banner": banner,
|
||||
if (accentColor != null) "accent_color": accentColor,
|
||||
if (locale != null) "locale": locale,
|
||||
if (verified != null) "verified": verified,
|
||||
if (email != null) "email": email,
|
||||
if (flags != null) "flags": flags!.value,
|
||||
if (premiumType != null) "premium_type": premiumType!.value,
|
||||
if (publicFlags != null) "public_flags": publicFlags!.value,
|
||||
if (decoration != null) "avatar_decoration_data": decoration!.toJson()
|
||||
};
|
||||
}
|
||||
|
||||
factory User.fromJson(String js) {
|
||||
return User.decode(json.decode(js))!;
|
||||
}
|
||||
|
||||
static User? decode(Map<String, dynamic>? js) {
|
||||
if (js == null) return null;
|
||||
return User(
|
||||
id: Snowflake.parse(js['id'] as String, Snowflake.DiscordEpoch),
|
||||
username: js['username'] as String,
|
||||
discriminator: js['discrimination'] as String,
|
||||
globalName: js['global_name'],
|
||||
avatar: js['avatar'],
|
||||
bot: setor(js, "bot", null),
|
||||
system: setor(js, "system", null),
|
||||
mfaEnabled: setor(js, "mfa_enabled", null),
|
||||
banner: setor(js, "banner", null),
|
||||
accentColor: setor(js, "accent_color", null),
|
||||
locale: setor(js, "locale", null),
|
||||
verified: setor(js, "verified", null),
|
||||
email: setor(js, "email", null),
|
||||
flags: BitMask.of(setor(js, "flags", null)),
|
||||
premiumType: BitMask.of(setor(js, "premium_type", null)),
|
||||
publicFlags: BitMask.of(setor(js, "public_flags", null)),
|
||||
decoration: AvatarDecorationData.decode(
|
||||
setor(js, "avatar_decoration_data", null)));
|
||||
}
|
||||
}
|
||||
|
||||
enum UserFlags {
|
||||
DiscordEmployee(1 << 0),
|
||||
PartneredServerOwner(1 << 1),
|
||||
HypeSquadEvents(1 << 2),
|
||||
BugHunterLv1(1 << 3),
|
||||
HouseBravery(1 << 6),
|
||||
HouseBrilliance(1 << 7),
|
||||
HouseBalance(1 << 8),
|
||||
EarlyNitro(1 << 9),
|
||||
Team(1 << 10),
|
||||
BugHunterLv2(1 << 14),
|
||||
VerifiedBot(1 << 16),
|
||||
VerifiedEarlyDeveloper(1 << 17),
|
||||
ModeratorProgramAlumni(1 << 18),
|
||||
BotHTTP(1 << 19),
|
||||
ActiveDeveloper(1 << 22);
|
||||
|
||||
final int flags;
|
||||
|
||||
const UserFlags(this.flags);
|
||||
}
|
||||
|
||||
enum PremiumType {
|
||||
None(0),
|
||||
Classic(1),
|
||||
Nitro(2),
|
||||
Basic(3);
|
||||
|
||||
final int flag;
|
||||
|
||||
const PremiumType(this.flag);
|
||||
}
|
||||
|
||||
class AvatarDecorationData {
|
||||
String asset;
|
||||
Snowflake sku;
|
||||
|
||||
AvatarDecorationData({required this.asset, required this.sku});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {"asset": asset, "sku_id": sku.toString()};
|
||||
}
|
||||
|
||||
factory AvatarDecorationData.fromJson(String js) {
|
||||
return AvatarDecorationData.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory AvatarDecorationData.decode(Map<String, dynamic> js) {
|
||||
return AvatarDecorationData(
|
||||
asset: js['asset'] as String,
|
||||
sku: Snowflake.parse(js['sku_id'] as String, Snowflake.DiscordEpoch));
|
||||
}
|
||||
}
|
||||
|
||||
class Team {
|
||||
String? icon;
|
||||
Snowflake id;
|
||||
List<TeamMember> members;
|
||||
String name;
|
||||
Snowflake ownerUserId;
|
||||
|
||||
Team(
|
||||
{required this.icon,
|
||||
required this.id,
|
||||
required this.members,
|
||||
required this.name,
|
||||
required this.ownerUserId});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
List<Map<String, dynamic>> membersJs = [];
|
||||
for (TeamMember tm in members) {}
|
||||
|
||||
return {
|
||||
"icon": icon,
|
||||
"id": id.toString(),
|
||||
"members": membersJs,
|
||||
"name": name,
|
||||
"owner_user_id": ownerUserId.toString()
|
||||
};
|
||||
}
|
||||
|
||||
factory Team.fromJson(String js) {
|
||||
return Team.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory Team.decode(Map<String, dynamic> js) {
|
||||
List<TeamMember> memberjs = [];
|
||||
List<Map<String, dynamic>> mmap =
|
||||
js['members'] as List<Map<String, dynamic>>;
|
||||
for (var entry in mmap) {
|
||||
memberjs.add(TeamMember.decode(entry));
|
||||
}
|
||||
|
||||
return Team(
|
||||
icon: js['icon'],
|
||||
id: Snowflake.parse(js['id'], Snowflake.DiscordEpoch),
|
||||
members: memberjs,
|
||||
name: js['name'],
|
||||
ownerUserId:
|
||||
Snowflake.parse(js['owner_user_id'], Snowflake.DiscordEpoch));
|
||||
}
|
||||
}
|
||||
|
||||
class TeamMember {
|
||||
MembershipState membershipState;
|
||||
Snowflake teamId;
|
||||
User user;
|
||||
String role;
|
||||
|
||||
TeamMember(
|
||||
{required this.membershipState,
|
||||
required this.teamId,
|
||||
required this.user,
|
||||
required this.role});
|
||||
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
"membership_state": membershipState,
|
||||
"team_id": teamId.toString(),
|
||||
"user": user.toJson(),
|
||||
"role": role
|
||||
};
|
||||
}
|
||||
|
||||
factory TeamMember.fromJson(String js) {
|
||||
return TeamMember.decode(json.decode(js));
|
||||
}
|
||||
|
||||
factory TeamMember.decode(Map<String, dynamic> js) {
|
||||
return TeamMember(
|
||||
membershipState: MembershipState.of(js['membership_state']),
|
||||
teamId: Snowflake.parse(js['team_id'], Snowflake.DiscordEpoch),
|
||||
user: User.decode(js['user'] as Map<String, dynamic>)!,
|
||||
role: js['role']);
|
||||
}
|
||||
}
|
||||
|
||||
enum MembershipState {
|
||||
INVITED(1),
|
||||
ACCEPTED(2);
|
||||
|
||||
final int val;
|
||||
|
||||
const MembershipState(this.val);
|
||||
|
||||
static MembershipState of(int val) {
|
||||
switch (val) {
|
||||
case 1:
|
||||
{
|
||||
return MembershipState.INVITED;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return MembershipState.ACCEPTED;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return MembershipState.INVITED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
lib/structs/Bitmasks.dart
Normal file
27
lib/structs/Bitmasks.dart
Normal file
|
@ -0,0 +1,27 @@
|
|||
mixin EFlags on Enum {
|
||||
int get value => 1 << index;
|
||||
}
|
||||
|
||||
/// A simple universal bitmask object
|
||||
class BitMask {
|
||||
int _mask = 0;
|
||||
|
||||
BitMask(this._mask);
|
||||
|
||||
void setBit(int bit) {
|
||||
_mask |= bit;
|
||||
}
|
||||
|
||||
void unsetBit(int bit) {
|
||||
_mask ^= bit;
|
||||
}
|
||||
|
||||
int get value => _mask;
|
||||
|
||||
factory BitMask.of(int? val) {
|
||||
if (val == null)
|
||||
return BitMask(0);
|
||||
else
|
||||
return BitMask(val);
|
||||
}
|
||||
}
|
11
lib/structs/JsonSerializable.dart
Normal file
11
lib/structs/JsonSerializable.dart
Normal file
|
@ -0,0 +1,11 @@
|
|||
import 'dart:convert';
|
||||
|
||||
abstract class IJsonSerializable {
|
||||
/// Encode json and return as String
|
||||
String encode() {
|
||||
return json.encode(toJson());
|
||||
}
|
||||
|
||||
/// Returns a Json Object
|
||||
Map<String,dynamic> toJson();
|
||||
}
|
69
lib/structs/Snowflake.dart
Normal file
69
lib/structs/Snowflake.dart
Normal file
|
@ -0,0 +1,69 @@
|
|||
class Snowflake implements Comparable<Snowflake> {
|
||||
/// Discord Epoch
|
||||
static final DiscordEpoch = DateTime.utc(2015, 1, 1, 0, 0, 0);
|
||||
|
||||
/// Aria's Creations Epoch
|
||||
static final ACEpoch = DateTime.utc(2024, 7, 9, 23, 0, 0);
|
||||
|
||||
final DateTime epoch;
|
||||
final int value;
|
||||
static final ZERO = Snowflake(epoch: DiscordEpoch, value: 0);
|
||||
|
||||
Snowflake({required this.epoch, required this.value});
|
||||
|
||||
DateTime get timestamp =>
|
||||
epoch.add(Duration(milliseconds: millisecondsSinceEpoch));
|
||||
|
||||
int get millisecondsSinceEpoch => value >> 22;
|
||||
|
||||
int get workerId => (value & 0x3E0000) >> 17;
|
||||
|
||||
int get processId => (value & 0x1F000) >> 12;
|
||||
|
||||
int get increment => value & 0xFFF;
|
||||
|
||||
bool get isZero => value == 0;
|
||||
|
||||
factory Snowflake.parse(dynamic value, DateTime epoch) {
|
||||
int val = int.parse(value.toString());
|
||||
return Snowflake(epoch: epoch, value: val);
|
||||
}
|
||||
|
||||
factory Snowflake.now(DateTime epoch) =>
|
||||
Snowflake.fromDateTime(DateTime.now(), epoch);
|
||||
|
||||
factory Snowflake.fromDateTime(DateTime dt, DateTime epoch) {
|
||||
return Snowflake(
|
||||
epoch: epoch, value: dt.difference(epoch).inMilliseconds << 22);
|
||||
}
|
||||
|
||||
bool isBefore(Snowflake other) => timestamp.isBefore(other.timestamp);
|
||||
|
||||
bool isAfter(Snowflake other) => timestamp.isAfter(other.timestamp);
|
||||
|
||||
bool isAtSameMomentAs(Snowflake other) =>
|
||||
timestamp.isAtSameMomentAs(other.timestamp);
|
||||
|
||||
Snowflake operator +(Duration duration) =>
|
||||
Snowflake.fromDateTime(timestamp.add(duration), epoch);
|
||||
|
||||
Snowflake operator -(Duration duration) =>
|
||||
Snowflake.fromDateTime(timestamp.subtract(duration), epoch);
|
||||
|
||||
@override
|
||||
int compareTo(Snowflake other) => value.compareTo(other.value);
|
||||
|
||||
bool operator <(Snowflake other) => isBefore(other);
|
||||
|
||||
bool operator >(Snowflake other) => isAfter(other);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) || (other is Snowflake && other.value == value);
|
||||
|
||||
@override
|
||||
int get hashCode => value.hashCode;
|
||||
|
||||
@override
|
||||
String toString() => value.toString();
|
||||
}
|
6
lib/utils/DictTools.dart
Normal file
6
lib/utils/DictTools.dart
Normal file
|
@ -0,0 +1,6 @@
|
|||
dynamic setor(Map<String, dynamic> arr, String element, dynamic other) {
|
||||
if (arr.containsKey(element))
|
||||
return arr[element];
|
||||
else
|
||||
return other;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
name: libac_dart
|
||||
description: "Aria's Creations code library"
|
||||
version: 1.1.070324+0002
|
||||
version: 1.2.072024+2035
|
||||
homepage: "https://zontreck.com"
|
||||
|
||||
|
||||
|
@ -9,6 +9,8 @@ environment:
|
|||
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
crypto: ^3.0.3
|
||||
dio: ^5.5.0+1
|
||||
# path: ^1.8.0
|
||||
|
||||
dev_dependencies:
|
||||
|
@ -16,7 +18,7 @@ dev_dependencies:
|
|||
test: ^1.24.0
|
||||
|
||||
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
|
||||
# To add assets to your package, add an assets section, like this:
|
||||
|
|
|
@ -8,7 +8,7 @@ import 'package:test/scaffolding.dart';
|
|||
|
||||
void main() {
|
||||
test("Test parsing a argument", () async {
|
||||
List<String> testArgs = ["--test=12", "--enable", "--put=\"Here\""];
|
||||
List<String> testArgs = ["--test=12", "--enable", "--put=Here"];
|
||||
|
||||
Arguments defaults = Arguments();
|
||||
|
||||
|
|
|
@ -25,28 +25,6 @@ void main() {
|
|||
}
|
||||
});
|
||||
|
||||
test("Check UUIDv4 for validity", () {
|
||||
var ID = UUID.generate(4);
|
||||
ByteLayer layer = ByteLayer();
|
||||
//layer.writeLong(ID.getMostSignificantBits().toInt());
|
||||
//layer.writeLong(ID.getLeastSignificantBits().toInt());
|
||||
|
||||
print(
|
||||
"Checking version bit: ${layer.checkBit(6, 0x40)} - ${layer.getBit(6)}");
|
||||
expect(layer.checkBit(6, 0x40), true);
|
||||
});
|
||||
|
||||
test("Generate and check a UUIDv3", () {
|
||||
var ID3 = UUID.generate(3, parameters: ["Test", "Test2"]);
|
||||
ByteLayer layer = ByteLayer();
|
||||
//layer.writeLong(ID3.getMostSignificantBits().toInt());
|
||||
//layer.writeLong(ID3.getLeastSignificantBits().toInt());
|
||||
|
||||
print(
|
||||
"Checking version bit: ${layer.checkBit(6, 0x30)} - ${layer.getBit(6)}");
|
||||
expect(layer.checkBit(6, 0x30), true);
|
||||
});
|
||||
|
||||
test("Test stream bitflipping", () {
|
||||
ByteLayer layer = ByteLayer();
|
||||
layer.writeBytes({0, 255, 80});
|
||||
|
|
Loading…
Reference in a new issue