Releases: brainboxdotcc/DPP
v10.0.35 release
We are happy to announce the release of D++ 10.0.35, which is mainly a bugfix release. It will fix a crash that may sometimes happen after registering a slash command. There are also a couple of fixes for compilation on void linux, and ARM NEON support for voice receive is now fixed.
Release Changelog
🐞 Bug Fixes
- Missing ctime in
sslclient.h
breaks on void Linux (#1314) - Neon now compiles (#1313)
- Commands should no longer crash when no context is defined (#1312)
📚 Documentation
📜 Miscellaneous Changes
- Sync with version from conan-center. this here for reference only. do not install via this
conanfile.py
Thank you for using D++!
v10.0.34 release
We are proud to announce the release of D++ 10.0.34! This new release of D++ adds support for user apps, which is a new Discord feature which allows you to add a bot to a user's profile (rather than a guild) so that commands listed by the bot can be ran anywhere (including in DMs and group DMs).
We have also added some supporting infrastructure to allow us to add to Conan Centre, so you will hopefully see D++ on Conan very soon!
The changelog is listed below:
Release Changelog
✨ New Features
- Conan 2.x recipe (#1308)
- Add support for user apps (#1304)
- User app commands and test program
- Add
interaction_metadata
for messages - Add
authorizing_integration_owners
- Add support for
application_integration_types
- Add
interaction_context_type
support
🐞 Bug Fixes
- Fix weird comments
- Deprecate old fields
♻️ Refactoring
- Dont use strings and
uint64_t
in dave, use snowflake type (#1307) - Change to
register_command
📚 Documentation
- Add documentation page for creating user app commands! (#1305)
📜 Miscellaneous Changes
- Fix/dave segfault (#1306)
- User-installed commands (#1223)
- Change docker schedule to monthly, not daily
Thank you for using D++!
v10.0.33 release
We are proud to announce the release of D++ 10.0.33! Barely a week after our last release, we have many more features to bring to you, and some fixes relating to DAVE E2EE. When users join a DAVE voice channel, the encryption will now remain as end-to-end and not downgrade to standard. The on_voice_ready event will also now always fire after a timeout when DAVE is enabled, even if there are no other users in the VC to build an MLS group with.
We have also added the approximate_user_install_count
field to dpp::application
and added cluster functions to fetch a users voice state via API calls (regardless of gateway, or cache).
Please note that this release officially deprecates _sync
functions. They will still operate, but will emit a warning at compile time if used. Instead of sync functions, if you are still using them, you should consider migrating to coroutines instead. CircleCI is now also officially removed from our build process, as this had been in place before we had GitHub actions and is no longer relevant.
The changelog is listed below:
Release Changelog
✨ New Features
- Added endpoints to fetch a user's voice state (#1294)
- Added
approximate_user_install_count
field to application (#1293) - Added NOMINMAX to
CMakeLists.txt
(#1292) - Voice ready now fires even if there are no other users in the VC (#1289)
🐞 Bug Fixes
- Fix broken static builds (#1290)
- Fix broken vcpkg builds which were failing because they were trying to compile as static (#1287)
- DAVE! client join/part re-derive client ratchets and privacy code (#1264)
- Vcpkg is always built with voice (#1272)
♻️ Refactoring
- Cleanup namespaces and unneeded includes (#1295)
- Libdave camel massacre 🐪🔪 (#1285)
- Low level socket tidyups and removal of punning (#1282)
- Breaking: Deprecate sync calls (#1280)
📚 Documentation
- Add docblock comments to all libdave class variables (#1286)
- Update roadmap (#1279)
- Extend Coroutine Documentation (#1288)
💎 Style Changes
- Clang-format file, for discussion (#1277)
📜 Miscellaneous Changes
- Delete .circleci directory
Thank you for using D++!
v10.0.32 release
We are extremely happy to announce the release of D++ 10.0.32! This new release is (to our knowledge) the first released Discord library to feature Discord's new DAVE end-to-end encryption for voice channels.
Please note that DAVE is experimental at present, and can be enabled by passing true to a boolean parameter when connecting to a voice channel. Please report any bugs, and we strongly welcome PRs. Now is your time to get involved with D++ development!
We have also removed the dependency upon libsodium
for voice support. Instead, we use OpenSSL primitives for the same features, allowing us to remove a huge dependency from the library.
This new release officially bumps the audio protocol to version 8, so this is required if you wish to continue using voice with D++ past November, as Discord are enforcing Voice protocol version 8 from this date onwards.
We also have added support for named slashcommand handlers, so routing of commands to different functions based on the name of the command can be done automatically for you by the library. Check out documentation on register_command and unregister_command for more information!
The changelog is listed below:
Release Changelog
✨ New Features
🐞 Bug Fixes
- Crash in
threads_get_public_archived
(#1268)
♻ Refactoring
- Remove unused debug variable (#1266)
- Why you so salty? Entirely remove libsodium from D++ (#1265)
- Deprecation: officially deprecate commandhandler (#1263)
- Better registration with
try_emplace
📚 Documentation
📜 Miscellaneous Changes
- Implementing named commands handlers for the cluster (#1262)
- This cant be fatal while we are offering documents on deprecated stuff for SEO
- Officially deprecate commandhandler
- Fix
embeds.cpp
not required intent + add cout logger (#1250)
👷 Build/CI
- More secure llvm19 install process (#1246)
Thank you for using D++!
v10.0.31 release
We are happy to announce the release of D++ 10.0.31! This new version is a required upgrade if you use Discord Monetization, or voice/audio. Discord have changed the requirements for encryption of voice, so this new version adds support for XChaCha20 voice encryption via sodium, and also adds the new monetization API calls. These have been tested for quite some time in production bots and can be considered as stable and ready for general availability.
This fix also contains several new features such as support for application emojis, customisable HTTP timeout durations, and a new coroutines implementation which fixes some long standing UB and minor memory leaks if you were using coroutines. If your bot does use coroutines, this is a strongly recommended upgrade which will increase performance and stability for your bots.
The changelog is listed below:
Release Changelog
✨ New Features
- Change encryption to AEAD XChaCha20 Poly1305 (#1239)
- XChaCha20 voice encryption (#1242)
std::format
support fordpp::snowflake
(#1203)- Added support for application emojis (#1207)
- Timeout is now 20 seconds. Users can now change the timeout length (#1208)
- Added file size limit to avatars and banners (#1209)
- Coro: coro 2.0 (#1196)
- Banners can now be uploaded to bots (#1197)
- Add XBPS docs (#1192)
- Add
request_timeout
, a parameter as optional tocluster::request()
which allows user to sethttp_client::timeout
and add error message for request timeouts (#1186) - Added warnings for certain events that require an intent (#1169)
- New premium upsell button style (#1175)
- Add missing entitlement type enum values (#1171)
- Added consuming an entitlement (#1170)
- Add
result_type
member type todpp::task
(#1165)
🐞 Bug Fixes
- Added missing include to
awaitable.h
(#1243) - Improve compatiblity with socket (#1229)
- Fix requests fizzling if the response doesn't contain Content-Length (#1232)
- Fix
guild_member::get_avatar_url()
(#1230) (#1231) - Incorrect comment (#1228)
- Coro: fix awaitable/task move assignment, again
- Coro: fix
dpp::task
's move assignment - Coro: fix unused alias warning
- Coro: fix read-after-free in
dpp::async
- Coro: fix includes, improve NOMINMAX define
- Qol: shut up soundboard events (#1202)
- Fixed padding in tests
- Add and to
misc-enum.h
- Test: fix ban unit tests to be dependent upon each other (#1200)
- Removed max limit for avatars and banners
- Banner blob now correctly throws for banner blob size. coro and sync calls updated
- Unit tests are now built statically when
BUILD_SHARED_LIBS
is off (#1193) - Compilation on clang-19 (#1195)
- Add
packets_left
count (#1194) - Fix leak of
in_thread
, fix read-after-free, fix race condition UB after cluster shutdown (#1187) - Add error message for request timeouts and add
timed_out
member variable tohttps_client
to check for request timeouts
♻️ Refactoring
- Readability changes to sslclient and wsclient (#1210)
- Changed
DPP_BUFSIZE
to beuint16_t
instead ofuint32_t
- Removed un-needed includes, more indentation corrections
- Removed constexpr for
http_version
, moved send tostd::string_view
, removed spaces - Change
get_gateway_bot
to use coro when available - Remove Cmake special options to compile on clang-19
- Coro: coro tidy up, add
sync_wait
🚨 Testing
- Test
to_binary()
📚 Documentation
- Change init to create (#1220)
- Fix unnecessary include of fmt in mp3 example (#1218)
- Create Gentoo installation tutorial (#1211)
- Remove XBPS coroutine section (#1205)
- Added a page for editing messages from a button click (#1163)
- Altered minimum gcc version for Coro, fixed docs issues (#1173)
- Added a missing ref (#1179)
- Changed wording of token page (#1161)
set_allow_multiselect
is now correctly documented- Added an example on how to edit an embed (#1128)
💎 Style Changes
- Static and reinterpret casts
📜 Miscellaneous Changes
- Adding fix to arm-neon bug. (#1226)
- Adding Arm-Neon implementation. (#1225)
- Introduced
DPP_HAS_FORMAT
definition std::format
support fordpp::snowflake
- Add requires clause to
await_transform
to improve error messages when trying toco_await
something that can't be - Coro test case to detect leaks
- Coro: allow move-only types in
dpp::async
, de-duplicate void specializations where possible, document some more - Coro: add concept
awaitable_type
, movedpp::detail
::promise::promise
todpp::basic_promise
, document some more - Coro: remove long-deprecated
dpp::job
event handlers - Coro: add [[nodiscard]] to
dpp::task
,dpp::coroutine
- Coro: use
std::memory_order
- Updated libsodium version for rpm packages to latest (#1190)
- Use
string_view
for message object ctors + setters (#1178) - Big number implementation, for future use in permissions bitfields (#1176)
- Mark interaction type 10 as depreciated
- Add Missing SKU types
- Update Docker image to Ubuntu 24.04 LTS (#1168)
- QoL fix: Enhance the entitlement stuff with data from the actual api docs now there are some (#1166)
- Poll conflicting with
dpp::poll
(#1152) - Updated autocomplete tutorial (#1151)
👷 Build/CI
- Add clang-19-libc++ as manual install (#1245)
- Fix mac xcode version (#1244)
- Added clang16-18 jobs for Linux, added clang16 for OSX (#1206)
- Fixed clang16 for OSX
- Added clang16-18 runners for Linux, added clang16 for OSX
- Added a clang++15 osx job, fixed clang++14 job. (#1204)
- Adds support for g++13 and g++14 CI on Ubuntu 24.04 (#1201)
- Allow runners to use mold, increased concurrency to 4 (#1198)
- Codeql now uses -j4
- Updated cmake commands for Linux to be more modern
- Arm7hf no longer uses mold
- Allow runners to use mold, increased concurrency to 3
Thank you for using D++!
v10.0.30 release
After several months of development, we are happy to announce the release of D++ 10.0.30, with support for polls, voice channel statuses, improved error logging, better UTF-8 functionality, and the ability to supress embeds on other users messages.
We recommend you update to this version for the fixes here, and for the new features to keep current with Discord's feature set.
The changelog is listed below:
Release Changelog
✨ New Features
- Poll support (#1136)
- Added
is_guild_owner
fordpp::guild_member
(#1109) - Add embed-only message ctor (#1100)
- Added
change_voice_channel
to discordclient (#1083) - Alter
set_allowed_mentions
(#1081) - Added expire and issued timestamps in attachment (#1065)
- Added
newly_created
bool to threads (#1069) - Added
dpp::cluster
::guild_member_timeout_remove
and its sync/coro versions (#1067) - Added the ability to set voice channel statuses (#1064)
🐞 Bug Fixes
- Error in logging with malformed json that doesnt fit the structure for an error (#1126)
- Signal Handlers on Non-Windows Platforms in sslclient (#1123)
- Fix uncleared track meta on stop audio (#1127)
- Fix
human_readable
for good (#1135) - Empty presences will now warn (#1121)
- Fix memory leak on libstdc++ (#1112)
- Out-of-bounds read of MIME types (#1104)
- Get size of object instead of pointer
- Correct wrong linking order to fix static build (#1102)
- Add version parameter as optional parameter to
co_request
, has been part of request for some time - Add version parameter to
co_request
ts_not_null
now works for all timezones (#1089)- Fixed getting archived threads
- Fix bug in human readable errors (#1077)
- Default callback parameters (#1079)
- It's going to be OK (#1078)
- Send stickers in message if present
- Cmyk calculations - blue value calculations (#1053)
- Remove unnecessary
SSL_free
(#1050) - Properly free ssl session and ssl context (#1049)
- Avoid memory leaks in
event_map
(#1043) - Use of uninitialized value in
command_option
copy ctor (#1044)
♻️ Refactoring
- Fix and improve utf8 utilities (#1046)
📚 Documentation
- Added a timers page, added a note in
setting_status
for timers (#1120) - Rewrote the CLion VCPKG page to use VS toolchain (#1111)
- Fixed missing/incorrect params for many functions (#1110)
- Added a thinking page (#1092)
- Update Xcode page. (#1061)
- Improve Windows VS tutorials (#1058)
- Added the homebrew version to readme (#1041)
📜 Miscellaneous Changes
- Silence
GUILD_SOUNDBOARD_
* websocket events, currently undocumented (#1148) - QOL: non fatal utf8 handling. (#1147)
- Capturing "bot" is not needed. Removing it resolves an unused variabl… (#1132)
- Ability to suppress embeds (#1107)
- Dont attempt to reschedule timers that are deleted (FIXES: #1048) (#1088)
- Potential uninitialised value returned if empty string passed to
from_string<T>()
(#1087) - Unit-test and non unit-test jobs are now merged into one (#1051)
👷 Build/CI
Thank you for using D++!
v10.0.29 release
We are pleased to announce the release of D++ v10.0.29! This release contains many fixes, and also introduces coroutines to the windows bot template, so you can use templates out of the box on windows bots. We also now have full support on Brew on MacOS plus a MacOS bot template ready to use in XCode.
The changelog is listed below:
Release Changelog
✨ New Features
- Made
iteration_interval
changeable. (#1040) - Added guilds array and count to
ready_t
(#1038) - Coroutines on the Windows Bot Template
- A new OSX Template
- Official clang-cl support
- Add clang-cl CMake presets
- Add error codes to exceptions (#1036)
🐞 Bug Fixes
- Remove msvc-only
/await:strict
from clang-cl flags - Remove
DPP_EXPORT
onjson_interface.h
- Corrected some comments
- Added fixes for clang-cl
- Changed default audio type for Windows (#1004)
- Fixed unittest for mac, ctest now works (#1001)
- Voiceregion now fills correctly, removed VIP from regions. (#997)
♻️ Refactoring
- Split
dpp::thread
fromchannel.h
intothread.h
- Changed the way messages holds files (#999)
📚 Documentation
- Made the
setting_status
page use the latestready_t
feature (#1039) - Added emoji page (#1019)
- Added an xcode page for osx (#1030)
- Fixed colour scheme after recent doxygen changes (#1023)
- Added install page for brew (#1006)
- Improved some sections for docs-style-standards (#1018)
- Added a docs convention (#1014)
- Corrected some issues in
clearing_slashcommands.cpp
(#1012) - Corrected punctuation and refs (#1002)
- Altered the OSX page (#1000)
💎 Style Changes
👷 Build/CI
- CI should no longer build from docpages changes (#1037)
- Mac changes, self-hosted runner now available (#1010)
- Unit tests now use ctest, macos now unit tests (#1003)
Thank you for using D++!
v10.0.28 release
We are happy to announce the release of D++ 10.0.28! This release fixes a few long standing issues, the main one being the way the library handles a mismatch between release and debug builds on windows with the project that links to D++. Instead of an exception which points to some obscure code called _Scary->_MyHead
you will get a dialog box popup instead before the library throws. This makes troubleshooting while developing a lot more straightforward.
Autocompletes where the options are numeric will also no longer throw an exception in on_autocomplete
.
The changelog is listed below:
Release Changelog
🐞 Bug Fixes
- Integer autocompletes no longer cause crash (#992)
- Add
maybe_unused
tobuild_type
constexpr to squash warning (#993) - Exorcised the scary head. halloween is over (#980)
♻️ Refactoring
- Renamed
inner_emoji
tocomponent_emoji
, changedselect_menu
and component to use it. (#974)
📚 Documentation
💎 Style Changes
- Refactored comments part 3 (#979)
- Refactored comments part 2 (#977)
- Refactored comments in several files to follow standard (#975)
📜 Miscellaneous Changes
- VCPKG info update [skip ci]
👷 Build/CI
- Move ARM64 to self hosted runner (#994)
- Updated nlohmann to 3.11.2 (#991)
- Add self hosted arm runner (#983)
- Vcpkg fix
Thank you for using D++!
v10.0.27 release
We are pleased to announce the Spooky release of D++ 10.0.27 👻 just before Halloween! This release is filled with non-ghostly enhancements and ghoulish fixes, notably, the way we store guild members has changed slightly, so you might find that where you were directly accessing values such as the roles
vector, instead you need to use get_roles()
. This is so we can correctly track which parts of the structure you changed if you send it to Discord in an API request.
We have also changed the way we hold icon data, to allow for uploading of guild banners etc.
Support for Discord's Premium App Subscriptions feature is now added. For more details please see the New Features section of this release announcement.
The changelog is listed below:
Release Changelog
💣 Breaking Changes
guild_member
state tracking (#909)- Changed
dpp::role
'sicon
field toutility::image_data
✨ New Features
- Support iconhash/image data variant fields (#965)
utility::image_data
for storing... image data- Added methods to change guild icon, banner, splash, discovery splash
- Added methods to set a scheduled event's banner
- Added support for Premium App Subscriptions (#969)
- Added application and following support for webhooks. (#960)
- Added the ability to limit emojis to certain roles (#959)
- Support subcommand autocomplete (#963)
dpp::application
is now updated, addedset_iconhash_not_null
(#953)- Allow changing of HTTP protocol to 1.0 for backwards API endpoints and broken servers (#951)
- Added component default values (#889)
- Added bulk command deleting. (#938)
- Added
thread_get
for threads (#930) - Added support for hsl colors (#924)
- Improved human readable error messages to default logger, with unit test (#921)
- Added an error for caps in
command_option
. (#918)
🐞 Bug Fixes
- Multiheader-cookie test, now queries a domain and url in our control which returns 3 hard coded test cookies (#968)
- Make embed color optional (#961)
- Fix
interaction_modal_response
's ambiguousto_json
(#956) - Make modals work again by making
to_json_impl
andfill_from_json
virtual (#950) - Dont require guild cache to fill member roles in message (#945)
- Make snowflake formattable again (#943)
- Refactored
guild_member_remove
- Refactors for readability
- Unit test to comply with new
message_delete
- Fix clang c++17 build (#933)
- Threads now send correctly to Discord. (#931)
- Run coro and sync generator to make coro and sync
thread_get
- Fix bug introduced by #927 (#928)
- Guild member flags can't be set by a bot (#911)
♻️ Refactoring
- Coro: deprecate
dpp::job
handler & pushdpp::task
instead, and removestatic_assert
indpp::job
(#958) - Fix
json_interface
(#937)
📚 Documentation
- Comments are now more specific in code style. (#964)
- Added a note to
setting_status
for guild cache (#955) - Added a page for default select menu values. Added a section in components3 for role select menus (#947)
- Reorganize interactions and components, add subcategories and move some things to other places (#942)
- Refactored code examples to comply with code standard (#940)
- Added a page for clearing slashcommands (#939)
- Changed
making_threads.md
to include more info (#932) - Embedded video into
windows_vs.md
(#916) - Merged all changes to
make_a_bot
from #820 (#915) - Corrected
FreeBSD.md
andopenbsd.md
(#914) - Added OpenBSD to
README.MD
(#891)
💎 Style Changes
📜 Miscellaneous Changes
- Missing runs
- Feat!: updated integration to now contain more information (#954)
- Been on a refactor binge (#941)
- Broken event data in
on_message_delete
,on_role_delete
Improvement: improved detail for many other delete events, where we can give partial information instead of none for a delete event or give ids Refactor: Removeusing namespace dpp
andusing json =
nlohmann::json` in event handler source files - Add clang builds (#934)
- Added resolved object example (#923)
- Freshen up
dpp::snowflake
anddpp::managed
(#912) - Removed
version_checker
for UE. (#970)
👷 Build/CI
- Fix vcpkg surely (#973)
- Fix #926, speedrun to #1000 (#927)
- Refactor
json.h
out of include fromdiscordevents.h
(#926) - Cancel concurrent test docs examples (#919)
- Fixed an issue with labeler failing (#917)
- Changes to labeler, stopped labeler from changing every push. (#913)
- Prevent ci runs being cancelled by github incorrectly (backwards) (#910)
- Improved security on workflows. (#903)
Thank you for using D++!
v10.0.26 release
We are pleased to announce the release of D++ version 10.0.26! This new version fixes a long standing bug with voice connections where some voice endpoints would reject the connection. If you make use of audio in D++ you are strongly encouraged to upgrade.
We have also added support for disabling the guild and channel caches. At scale, this can save anything up to gigabytes of RAM (if you have for example 200,000+ guilds and several tens of millions of channels on your bot). If you use D++ on a very large bot you should investigate using this new feature. This version also adds support for avatar decorations in the dpp::user
class.
The changelog is listed below:
Release Changelog
✨ New Features
- Allow disabling of guild and channel caches (#895)
- Added an auto-labeller for documentation PRs. (#877)
- Added avatar decoration url to the
dpp::user
class (#732) - Added
[[maybe_unused]]
in some places where it was needed (#856) - Implement clyde AI permission bits (#825)
- Created
get_url
methods for message, channel and user. (#855)
🐞 Bug Fixes
- Should fix #714, closes out issue where length of websocket-sec-key was wrong (#900)
- Update
dispatcher.h
/.cpp (#899) - Base64 sslclient key (#898)
- Awful wrong indentation in stringops (#885)
- Fix formatting in the subcommands example (#881)
- Stopped
_XOPEN_SOURCE
from defining on OpenBSD (#880) - Cmake: fix
include_directories
for installed target (#863) - Updating to fix the clamping behavior of the AVX-512 implementation. (#861)
- Wrong size assignment (#853)
- Corrected
presence.cpp
to allow custom statuses. (#848) - Fixed
discord_voice_client::send_audio_raw
blocking thread when provided with invalid size (#845) - Vcpkg wouldnt build (#843)
♻️ Refactoring
- Destroy spawn of satan type punning in ETF parser (#894)
- Changed user-agent, more logging, removed infinite loop (#883)
- Removal of unused cmake and vcpkg stuff, and adding bold red to some error messages (#867)
- Changed templates to properly fix changes from #868 (#870)
- Improving the efficiency of the AVX-implementations (#866)
- Improve AVX, make detection a little nicer (#865)
- Remove bad compile defs (#844)
- Organised .gitignore, added .idea to ignore (#827)
📚 Documentation
- Changed the notes on
read_file
. (#896) - Added minimum required clang version (#888)
- Added an openbsd page (#887)
- Added a voice model page (#882)
- Remade the
clion.md
page. (#873) - Added more info to the buildcmake page. Merged
cmake.md
with #820. (#872) - New cache example and file name fixes (#862)
- Fixed a ref issue and added more info in
discordvoiceclient.h
(#871) - Add footer to all install from binary pages (#864)
- Fixed mistakes, removed [&] (#859)
- Add auto testing of examples (#854)
- Merged
coding_style_standards.md
with #820 (#852) - Created a page about making threads (channel threads) (#850)
- Cleaned up
windows_wsl.md
(#851) - Refactored
install-vcpkg.md
(#849) - Added object editing example (#847)
- Added a private messaging page. (#835)
- Changed emojis to
unicode_emoji
and fixed callback page. (#842) - Fixed missing brackets in
attachments.md
(#840) - Added a setting status page. (#841)
- Fixed an issue in
embeds.md
(#838) - Fixed typos and added Callback Functions examples (#829)
- Coro: small touches (#824)
💎 Style Changes
- Fix some simple style issues that seem to happen a lot (#897)
📜 Miscellaneous Changes
- Extra check for 200 and 204 so we dont spam console
- Move the error checks from
sslclient.cpp
towsclient.cpp
where they belong, so they dont cause excessive data copies or false alarms - Expanded labeler to use more labels. (#892)
- Making AudioMixer a member instead of invoking it statically to cut down CPU usage by roughly 50% (#884)
- Fixing a typod type in
avx.h
(#879) - Fixing the AVX2 detection instruction. (#878)
- Improved pull request template, less checkboxes - auto close master PRs with action (#868)
- Updating some variables to be constexpr. (#858)
👷 Build/CI
- Use AVX0 not
T_fallback
- Fix avx issues on arm (#860)
- Remove ninja for all but Windows, for us it is slower than make -j2 (#857)
Thank you for using D++!