You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

RestGuild.cs 41 kB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
9 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
Add support for channel categories (#907) commit a85c5814a74e473e95fe172f0379cbc7f9f951d8 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:25:48 2018 -0500 Code cleanup commit 4b243fd3dd99152b4ebc7ee01d704bd8e57eeee1 Author: Christopher F <computerizedtaco@gmail.com> Date: Sat Jan 6 22:08:28 2018 -0500 Add support for channel categories (#907) commit 41ed9106f2b05530acbf06b245c9aa618011d815 Author: mrspits4ever <spits.lucas@gmail.com> Date: Thu Dec 14 20:02:57 2017 +0100 removed mentioning support for RestCategoryChannel, added channels property to SocketCategoryChannel commit 71142c310847886dff80c49e9357dd0786d67a1b Merge: 4589d731 678a7238 Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:53 2017 +0100 Merge branch 'dev' of https://github.com/RogueException/Discord.Net into feature/channel-categories commit 4589d73187871c98485ed25c6d223706927af7ec Author: mrspits4ever <spits.lucas@gmail.com> Date: Wed Dec 13 21:17:46 2017 +0100 adressed requested changes commit d59b038efa048b2279602e2015ddd2c185e58d63 Author: pegasy <pegasy@users.noreply.github.com> Date: Mon Sep 25 18:53:23 2017 +0200 Renamed classes / properties / methods to use CategoryChannel instead of ChannelCategory to be consistant with how text / voice channels are named. commit 5c4777dc8cc443108f2e7e4afae98824c9a32b1f Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 19:08:25 2017 +0200 removed Guild from class name for ChannelCategory Renamed all properties to use Category instead of Parent Throw exception on GetUsers / GetInvites etc for categories commit e18bd8c799d2327270021c05866cb2e97ad4671b Author: pegasy <pegasy@users.noreply.github.com> Date: Sun Sep 24 15:49:51 2017 +0200 Add support for channel categories (as its own channel type)
8 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. using Discord.Audio;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Collections.Immutable;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using System.Threading.Tasks;
  8. using EmbedModel = Discord.API.GuildEmbed;
  9. using Model = Discord.API.Guild;
  10. namespace Discord.Rest
  11. {
  12. /// <summary>
  13. /// Represents a REST-based guild/server.
  14. /// </summary>
  15. [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
  16. public class RestGuild : RestEntity<ulong>, IGuild, IUpdateable
  17. {
  18. private ImmutableDictionary<ulong, RestRole> _roles;
  19. private ImmutableArray<GuildEmote> _emotes;
  20. private ImmutableArray<string> _features;
  21. /// <inheritdoc />
  22. public string Name { get; private set; }
  23. /// <inheritdoc />
  24. public int AFKTimeout { get; private set; }
  25. /// <inheritdoc />
  26. public bool IsEmbeddable { get; private set; }
  27. /// <inheritdoc />
  28. public VerificationLevel VerificationLevel { get; private set; }
  29. /// <inheritdoc />
  30. public MfaLevel MfaLevel { get; private set; }
  31. /// <inheritdoc />
  32. public DefaultMessageNotifications DefaultMessageNotifications { get; private set; }
  33. /// <inheritdoc />
  34. public ulong? AFKChannelId { get; private set; }
  35. /// <inheritdoc />
  36. public ulong? EmbedChannelId { get; private set; }
  37. /// <inheritdoc />
  38. public ulong? SystemChannelId { get; private set; }
  39. /// <inheritdoc />
  40. public ulong OwnerId { get; private set; }
  41. /// <inheritdoc />
  42. public string VoiceRegionId { get; private set; }
  43. /// <inheritdoc />
  44. public string IconId { get; private set; }
  45. /// <inheritdoc />
  46. public string SplashId { get; private set; }
  47. internal bool Available { get; private set; }
  48. /// <inheritdoc />
  49. public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
  50. [Obsolete("DefaultChannelId is deprecated, use GetDefaultChannelAsync")]
  51. public ulong DefaultChannelId => Id;
  52. /// <inheritdoc />
  53. public string IconUrl => CDN.GetGuildIconUrl(Id, IconId);
  54. /// <inheritdoc />
  55. public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId);
  56. /// <summary>
  57. /// Gets the built-in role containing all users in this guild.
  58. /// </summary>
  59. public RestRole EveryoneRole => GetRole(Id);
  60. /// <summary>
  61. /// Gets a collection of all roles in this guild.
  62. /// </summary>
  63. public IReadOnlyCollection<RestRole> Roles => _roles.ToReadOnlyCollection();
  64. /// <inheritdoc />
  65. public IReadOnlyCollection<GuildEmote> Emotes => _emotes;
  66. /// <inheritdoc />
  67. public IReadOnlyCollection<string> Features => _features;
  68. internal RestGuild(BaseDiscordClient client, ulong id)
  69. : base(client, id)
  70. {
  71. }
  72. internal static RestGuild Create(BaseDiscordClient discord, Model model)
  73. {
  74. var entity = new RestGuild(discord, model.Id);
  75. entity.Update(model);
  76. return entity;
  77. }
  78. internal void Update(Model model)
  79. {
  80. AFKChannelId = model.AFKChannelId;
  81. EmbedChannelId = model.EmbedChannelId;
  82. SystemChannelId = model.SystemChannelId;
  83. AFKTimeout = model.AFKTimeout;
  84. IsEmbeddable = model.EmbedEnabled;
  85. IconId = model.Icon;
  86. Name = model.Name;
  87. OwnerId = model.OwnerId;
  88. VoiceRegionId = model.Region;
  89. SplashId = model.Splash;
  90. VerificationLevel = model.VerificationLevel;
  91. MfaLevel = model.MfaLevel;
  92. DefaultMessageNotifications = model.DefaultMessageNotifications;
  93. if (model.Emojis != null)
  94. {
  95. var emotes = ImmutableArray.CreateBuilder<GuildEmote>(model.Emojis.Length);
  96. for (int i = 0; i < model.Emojis.Length; i++)
  97. emotes.Add(model.Emojis[i].ToEntity());
  98. _emotes = emotes.ToImmutableArray();
  99. }
  100. else
  101. _emotes = ImmutableArray.Create<GuildEmote>();
  102. if (model.Features != null)
  103. _features = model.Features.ToImmutableArray();
  104. else
  105. _features = ImmutableArray.Create<string>();
  106. var roles = ImmutableDictionary.CreateBuilder<ulong, RestRole>();
  107. if (model.Roles != null)
  108. {
  109. for (int i = 0; i < model.Roles.Length; i++)
  110. roles[model.Roles[i].Id] = RestRole.Create(Discord, this, model.Roles[i]);
  111. }
  112. _roles = roles.ToImmutable();
  113. Available = true;
  114. }
  115. internal void Update(EmbedModel model)
  116. {
  117. EmbedChannelId = model.ChannelId;
  118. IsEmbeddable = model.Enabled;
  119. }
  120. //General
  121. /// <inheritdoc />
  122. public async Task UpdateAsync(RequestOptions options = null)
  123. => Update(await Discord.ApiClient.GetGuildAsync(Id, options).ConfigureAwait(false));
  124. /// <inheritdoc />
  125. public Task DeleteAsync(RequestOptions options = null)
  126. => GuildHelper.DeleteAsync(this, Discord, options);
  127. /// <inheritdoc />
  128. /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
  129. public async Task ModifyAsync(Action<GuildProperties> func, RequestOptions options = null)
  130. {
  131. var model = await GuildHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false);
  132. Update(model);
  133. }
  134. /// <inheritdoc />
  135. /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
  136. public async Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null)
  137. {
  138. var model = await GuildHelper.ModifyEmbedAsync(this, Discord, func, options).ConfigureAwait(false);
  139. Update(model);
  140. }
  141. /// <inheritdoc />
  142. /// <exception cref="ArgumentNullException"><paramref name="args" /> is <c>null</c>.</exception>
  143. public async Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null)
  144. {
  145. var arr = args.ToArray();
  146. await GuildHelper.ReorderChannelsAsync(this, Discord, arr, options).ConfigureAwait(false);
  147. }
  148. /// <inheritdoc />
  149. public async Task ReorderRolesAsync(IEnumerable<ReorderRoleProperties> args, RequestOptions options = null)
  150. {
  151. var models = await GuildHelper.ReorderRolesAsync(this, Discord, args, options).ConfigureAwait(false);
  152. foreach (var model in models)
  153. {
  154. var role = GetRole(model.Id);
  155. role?.Update(model);
  156. }
  157. }
  158. /// <inheritdoc />
  159. public Task LeaveAsync(RequestOptions options = null)
  160. => GuildHelper.LeaveAsync(this, Discord, options);
  161. //Bans
  162. //Bans
  163. /// <summary>
  164. /// Gets a collection of all users banned in this guild.
  165. /// </summary>
  166. /// <param name="options">The options to be used when sending the request.</param>
  167. /// <returns>
  168. /// A task that represents the asynchronous get operation. The task result contains a read-only collection of
  169. /// ban objects that this guild currently possesses, with each object containing the user banned and reason
  170. /// behind the ban.
  171. /// </returns>
  172. public Task<IReadOnlyCollection<RestBan>> GetBansAsync(RequestOptions options = null)
  173. => GuildHelper.GetBansAsync(this, Discord, options);
  174. /// <summary>
  175. /// Gets a ban object for a banned user.
  176. /// </summary>
  177. /// <param name="user">The banned user.</param>
  178. /// <param name="options">The options to be used when sending the request.</param>
  179. /// <returns>
  180. /// A task that represents the asynchronous get operation. The task result contains a ban object, which
  181. /// contains the user information and the reason for the ban; <c>null</c> if the ban entry cannot be found.
  182. /// </returns>
  183. public Task<RestBan> GetBanAsync(IUser user, RequestOptions options = null)
  184. => GuildHelper.GetBanAsync(this, Discord, user.Id, options);
  185. /// <summary>
  186. /// Gets a ban object for a banned user.
  187. /// </summary>
  188. /// <param name="userId">The snowflake identifier for the banned user.</param>
  189. /// <param name="options">The options to be used when sending the request.</param>
  190. /// <returns>
  191. /// A task that represents the asynchronous get operation. The task result contains a ban object, which
  192. /// contains the user information and the reason for the ban; <c>null</c> if the ban entry cannot be found.
  193. /// </returns>
  194. public Task<RestBan> GetBanAsync(ulong userId, RequestOptions options = null)
  195. => GuildHelper.GetBanAsync(this, Discord, userId, options);
  196. /// <inheritdoc />
  197. public Task AddBanAsync(IUser user, int pruneDays = 0, string reason = null, RequestOptions options = null)
  198. => GuildHelper.AddBanAsync(this, Discord, user.Id, pruneDays, reason, options);
  199. /// <inheritdoc />
  200. public Task AddBanAsync(ulong userId, int pruneDays = 0, string reason = null, RequestOptions options = null)
  201. => GuildHelper.AddBanAsync(this, Discord, userId, pruneDays, reason, options);
  202. /// <inheritdoc />
  203. public Task RemoveBanAsync(IUser user, RequestOptions options = null)
  204. => GuildHelper.RemoveBanAsync(this, Discord, user.Id, options);
  205. /// <inheritdoc />
  206. public Task RemoveBanAsync(ulong userId, RequestOptions options = null)
  207. => GuildHelper.RemoveBanAsync(this, Discord, userId, options);
  208. //Channels
  209. /// <summary>
  210. /// Gets a collection of all channels in this guild.
  211. /// </summary>
  212. /// <param name="options">The options to be used when sending the request.</param>
  213. /// <returns>
  214. /// A task that represents the asynchronous get operation. The task result contains a read-only collection of
  215. /// generic channels found within this guild.
  216. /// </returns>
  217. public Task<IReadOnlyCollection<RestGuildChannel>> GetChannelsAsync(RequestOptions options = null)
  218. => GuildHelper.GetChannelsAsync(this, Discord, options);
  219. /// <summary>
  220. /// Gets a channel in this guild.
  221. /// </summary>
  222. /// <param name="id">The snowflake identifier for the channel.</param>
  223. /// <param name="options">The options to be used when sending the request.</param>
  224. /// <returns>
  225. /// A task that represents the asynchronous get operation. The task result contains the generic channel
  226. /// associated with the specified <paramref name="id"/>; <c>null</c> if none is found.
  227. /// </returns>
  228. public Task<RestGuildChannel> GetChannelAsync(ulong id, RequestOptions options = null)
  229. => GuildHelper.GetChannelAsync(this, Discord, id, options);
  230. /// <summary>
  231. /// Gets a text channel in this guild.
  232. /// </summary>
  233. /// <param name="id">The snowflake identifier for the text channel.</param>
  234. /// <param name="options">The options to be used when sending the request.</param>
  235. /// <returns>
  236. /// A task that represents the asynchronous get operation. The task result contains the text channel
  237. /// associated with the specified <paramref name="id"/>; <c>null</c> if none is found.
  238. /// </returns>
  239. public async Task<RestTextChannel> GetTextChannelAsync(ulong id, RequestOptions options = null)
  240. {
  241. var channel = await GuildHelper.GetChannelAsync(this, Discord, id, options).ConfigureAwait(false);
  242. return channel as RestTextChannel;
  243. }
  244. /// <summary>
  245. /// Gets a collection of all text channels in this guild.
  246. /// </summary>
  247. /// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param>
  248. /// <param name="options">The options to be used when sending the request.</param>
  249. /// <returns>
  250. /// A task that represents the asynchronous get operation. The task result contains a read-only collection of
  251. /// message channels found within this guild.
  252. /// </returns>
  253. public async Task<IReadOnlyCollection<RestTextChannel>> GetTextChannelsAsync(RequestOptions options = null)
  254. {
  255. var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
  256. return channels.OfType<RestTextChannel>().ToImmutableArray();
  257. }
  258. /// <summary>
  259. /// Gets a voice channel in this guild.
  260. /// </summary>
  261. /// <param name="id">The snowflake identifier for the voice channel.</param>
  262. /// <param name="options">The options to be used when sending the request.</param>
  263. /// <returns>
  264. /// A task that represents the asynchronous get operation. The task result contains the voice channel associated
  265. /// with the specified <paramref name="id"/>; <c>null</c> if none is found.
  266. /// </returns>
  267. public async Task<RestVoiceChannel> GetVoiceChannelAsync(ulong id, RequestOptions options = null)
  268. {
  269. var channel = await GuildHelper.GetChannelAsync(this, Discord, id, options).ConfigureAwait(false);
  270. return channel as RestVoiceChannel;
  271. }
  272. /// <summary>
  273. /// Gets a collection of all voice channels in this guild.
  274. /// </summary>
  275. /// <param name="options">The options to be used when sending the request.</param>
  276. /// <returns>
  277. /// A task that represents the asynchronous get operation. The task result contains a read-only collection of
  278. /// voice channels found within this guild.
  279. /// </returns>
  280. public async Task<IReadOnlyCollection<RestVoiceChannel>> GetVoiceChannelsAsync(RequestOptions options = null)
  281. {
  282. var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
  283. return channels.OfType<RestVoiceChannel>().ToImmutableArray();
  284. }
  285. /// <summary>
  286. /// Gets a collection of all category channels in this guild.
  287. /// </summary>
  288. /// <param name="options">The options to be used when sending the request.</param>
  289. /// <returns>
  290. /// A task that represents the asynchronous get operation. The task result contains a read-only collection of
  291. /// category channels found within this guild.
  292. /// </returns>
  293. public async Task<IReadOnlyCollection<RestCategoryChannel>> GetCategoryChannelsAsync(RequestOptions options = null)
  294. {
  295. var channels = await GuildHelper.GetChannelsAsync(this, Discord, options).ConfigureAwait(false);
  296. return channels.OfType<RestCategoryChannel>().ToImmutableArray();
  297. }
  298. /// <summary>
  299. /// Gets the AFK voice channel in this guild.
  300. /// </summary>
  301. /// <param name="options">The options to be used when sending the request.</param>
  302. /// <returns>
  303. /// A task that represents the asynchronous get operation. The task result contains the voice channel that the
  304. /// AFK users will be moved to after they have idled for too long; <c>null</c> if none is set.
  305. /// </returns>
  306. public async Task<RestVoiceChannel> GetAFKChannelAsync(RequestOptions options = null)
  307. {
  308. var afkId = AFKChannelId;
  309. if (afkId.HasValue)
  310. {
  311. var channel = await GuildHelper.GetChannelAsync(this, Discord, afkId.Value, options).ConfigureAwait(false);
  312. return channel as RestVoiceChannel;
  313. }
  314. return null;
  315. }
  316. /// <summary>
  317. /// Gets the first viewable text channel in this guild.
  318. /// </summary>
  319. /// <param name="options">The options to be used when sending the request.</param>
  320. /// <returns>
  321. /// A task that represents the asynchronous get operation. The task result contains the first viewable text
  322. /// channel in this guild; <c>null</c> if none is found.
  323. /// </returns>
  324. public async Task<RestTextChannel> GetDefaultChannelAsync(RequestOptions options = null)
  325. {
  326. var channels = await GetTextChannelsAsync(options).ConfigureAwait(false);
  327. var user = await GetCurrentUserAsync(options).ConfigureAwait(false);
  328. return channels
  329. .Where(c => user.GetPermissions(c).ViewChannel)
  330. .OrderBy(c => c.Position)
  331. .FirstOrDefault();
  332. }
  333. /// <summary>
  334. /// Gets the embed channel (i.e. the channel set in the guild's widget settings) in this guild.
  335. /// </summary>
  336. /// <param name="options">The options to be used when sending the request.</param>
  337. /// <returns>
  338. /// A task that represents the asynchronous get operation. The task result contains the embed channel set
  339. /// within the server's widget settings; <c>null</c> if none is set.
  340. /// </returns>
  341. public async Task<RestGuildChannel> GetEmbedChannelAsync(RequestOptions options = null)
  342. {
  343. var embedId = EmbedChannelId;
  344. if (embedId.HasValue)
  345. return await GuildHelper.GetChannelAsync(this, Discord, embedId.Value, options).ConfigureAwait(false);
  346. return null;
  347. }
  348. /// <summary>
  349. /// Gets the first viewable text channel in this guild.
  350. /// </summary>
  351. /// <param name="options">The options to be used when sending the request.</param>
  352. /// <returns>
  353. /// A task that represents the asynchronous get operation. The task result contains the first viewable text
  354. /// channel in this guild; <c>null</c> if none is found.
  355. /// </returns>
  356. public async Task<RestTextChannel> GetSystemChannelAsync(RequestOptions options = null)
  357. {
  358. var systemId = SystemChannelId;
  359. if (systemId.HasValue)
  360. {
  361. var channel = await GuildHelper.GetChannelAsync(this, Discord, systemId.Value, options).ConfigureAwait(false);
  362. return channel as RestTextChannel;
  363. }
  364. return null;
  365. }
  366. /// <summary>
  367. /// Creates a new text channel in this guild.
  368. /// </summary>
  369. /// <example>
  370. /// The following example creates a new text channel under an existing category named <c>Wumpus</c> with a set topic.
  371. /// <code lang="cs">
  372. /// var categories = await guild.GetCategoriesAsync();
  373. /// var targetCategory = categories.FirstOrDefault(x => x.Name == "wumpus");
  374. /// if (targetCategory == null) return;
  375. /// await Context.Guild.CreateTextChannelAsync(name, x =>
  376. /// {
  377. /// x.CategoryId = targetCategory.Id;
  378. /// x.Topic = $"This channel was created at {DateTimeOffset.UtcNow} by {user}.";
  379. /// });
  380. /// </code>
  381. /// </example>
  382. /// <param name="name">The new name for the text channel.</param>
  383. /// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
  384. /// <param name="options">The options to be used when sending the request.</param>
  385. /// <returns>
  386. /// A task that represents the asynchronous creation operation. The task result contains the newly created
  387. /// text channel.
  388. /// </returns>
  389. public Task<RestTextChannel> CreateTextChannelAsync(string name, Action<TextChannelProperties> func = null, RequestOptions options = null)
  390. => GuildHelper.CreateTextChannelAsync(this, Discord, name, options, func);
  391. /// <summary>
  392. /// Creates a voice channel with the provided name.
  393. /// </summary>
  394. /// <param name="name">The name of the new channel.</param>
  395. /// <param name="func">The delegate containing the properties to be applied to the channel upon its creation.</param>
  396. /// <param name="options">The options to be used when sending the request.</param>
  397. /// <exception cref="ArgumentNullException"><paramref name="name" /> is <c>null</c>.</exception>
  398. /// <returns>
  399. /// The created voice channel.
  400. /// </returns>
  401. public Task<RestVoiceChannel> CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func = null, RequestOptions options = null)
  402. => GuildHelper.CreateVoiceChannelAsync(this, Discord, name, options, func);
  403. /// <summary>
  404. /// Creates a category channel with the provided name.
  405. /// </summary>
  406. /// <param name="name">The name of the new channel.</param>
  407. /// <param name="options">The options to be used when sending the request.</param>
  408. /// <exception cref="ArgumentNullException"><paramref name="name" /> is <c>null</c>.</exception>
  409. /// <returns>
  410. /// The created category channel.
  411. /// </returns>
  412. public Task<RestCategoryChannel> CreateCategoryChannelAsync(string name, RequestOptions options = null)
  413. => GuildHelper.CreateCategoryChannelAsync(this, Discord, name, options);
  414. //Integrations
  415. public Task<IReadOnlyCollection<RestGuildIntegration>> GetIntegrationsAsync(RequestOptions options = null)
  416. => GuildHelper.GetIntegrationsAsync(this, Discord, options);
  417. public Task<RestGuildIntegration> CreateIntegrationAsync(ulong id, string type, RequestOptions options = null)
  418. => GuildHelper.CreateIntegrationAsync(this, Discord, id, type, options);
  419. //Invites
  420. /// <summary>
  421. /// Gets a collection of all invites in this guild.
  422. /// </summary>
  423. /// <param name="options">The options to be used when sending the request.</param>
  424. /// <returns>
  425. /// A task that represents the asynchronous get operation. The task result contains a read-only collection of
  426. /// invite metadata, each representing information for an invite found within this guild.
  427. /// </returns>
  428. public Task<IReadOnlyCollection<RestInviteMetadata>> GetInvitesAsync(RequestOptions options = null)
  429. => GuildHelper.GetInvitesAsync(this, Discord, options);
  430. /// <summary>
  431. /// Gets the vanity invite URL of this guild.
  432. /// </summary>
  433. /// <param name="options">The options to be used when sending the request.</param>
  434. /// <returns>
  435. /// A partial metadata of the vanity invite found within this guild.
  436. /// </returns>
  437. public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null)
  438. => GuildHelper.GetVanityInviteAsync(this, Discord, options);
  439. //Roles
  440. /// <summary>
  441. /// Gets a role in this guild.
  442. /// </summary>
  443. /// <param name="id">The snowflake identifier for the role.</param>
  444. /// <returns>
  445. /// A role that is associated with the specified <paramref name="id"/>; <c>null</c> if none is found.
  446. /// </returns>
  447. public RestRole GetRole(ulong id)
  448. {
  449. if (_roles.TryGetValue(id, out RestRole value))
  450. return value;
  451. return null;
  452. }
  453. /// <summary>
  454. /// Creates a new role with the provided name.
  455. /// </summary>
  456. /// <param name="name">The new name for the role.</param>
  457. /// <param name="permissions">The guild permission that the role should possess.</param>
  458. /// <param name="color">The color of the role.</param>
  459. /// <param name="isHoisted">Whether the role is separated from others on the sidebar.</param>
  460. /// <param name="options">The options to be used when sending the request.</param>
  461. /// <returns>
  462. /// A task that represents the asynchronous creation operation. The task result contains the newly created
  463. /// role.
  464. /// </returns>
  465. public async Task<RestRole> CreateRoleAsync(string name, GuildPermissions? permissions = default(GuildPermissions?), Color? color = default(Color?),
  466. bool isHoisted = false, RequestOptions options = null)
  467. {
  468. var role = await GuildHelper.CreateRoleAsync(this, Discord, name, permissions, color, isHoisted, options).ConfigureAwait(false);
  469. _roles = _roles.Add(role.Id, role);
  470. return role;
  471. }
  472. //Users
  473. /// <summary>
  474. /// Gets a collection of all users in this guild.
  475. /// </summary>
  476. /// <remarks>
  477. /// This method retrieves all users found within this guild.
  478. /// </remarks>
  479. /// <param name="options">The options to be used when sending the request.</param>
  480. /// <returns>
  481. /// A task that represents the asynchronous get operation. The task result contains a collection of guild
  482. /// users found within this guild.
  483. /// </returns>
  484. public IAsyncEnumerable<IReadOnlyCollection<RestGuildUser>> GetUsersAsync(RequestOptions options = null)
  485. => GuildHelper.GetUsersAsync(this, Discord, null, null, options);
  486. /// <summary>
  487. /// Gets a user from this guild.
  488. /// </summary>
  489. /// <remarks>
  490. /// This method retrieves a user found within this guild.
  491. /// </remarks>
  492. /// <param name="id">The snowflake identifier of the user.</param>
  493. /// <param name="options">The options to be used when sending the request.</param>
  494. /// <returns>
  495. /// A task that represents the asynchronous get operation. The task result contains the guild user
  496. /// associated with the specified <paramref name="id"/>; <c>null</c> if none is found.
  497. /// </returns>
  498. public Task<RestGuildUser> GetUserAsync(ulong id, RequestOptions options = null)
  499. => GuildHelper.GetUserAsync(this, Discord, id, options);
  500. /// <summary>
  501. /// Gets the current user for this guild.
  502. /// </summary>
  503. /// <param name="options">The options to be used when sending the request.</param>
  504. /// <returns>
  505. /// A task that represents the asynchronous get operation. The task result contains the currently logged-in
  506. /// user within this guild.
  507. /// </returns>
  508. public Task<RestGuildUser> GetCurrentUserAsync(RequestOptions options = null)
  509. => GuildHelper.GetUserAsync(this, Discord, Discord.CurrentUser.Id, options);
  510. /// <summary>
  511. /// Gets the owner of this guild.
  512. /// </summary>
  513. /// <param name="options">The options to be used when sending the request.</param>
  514. /// <returns>
  515. /// A task that represents the asynchronous get operation. The task result contains the owner of this guild.
  516. /// </returns>
  517. public Task<RestGuildUser> GetOwnerAsync(RequestOptions options = null)
  518. => GuildHelper.GetUserAsync(this, Discord, OwnerId, options);
  519. /// <inheritdoc />
  520. /// <summary>
  521. /// Prunes inactive users.
  522. /// </summary>
  523. /// <remarks>
  524. /// <para>
  525. /// This method removes all users that have not logged on in the provided number of <paramref name="days"/>.
  526. /// </para>
  527. /// <para>
  528. /// If <paramref name="simulate" /> is <c>true</c>, this method will only return the number of users that
  529. /// would be removed without kicking the users.
  530. /// </para>
  531. /// </remarks>
  532. /// <param name="days">The number of days required for the users to be kicked.</param>
  533. /// <param name="simulate">Whether this prune action is a simulation.</param>
  534. /// <param name="options">The options to be used when sending the request.</param>
  535. /// <returns>
  536. /// A task that represents the asynchronous prune operation. The task result contains the number of users to
  537. /// be or has been removed from this guild.
  538. /// </returns>
  539. public Task<int> PruneUsersAsync(int days = 30, bool simulate = false, RequestOptions options = null)
  540. => GuildHelper.PruneUsersAsync(this, Discord, days, simulate, options);
  541. //Audit logs
  542. /// <summary>
  543. /// Gets the specified number of audit log entries for this guild.
  544. /// </summary>
  545. /// <param name="limit">The number of audit log entries to fetch.</param>
  546. /// <param name="options">The options to be used when sending the request.</param>
  547. /// <returns>
  548. /// A task that represents the asynchronous get operation. The task result contains a read-only collection
  549. /// of the requested audit log entries.
  550. /// </returns>
  551. public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null)
  552. => GuildHelper.GetAuditLogsAsync(this, Discord, null, limit, options);
  553. //Webhooks
  554. /// <summary>
  555. /// Gets a webhook found within this guild.
  556. /// </summary>
  557. /// <param name="id">The identifier for the webhook.</param>
  558. /// <param name="options">The options to be used when sending the request.</param>
  559. /// <returns>
  560. /// A task that represents the asynchronous get operation. The task result contains the webhook with the
  561. /// specified <paramref name="id"/>; <c>null</c> if none is found.
  562. /// </returns>
  563. public Task<RestWebhook> GetWebhookAsync(ulong id, RequestOptions options = null)
  564. => GuildHelper.GetWebhookAsync(this, Discord, id, options);
  565. /// <summary>
  566. /// Gets a collection of all webhook from this guild.
  567. /// </summary>
  568. /// <param name="options">The options to be used when sending the request.</param>
  569. /// <returns>
  570. /// A task that represents the asynchronous get operation. The task result contains a read-only collection
  571. /// of webhooks found within the guild.
  572. /// </returns>
  573. public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
  574. => GuildHelper.GetWebhooksAsync(this, Discord, options);
  575. /// <summary>
  576. /// Returns the name of the guild.
  577. /// </summary>
  578. /// <returns>
  579. /// The name of the guild.
  580. /// </returns>
  581. public override string ToString() => Name;
  582. private string DebuggerDisplay => $"{Name} ({Id})";
  583. //Emotes
  584. /// <inheritdoc />
  585. public Task<GuildEmote> GetEmoteAsync(ulong id, RequestOptions options = null)
  586. => GuildHelper.GetEmoteAsync(this, Discord, id, options);
  587. /// <inheritdoc />
  588. public Task<GuildEmote> CreateEmoteAsync(string name, Image image, Optional<IEnumerable<IRole>> roles = default(Optional<IEnumerable<IRole>>), RequestOptions options = null)
  589. => GuildHelper.CreateEmoteAsync(this, Discord, name, image, roles, options);
  590. /// <inheritdoc />
  591. /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
  592. public Task<GuildEmote> ModifyEmoteAsync(GuildEmote emote, Action<EmoteProperties> func, RequestOptions options = null)
  593. => GuildHelper.ModifyEmoteAsync(this, Discord, emote.Id, func, options);
  594. /// <inheritdoc />
  595. public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null)
  596. => GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options);
  597. //IGuild
  598. /// <inheritdoc />
  599. bool IGuild.Available => Available;
  600. /// <inheritdoc />
  601. IAudioClient IGuild.AudioClient => null;
  602. /// <inheritdoc />
  603. IRole IGuild.EveryoneRole => EveryoneRole;
  604. /// <inheritdoc />
  605. IReadOnlyCollection<IRole> IGuild.Roles => Roles;
  606. /// <inheritdoc />
  607. async Task<IReadOnlyCollection<IBan>> IGuild.GetBansAsync(RequestOptions options)
  608. => await GetBansAsync(options).ConfigureAwait(false);
  609. /// <inheritdoc/>
  610. async Task<IBan> IGuild.GetBanAsync(IUser user, RequestOptions options)
  611. => await GetBanAsync(user, options).ConfigureAwait(false);
  612. /// <inheritdoc/>
  613. async Task<IBan> IGuild.GetBanAsync(ulong userId, RequestOptions options)
  614. => await GetBanAsync(userId, options).ConfigureAwait(false);
  615. /// <inheritdoc />
  616. async Task<IReadOnlyCollection<IGuildChannel>> IGuild.GetChannelsAsync(CacheMode mode, RequestOptions options)
  617. {
  618. if (mode == CacheMode.AllowDownload)
  619. return await GetChannelsAsync(options).ConfigureAwait(false);
  620. else
  621. return ImmutableArray.Create<IGuildChannel>();
  622. }
  623. /// <inheritdoc />
  624. async Task<IGuildChannel> IGuild.GetChannelAsync(ulong id, CacheMode mode, RequestOptions options)
  625. {
  626. if (mode == CacheMode.AllowDownload)
  627. return await GetChannelAsync(id, options).ConfigureAwait(false);
  628. else
  629. return null;
  630. }
  631. /// <inheritdoc />
  632. async Task<IReadOnlyCollection<ITextChannel>> IGuild.GetTextChannelsAsync(CacheMode mode, RequestOptions options)
  633. {
  634. if (mode == CacheMode.AllowDownload)
  635. return await GetTextChannelsAsync(options).ConfigureAwait(false);
  636. else
  637. return ImmutableArray.Create<ITextChannel>();
  638. }
  639. /// <inheritdoc />
  640. async Task<ITextChannel> IGuild.GetTextChannelAsync(ulong id, CacheMode mode, RequestOptions options)
  641. {
  642. if (mode == CacheMode.AllowDownload)
  643. return await GetTextChannelAsync(id, options).ConfigureAwait(false);
  644. else
  645. return null;
  646. }
  647. /// <inheritdoc />
  648. async Task<IReadOnlyCollection<IVoiceChannel>> IGuild.GetVoiceChannelsAsync(CacheMode mode, RequestOptions options)
  649. {
  650. if (mode == CacheMode.AllowDownload)
  651. return await GetVoiceChannelsAsync(options).ConfigureAwait(false);
  652. else
  653. return ImmutableArray.Create<IVoiceChannel>();
  654. }
  655. /// <inheritdoc />
  656. async Task<IReadOnlyCollection<ICategoryChannel>> IGuild.GetCategoriesAsync(CacheMode mode, RequestOptions options)
  657. {
  658. if (mode == CacheMode.AllowDownload)
  659. return await GetCategoryChannelsAsync(options).ConfigureAwait(false);
  660. else
  661. return null;
  662. }
  663. /// <inheritdoc />
  664. async Task<IVoiceChannel> IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions options)
  665. {
  666. if (mode == CacheMode.AllowDownload)
  667. return await GetVoiceChannelAsync(id, options).ConfigureAwait(false);
  668. else
  669. return null;
  670. }
  671. /// <inheritdoc />
  672. async Task<IVoiceChannel> IGuild.GetAFKChannelAsync(CacheMode mode, RequestOptions options)
  673. {
  674. if (mode == CacheMode.AllowDownload)
  675. return await GetAFKChannelAsync(options).ConfigureAwait(false);
  676. else
  677. return null;
  678. }
  679. /// <inheritdoc />
  680. async Task<ITextChannel> IGuild.GetDefaultChannelAsync(CacheMode mode, RequestOptions options)
  681. {
  682. if (mode == CacheMode.AllowDownload)
  683. return await GetDefaultChannelAsync(options).ConfigureAwait(false);
  684. else
  685. return null;
  686. }
  687. /// <inheritdoc />
  688. async Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options)
  689. {
  690. if (mode == CacheMode.AllowDownload)
  691. return await GetEmbedChannelAsync(options).ConfigureAwait(false);
  692. else
  693. return null;
  694. }
  695. /// <inheritdoc />
  696. async Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options)
  697. {
  698. if (mode == CacheMode.AllowDownload)
  699. return await GetSystemChannelAsync(options).ConfigureAwait(false);
  700. else
  701. return null;
  702. }
  703. /// <inheritdoc />
  704. async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options)
  705. => await CreateTextChannelAsync(name, func, options).ConfigureAwait(false);
  706. /// <inheritdoc />
  707. async Task<IVoiceChannel> IGuild.CreateVoiceChannelAsync(string name, Action<VoiceChannelProperties> func, RequestOptions options)
  708. => await CreateVoiceChannelAsync(name, func, options).ConfigureAwait(false);
  709. /// <inheritdoc />
  710. async Task<ICategoryChannel> IGuild.CreateCategoryAsync(string name, RequestOptions options)
  711. => await CreateCategoryChannelAsync(name, options).ConfigureAwait(false);
  712. /// <inheritdoc />
  713. async Task<IReadOnlyCollection<IGuildIntegration>> IGuild.GetIntegrationsAsync(RequestOptions options)
  714. => await GetIntegrationsAsync(options).ConfigureAwait(false);
  715. /// <inheritdoc />
  716. async Task<IGuildIntegration> IGuild.CreateIntegrationAsync(ulong id, string type, RequestOptions options)
  717. => await CreateIntegrationAsync(id, type, options).ConfigureAwait(false);
  718. /// <inheritdoc />
  719. async Task<IReadOnlyCollection<IInviteMetadata>> IGuild.GetInvitesAsync(RequestOptions options)
  720. => await GetInvitesAsync(options).ConfigureAwait(false);
  721. /// <inheritdoc />
  722. async Task<IInviteMetadata> IGuild.GetVanityInviteAsync(RequestOptions options)
  723. => await GetVanityInviteAsync(options).ConfigureAwait(false);
  724. /// <inheritdoc />
  725. IRole IGuild.GetRole(ulong id)
  726. => GetRole(id);
  727. /// <inheritdoc />
  728. async Task<IRole> IGuild.CreateRoleAsync(string name, GuildPermissions? permissions, Color? color, bool isHoisted, RequestOptions options)
  729. => await CreateRoleAsync(name, permissions, color, isHoisted, options).ConfigureAwait(false);
  730. /// <inheritdoc />
  731. async Task<IGuildUser> IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
  732. {
  733. if (mode == CacheMode.AllowDownload)
  734. return await GetUserAsync(id, options).ConfigureAwait(false);
  735. else
  736. return null;
  737. }
  738. /// <inheritdoc />
  739. async Task<IGuildUser> IGuild.GetCurrentUserAsync(CacheMode mode, RequestOptions options)
  740. {
  741. if (mode == CacheMode.AllowDownload)
  742. return await GetCurrentUserAsync(options).ConfigureAwait(false);
  743. else
  744. return null;
  745. }
  746. /// <inheritdoc />
  747. async Task<IGuildUser> IGuild.GetOwnerAsync(CacheMode mode, RequestOptions options)
  748. {
  749. if (mode == CacheMode.AllowDownload)
  750. return await GetOwnerAsync(options).ConfigureAwait(false);
  751. else
  752. return null;
  753. }
  754. /// <inheritdoc />
  755. async Task<IReadOnlyCollection<IGuildUser>> IGuild.GetUsersAsync(CacheMode mode, RequestOptions options)
  756. {
  757. if (mode == CacheMode.AllowDownload)
  758. return (await GetUsersAsync(options).FlattenAsync().ConfigureAwait(false)).ToImmutableArray();
  759. else
  760. return ImmutableArray.Create<IGuildUser>();
  761. }
  762. /// <inheritdoc />
  763. /// <exception cref="NotSupportedException">Downloading users is not supported for a REST-based guild.</exception>
  764. Task IGuild.DownloadUsersAsync() =>
  765. throw new NotSupportedException();
  766. async Task<IReadOnlyCollection<IAuditLogEntry>> IGuild.GetAuditLogsAsync(int limit, CacheMode cacheMode, RequestOptions options)
  767. {
  768. if (cacheMode == CacheMode.AllowDownload)
  769. return (await GetAuditLogsAsync(limit, options).FlattenAsync().ConfigureAwait(false)).ToImmutableArray();
  770. else
  771. return ImmutableArray.Create<IAuditLogEntry>();
  772. }
  773. /// <inheritdoc />
  774. async Task<IWebhook> IGuild.GetWebhookAsync(ulong id, RequestOptions options)
  775. => await GetWebhookAsync(id, options).ConfigureAwait(false);
  776. /// <inheritdoc />
  777. async Task<IReadOnlyCollection<IWebhook>> IGuild.GetWebhooksAsync(RequestOptions options)
  778. => await GetWebhooksAsync(options).ConfigureAwait(false);
  779. }
  780. }