Skip to content

Commit 7bd94de

Browse files
authored
Merge pull request #96 from eunwoo1104/need-to-fix
Fixed #88
2 parents e3bf048 + bf309b7 commit 7bd94de

File tree

1 file changed

+91
-64
lines changed

1 file changed

+91
-64
lines changed

discord_slash/client.py

Lines changed: 91 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import copy
12
import logging
23
import typing
34
import discord
@@ -104,16 +105,16 @@ def get_cog_commands(self, cog: commands.Cog):
104105
self.commands[x.name] = x
105106
else:
106107
if x.base in self.commands:
107-
for i in self.commands[x.base].allowed_guild_ids:
108-
if i not in x.allowed_guild_ids:
109-
x.allowed_guild_ids.append(i)
108+
for i in x.allowed_guild_ids:
109+
if i not in self.commands[x.base].allowed_guild_ids:
110+
self.commands[x.base].allowed_guild_ids.append(i)
110111
self.commands[x.base].has_subcommands = True
111112
else:
112113
_cmd = {
113114
"func": None,
114115
"description": x.base_description,
115116
"auto_convert": {},
116-
"guild_ids": x.allowed_guild_ids,
117+
"guild_ids": x.allowed_guild_ids.copy(),
117118
"api_options": [],
118119
"has_subcommands": True
119120
}
@@ -188,65 +189,88 @@ async def to_dict(self):
188189
Commands are in the format specified by discord `here <https://discord.com/developers/docs/interactions/slash-commands#applicationcommand>`_
189190
"""
190191
await self._discord.wait_until_ready() # In case commands are still not registered to SlashCommand.
192+
all_guild_ids = []
193+
for x in self.commands:
194+
for i in self.commands[x].allowed_guild_ids:
195+
if i not in all_guild_ids:
196+
all_guild_ids.append(i)
191197
cmds = {
192198
"global": [],
193-
"guild": {}
199+
"guild": {x: [] for x in all_guild_ids}
194200
}
201+
wait = {} # Before merging to return dict, let's first put commands to temporary dict.
195202
for x in self.commands:
196203
selected = self.commands[x]
197-
if selected.has_subcommands and selected.func:
198-
# Registering both subcommand and command with same base name / name
199-
# will result in only subcommand being registered,
200-
# so we will warn this at registering subcommands.
201-
self.logger.warning(f"Detected command name with same subcommand base name! "
202-
f"This command will only have subcommand: {x}")
203-
204-
options = []
205-
if selected.has_subcommands:
206-
tgt = self.subcommands[x]
207-
for y in tgt:
208-
sub = tgt[y]
209-
if isinstance(sub, model.SubcommandObject):
210-
_dict = {
211-
"name": sub.name,
212-
"description": sub.description or "No Description.",
213-
"type": model.SlashCommandOptionType.SUB_COMMAND,
214-
"options": sub.options or []
215-
}
216-
options.append(_dict)
217-
else:
218-
base_dict = {
219-
"name": y,
220-
"description": "No Description.",
221-
"type": model.SlashCommandOptionType.SUB_COMMAND_GROUP,
222-
"options": []
223-
}
224-
for z in sub:
225-
sub_sub = sub[z]
226-
_dict = {
227-
"name": sub_sub.name,
228-
"description": sub_sub.description or "No Description.",
229-
"type": model.SlashCommandOptionType.SUB_COMMAND,
230-
"options": sub_sub.options or []
231-
}
232-
base_dict["options"].append(_dict)
233-
if sub_sub.subcommand_group_description:
234-
base_dict["description"] = sub_sub.subcommand_group_description
235-
options.append(base_dict)
236-
237204
command_dict = {
238205
"name": x,
239206
"description": selected.description or "No Description.",
240-
"options": selected.options if not options else options
207+
"options": selected.options or []
241208
}
242209
if selected.allowed_guild_ids:
243210
for y in selected.allowed_guild_ids:
244-
try:
245-
cmds["guild"][y].append(command_dict)
246-
except KeyError:
247-
cmds["guild"][y] = [command_dict]
211+
if y not in wait:
212+
wait[y] = {}
213+
wait[y][x] = copy.deepcopy(command_dict)
214+
else:
215+
if "global" not in wait:
216+
wait["global"] = {}
217+
wait["global"][x] = copy.deepcopy(command_dict)
218+
219+
# Separated normal command add and subcommand add not to
220+
# merge subcommands to one. More info at Issue #88
221+
# https://github.com/eunwoo1104/discord-py-slash-command/issues/88
222+
223+
for x in self.commands:
224+
if not self.commands[x].has_subcommands:
225+
continue
226+
tgt = self.subcommands[x]
227+
for y in tgt:
228+
sub = tgt[y]
229+
if isinstance(sub, model.SubcommandObject):
230+
_dict = {
231+
"name": sub.name,
232+
"description": sub.description or "No Description.",
233+
"type": model.SlashCommandOptionType.SUB_COMMAND,
234+
"options": sub.options or []
235+
}
236+
if sub.allowed_guild_ids:
237+
for z in sub.allowed_guild_ids:
238+
wait[z][x]["options"].append(_dict)
239+
else:
240+
wait["global"][x]["options"].append(_dict)
241+
else:
242+
queue = {}
243+
base_dict = {
244+
"name": y,
245+
"description": "No Description.",
246+
"type": model.SlashCommandOptionType.SUB_COMMAND_GROUP,
247+
"options": []
248+
}
249+
for z in sub:
250+
sub_sub = sub[z]
251+
_dict = {
252+
"name": sub_sub.name,
253+
"description": sub_sub.description or "No Description.",
254+
"type": model.SlashCommandOptionType.SUB_COMMAND,
255+
"options": sub_sub.options or []
256+
}
257+
if sub_sub.allowed_guild_ids:
258+
for i in sub_sub.allowed_guild_ids:
259+
if i not in queue:
260+
queue[i] = copy.deepcopy(base_dict)
261+
queue[i]["options"].append(_dict)
262+
else:
263+
if "global" not in queue:
264+
queue["global"] = copy.deepcopy(base_dict)
265+
queue["global"]["options"].append(_dict)
266+
for i in queue:
267+
wait[i][x]["options"].append(queue[i])
268+
269+
for x in wait:
270+
if x == "global":
271+
[cmds["global"].append(n) for n in wait["global"].values()]
248272
else:
249-
cmds["global"].append(command_dict)
273+
[cmds["guild"][x].append(n) for n in wait[x].values()]
250274

251275
return cmds
252276

@@ -326,8 +350,10 @@ def add_slash_command(self,
326350
"connector": connector or {},
327351
"has_subcommands": has_subcommands
328352
}
329-
self.commands[name] = model.CommandObject(name, _cmd)
353+
obj = model.CommandObject(name, _cmd)
354+
self.commands[name] = obj
330355
self.logger.debug(f"Added command `{name}`")
356+
return obj
331357

332358
def add_subcommand(self,
333359
cmd,
@@ -371,18 +397,17 @@ def add_subcommand(self,
371397
description = description or getdoc(cmd)
372398

373399
if base in self.commands:
374-
tgt = self.commands[base]
375-
for x in tgt.allowed_guild_ids:
376-
if x not in guild_ids:
377-
guild_ids.append(x)
400+
for x in guild_ids:
401+
if x not in self.commands[base].allowed_guild_ids:
402+
self.commands[base].allowed_guild_ids.append(x)
378403

379404
if options is None:
380405
options = manage_commands.generate_options(cmd, description)
381406

382407
_cmd = {
383408
"func": None,
384409
"description": base_description,
385-
"guild_ids": guild_ids,
410+
"guild_ids": guild_ids.copy(),
386411
"api_options": [],
387412
"connector": {},
388413
"has_subcommands": True
@@ -401,7 +426,6 @@ def add_subcommand(self,
401426
self.commands[base] = model.CommandObject(base, _cmd)
402427
else:
403428
self.commands[base].has_subcommands = True
404-
self.commands[base].allowed_guild_ids = guild_ids
405429
if self.commands[base].description:
406430
_cmd["description"] = self.commands[base].description
407431
if base not in self.subcommands:
@@ -411,12 +435,15 @@ def add_subcommand(self,
411435
self.subcommands[base][subcommand_group] = {}
412436
if name in self.subcommands[base][subcommand_group]:
413437
raise error.DuplicateCommand(f"{base} {subcommand_group} {name}")
414-
self.subcommands[base][subcommand_group][name] = model.SubcommandObject(_sub, base, name, subcommand_group)
438+
obj = model.SubcommandObject(_sub, base, name, subcommand_group)
439+
self.subcommands[base][subcommand_group][name] = obj
415440
else:
416441
if name in self.subcommands[base]:
417442
raise error.DuplicateCommand(f"{base} {name}")
418-
self.subcommands[base][name] = model.SubcommandObject(_sub, base, name)
443+
obj = model.SubcommandObject(_sub, base, name)
444+
self.subcommands[base][name] = obj
419445
self.logger.debug(f"Added subcommand `{base} {subcommand_group or ''} {name or cmd.__name__}`")
446+
return obj
420447

421448
def slash(self,
422449
*,
@@ -485,8 +512,8 @@ async def _pick(ctx, choice1, choice2): # Command with 1 or more args.
485512
guild_ids = [guild_id]
486513

487514
def wrapper(cmd):
488-
self.add_slash_command(cmd, name, description, guild_ids, options, connector)
489-
return cmd
515+
obj = self.add_slash_command(cmd, name, description, guild_ids, options, connector)
516+
return obj
490517

491518
return wrapper
492519

@@ -557,8 +584,8 @@ async def _group_kick_user(ctx, user):
557584
subcommand_group_description = subcommand_group_description or sub_group_desc
558585

559586
def wrapper(cmd):
560-
self.add_subcommand(cmd, base, subcommand_group, name, description, base_description, subcommand_group_description, guild_ids, options, connector)
561-
return cmd
587+
obj = self.add_subcommand(cmd, base, subcommand_group, name, description, base_description, subcommand_group_description, guild_ids, options, connector)
588+
return obj
562589

563590
return wrapper
564591

0 commit comments

Comments
 (0)