Skip to content

Commit 023de28

Browse files
TheArmaganErdemGKSL
andcommitted
Dinamik Dil Desteği, Gerçek Zamanlı İnteraksiyon paylaşma
Co-Authored-By: Erdem <[email protected]>
1 parent 6273e56 commit 023de28

File tree

15 files changed

+274
-45
lines changed

15 files changed

+274
-45
lines changed

config.js

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module.exports = new (require("./types/Config"))({
1313
// Okumanızı tavsiye ederim: https://discordjs.guide/popular-topics/intents.html
1414
intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_MEMBERS", "GUILD_WEBHOOKS"]
1515
},
16+
// Botunuzun varsayılan dili.
17+
defaultLanguage: "tr",
1618
// Diğer ayarlar. Bunun içine ne isterseniz koyabilirsiniz.
1719
// Ulaşmak için "Underline.config.other" objesini kullanabilirsiniz.
1820
other: {
@@ -30,60 +32,37 @@ module.exports = new (require("./types/Config"))({
3032
userErrors: {
3133
// Arka arkaya interaksiyon kullanma limiti aşıldığında.
3234
coolDown(interaction, uInteraction, coolDown, type, other) {
33-
switch (type) {
34-
case "user": {
35-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu sen tekrardan ${(coolDown / 1000).toFixed(2)} saniye içerisinde kullanabilirsin.` })
36-
break;
37-
}
38-
case "member": {
39-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu bu sunucuda tekrardan senin kullanabilmen için ${(coolDown / 1000).toFixed(2)} saniye beklemen lazım.` })
40-
break;
41-
}
42-
case "guild": {
43-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu bu sunucuda tekrardan ${(coolDown / 1000).toFixed(2)} saniye içerisinde kullanabilirsin.` })
44-
break;
45-
}
46-
case "channel": {
47-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu bu kanalda tekrardan ${(coolDown / 1000).toFixed(2)} saniye içerisinde kullanabilirsin.` })
48-
break;
49-
}
50-
case "message": {
51-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu bu mesajda tekrardan ${(coolDown / 1000).toFixed(2)} saniye içerisinde kullanabilirsin.` })
52-
break;
53-
}
54-
case "any": {
55-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu tekrardan ${(coolDown / 1000).toFixed(2)} saniye içerisinde kullanabilirsin.` })
56-
break;
57-
}
58-
}
59-
35+
interaction.reply({
36+
ephemeral: true,
37+
content: other.locale.userErrors.coolDown[type]((coolDown / 1000).toFixed(2))
38+
});
6039
},
6140
// interaksiyon kapalı olduğunda
6241
disabled(interaction, uInteraction, other) {
63-
interaction.reply({ ephemeral: true, content: "Bu interaksiyon kapalı." });
42+
interaction.reply({ ephemeral: true, content: other.locale.userErrors.disabled() });
6443
},
6544
// Kullanıcı bottan yasaklı olduğunda.
6645
blocked(interaction, uInteraction, other) {
67-
interaction.reply({ ephemeral: true, content: "Bottan yasaklanmışsınız." });
46+
interaction.reply({ ephemeral: true, content: other.locale.userErrors.blocked() });
6847
},
6948
// interaksiyon sadece geliştiricilere özel olduğunda.
7049
developerOnly(interaction, uInteraction, other) {
71-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu sadece bot geliştiricileri kullanabilir.` })
50+
interaction.reply({ ephemeral: true, content: other.locale.userErrors.developerOnly() });
7251
},
7352
// interaksiyon sadece sunucu sahiplerine özel olduğunda.
7453
guildOwnerOnly(interaction, uInteraction, other) {
75-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu sadece sunucu sahipleri kullanabilir.` })
54+
interaction.reply({ ephemeral: true, content: other.locale.userErrors.guildOwnerOnly() });
7655
},
7756
guildOnly(interaction, uInteraction, other) {
78-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu sadece sunucularda kullanılabilir.` })
57+
interaction.reply({ ephemeral: true, content: other.locale.userErrors.guildOnly() });
7958
},
8059
// Botun çalışmak için x yertkilerine ihtiyacı olduğunda.
8160
botPermsRequired(interaction, uInteraction, perms, other) {
82-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonun çalışması için ${perms.join(", ")} yetkilerine ihtiyacım var.` })
61+
interaction.reply({ ephemeral: true, content: other.locale.userErrors.botPermsRequired(perms.join(", ")) });
8362
},
8463
// Kullanıcının interaksiyonu kullanabilmek için x yetkilerine ihtiyacı olduğunda.
8564
userPermsRequired(interaction, uInteraction, perms, other) {
86-
interaction.reply({ ephemeral: true, content: `Bu interaksiyonu kullanabilmek için ${perms.join(", ")} yetkilerine ihtiyacın var.` })
65+
interaction.reply({ ephemeral: true, content: other.locale.userErrors.userPermsRequired(perms.join(", ")) });
8766
},
8867
},
8968
// Her interaksiyonun varsayılan ayarları her anahtarın ne
@@ -135,6 +114,8 @@ module.exports = new (require("./types/Config"))({
135114
async onInteraction(uInteraction, interaction, other) {
136115
return true;
137116
},
117+
// İnteraksiyon hatasız bir şekilde çalıştıktan sonra tetikleniyor. (Armağan: peki.)
118+
async onAfterInteraction(uInteraction, interaction, other) { },
138119
// eventteki bütün kontrolleri geçtikten sonra, event
139120
// hemen çalıştırılmadan önce çalışır.
140121
// Sadece cevap true ise işleme devam eder.

globals.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
interface Underline {
44
interactions: import("discord.js").Collection<string, import("./types/Interaction") >
55
events: import("discord.js").Collection<string, import("./types/Event") >
6+
locales: import("discord.js").Collection<string, import("./types/Locale") >
67
config: import("./types/Config");
78
client: import("discord.js").Client;
89
Interaction: typeof import("./types/Interaction"),
@@ -12,6 +13,7 @@ interface Underline {
1213
Event: typeof import("./types/Event"),
1314
Button: typeof import("./types/Button"),
1415
SelectMenu: typeof import("./types/SelectMenu"),
16+
Locale: typeof import("./types/Locale"),
1517

1618
reload(): Promise<any>;
1719

index.js

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,25 @@ const { makeSureFolderExists } = require("stuffs");
1010
const client = new Discord.Client(config.clientOptions);
1111
const interactions = new Discord.Collection();
1212
const events = new Discord.Collection();
13+
const locales = new Discord.Collection();
1314
let interactionFiles;
1415
let eventFiles;
16+
let localeFiles;
1517
globalThis.Underline = {
1618
...config.globalObjects,
1719
config,
1820
client,
1921
interactions,
2022
events,
23+
locales,
2124
Interaction: require('./types/Interaction'),
2225
Event: require('./types/Event'),
2326
SlashCommand: require("./types/SlashCommand"),
2427
MessageAction: require("./types/MessageAction"),
2528
UserAction: require("./types/UserAction"),
2629
SelectMenu: require("./types/SelectMenu"),
2730
Button: require("./types/Button"),
31+
Locale: require("./types/Locale"),
2832
}
2933

3034
async function getEventFilePaths() {
@@ -49,13 +53,43 @@ async function getInteractionFilePaths() {
4953
return VInteractionFiles;
5054
}
5155

56+
async function getLocaleFilePaths() {
57+
let localesPath = path.resolve("./locales");
58+
await makeSureFolderExists(localesPath);
59+
let VLocaleFiles = await readdirRecursive(localesPath);
60+
VLocaleFiles = VLocaleFiles.filter(i => {
61+
let state = path.basename(i).startsWith("-");
62+
return !state;
63+
});
64+
return VLocaleFiles;
65+
}
66+
5267
/** @type {{name:string,listener:()=>any,base:any}[]} */
5368
let eventListeners = [];
5469

5570
async function load() {
5671
let loadStart = Date.now();
5772
console.debug(`[HATA AYIKLAMA] Yüklemeye başlandı!`);
5873

74+
localeFiles = await getLocaleFilePaths();
75+
await chillout.forEach(localeFiles, (localeFile) => {
76+
let start = Date.now();
77+
let rltPath = path.relative(__dirname, localeFile);
78+
console.info(`[BİLGİ] "${rltPath}" konumundaki dil yükleniyor..`)
79+
/** @type {import("./types/Locale")} */
80+
let locale = require(localeFile);
81+
82+
if (locale._type != "locale")
83+
return console.warn(`[UYARI] "${rltPath}" dil dosyası boş. Atlanıyor..`);
84+
85+
if (locales.has(locale.locale))
86+
return console.warn(`[UYARI] ${locale.locale} dili zaten yüklenmiş. Atlanıyor..`);
87+
88+
locales.set(locale.locale, locale);
89+
console.info(`[BİLGİ] "${locale.locale}" dili yüklendi. (${Date.now() - start}ms sürdü.)`);
90+
})
91+
92+
5993
interactionFiles = await getInteractionFilePaths();
6094
await chillout.forEach(interactionFiles, (interactionFile) => {
6195
let start = Date.now();
@@ -248,7 +282,10 @@ async function unload() {
248282
el.base.off(el.name, el.listener);
249283
})
250284

251-
let pathsToUnload = [...interactionFiles, ...eventFiles];
285+
console.info(`[BILGI] Dil listesi temizleniyor..`);
286+
Underline.locales.clear();
287+
288+
let pathsToUnload = [...interactionFiles, ...eventFiles, ...localeFiles];
252289

253290
await chillout.forEach(pathsToUnload, async (pathToUnload) => {
254291
console.info(`[BILGI] Modül "${path.relative(__dirname, pathToUnload)}" önbellekten kaldırılıyor!`);
@@ -259,7 +296,7 @@ async function unload() {
259296

260297
unloadStart = 0;
261298
pathsToUnload = 0;
262-
299+
263300
}
264301

265302
async function reload() {
@@ -302,9 +339,15 @@ client.on("interactionCreate", async (interaction) => {
302339

303340
let other = {};
304341

305-
let shouldRun1 = await config.onInteractionBeforeChecks(uInter, interaction, other);
342+
{
343+
let locale_id = (interaction.user.locale || interaction.locale)?.split("-")[0];
344+
other.locale = (Underline.locales.get(locale_id) || Underline.locales.get(Underline.config.defaultLanguage)).data;
345+
}
306346

307-
if (!shouldRun1) return;
347+
{
348+
let shouldRun1 = await config.onInteractionBeforeChecks(uInter, interaction, other);
349+
if (!shouldRun1) return;
350+
}
308351

309352
if (uInter.disabled) {
310353
config.userErrors.disabled(interaction, uInter, other);
@@ -389,10 +432,18 @@ client.on("interactionCreate", async (interaction) => {
389432
}
390433

391434
(async () => {
392-
let shouldRun2 = await config.onInteraction(uInter, interaction, other);
393-
if (!shouldRun2) return;
435+
436+
{
437+
let shouldRun2 = await config.onInteraction(uInter, interaction, other);
438+
if (!shouldRun2) return;
439+
}
440+
394441
try {
442+
395443
await uInter.onInteraction(interaction, other);
444+
445+
await config.onAfterInteraction(uInter, interaction, other);
446+
396447
} catch (err) {
397448
console.error(`[HATA] "${uInter.actionType == "CHAT_INPUT" ? `/${uInter.name.join(" ")}` : `${uInter.name[0]}`}" adlı interaksiyon çalıştırılırken bir hata ile karşılaşıldı!`)
398449
if (err.message) console.error(`[HATA] ${err.message}`);

interactions/profil.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module.exports = new Underline.SlashCommand({
1515
thumbnail: {
1616
url: member.user.displayAvatarURL({ dynamic: true })
1717
},
18-
description: `**Açıldığı Tarih:** <t:${Math.floor(member.user.createdTimestamp / 1000)}:F>\n**Katıldığı Tarih:** <t:${Math.floor(member.joinedTimestamp / 1000)}:F>\n**ID:** \`${member.user.id}\``,
18+
description: `**Açıldığı Tarih:** <t:${Math.floor(member.user.createdTimestamp / 1000)}:F>\n**Katıldığı Tarih:** <t:${Math.floor(member.joinedTimestamp / 1000)}:F>\n**ID:** \`${member.user.id}\`**Dil:** ${member.user.locale}`,
1919
createdAt: Date.now(),
2020
footer: {
2121
icon_url: interaction.user.displayAvatarURL({ dynamic: true }),
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const { Util } = require("discord.js");
2+
const util = require("util");
3+
const stuffs = require("stuffs")
4+
module.exports = new Underline.SlashCommand({
5+
name: ["interactions", "guild", "clear"],
6+
description: "Bot yetkilileri için publish komutu.",
7+
async onInteraction(inter, other) {
8+
await inter.deferReply();
9+
10+
let guildID = inter.options.getString("guild");
11+
12+
let guild = inter.client.guilds.cache.get(guildID);
13+
14+
if (!guild) return inter.editReply("Malesef aradığınız sunucu bulunamadı...")
15+
16+
let logged = await stuffs.execAsync(`node publishInteractions guild ${guildID} clear`);
17+
if(logged.stdout.includes("İnteraksiyonlar paylaşıldı!")) {
18+
await inter.editReply(other.locale.example.success());
19+
} else {
20+
21+
inter.editReply(other.locale.example.error(guild.name))
22+
console.log("İnteraksyion paylaşma hatası")
23+
// console.log(logged.stdout);
24+
console.error(logged.stderr);
25+
26+
}
27+
28+
},
29+
coolDown: {
30+
type: "any",
31+
amount: 180000
32+
},
33+
perms: {
34+
user: ["DEVELOPER"]
35+
},
36+
options: [
37+
{
38+
name: "guild",
39+
type: "STRING",
40+
description: "Paylaşılacak sunucu sec",
41+
required: true,
42+
autocomplete: true,
43+
async onComplete(inter, value) {
44+
let guilds = await Underline.client.guilds.cache.map(g => ({name: g.name, value: g.id})).filter(x => !value || x.name.includes(value) || x.id === value);
45+
return guilds.slice(0, 24)
46+
}
47+
}
48+
],
49+
publishType: "guildOnly"
50+
})
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const { Util } = require("discord.js");
2+
const util = require("util");
3+
const stuffs = require("stuffs")
4+
module.exports = new Underline.SlashCommand({
5+
name: ["interactions", "guild", "publish"],
6+
description: "Bot yetkilileri için publish komutu.",
7+
async onInteraction(inter, other) {
8+
await inter.deferReply();
9+
10+
let guildID = inter.options.getString("guild");
11+
12+
let guild = inter.client.guilds.cache.get(guildID);
13+
14+
let type = inter.options.getString("publish_type") || "guildOnly"
15+
16+
if (!guild) return inter.editReply("Malesef aradığınız sunucu bulunamadı...")
17+
18+
let logged = await stuffs.execAsync(`node publishInteractions guild ${guildID} ${type}`);
19+
if(logged.stdout.includes("İnteraksiyonlar paylaşıldı!")) {
20+
await inter.editReply(other.locale.example.success());
21+
} else {
22+
23+
inter.editReply(other.locale.example.error(guild.name))
24+
console.log("İnteraksyion paylaşma hatası")
25+
// console.log(logged.stdout);
26+
console.error(logged.stderr);
27+
28+
}
29+
30+
},
31+
coolDown: {
32+
type: "any",
33+
amount: 180000
34+
},
35+
perms: {
36+
user: ["DEVELOPER"]
37+
},
38+
options: [
39+
{
40+
name: "guild",
41+
type: "STRING",
42+
description: "Paylaşılacak sunucu sec",
43+
required: true,
44+
autocomplete: true,
45+
async onComplete(inter, value) {
46+
let guilds = await Underline.client.guilds.cache.map(g => ({name: g.name, value: g.id})).filter(x => !value || x.name.includes(value) || x.id === value);
47+
console.log(guilds)
48+
return guilds.slice(0, 24)
49+
}
50+
},
51+
{
52+
name: "publish_type",
53+
type: "STRING",
54+
description: "Paylaşılma tipi",
55+
required: false,
56+
}
57+
],
58+
publishType: "guildOnly"
59+
})

locales/Turkish.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module.exports = new Underline.Locale({
2+
locale: "tr",
3+
data: {
4+
userErrors: {
5+
coolDown: {
6+
user: `Bu interaksiyonu sen tekrardan {0} saniye içerisinde kullanabilirsin.`,
7+
member: `Bu interaksiyonu sen bu sunucuda tekrardan {0} saniye içerisinde kullanabilirsin.`,
8+
guild: `Bu interaksiyonu bu sunucuda tekrardan {0} saniye içerisinde kullanabilirsin.`,
9+
channel: `Bu interaksiyonu bu kanalda tekrardan {0} saniye içerisinde kullanabilirsin.`,
10+
message: `Bu interaksiyonu bu mesajda tekrardan {0} saniye içerisinde kullanabilirsin.`,
11+
any: `Bu interaksiyonu tekrardan {0} saniye içerisinde kullanabilirsin.`,
12+
},
13+
disabled: "Bu interkasiyon kapalı",
14+
blocked: "Bottan yasaklısınız.",
15+
developerOnly: "Bu interaksiyon sadece bot geliştiricilerine özel",
16+
guildOwnerOnly: "Bu interaksiyon sadece sunucu sahipleri kullanabilir",
17+
botPermsRequired: "Botun bu komutu kullanması için {0} yetkilerine ihtiyacı vardır.",
18+
userPermsRequired: "Bu komutu kullanmak için {0} yetkilerine ihtiyacın var.",
19+
},
20+
example: {
21+
success: "✔ Yeniden yükleme işlemi başarılı.",
22+
error: "Malesef {0} sunucusunda paylaşılamadı..."
23+
}
24+
}
25+
});

0 commit comments

Comments
 (0)