diff --git a/.github/workflows/ci-windows.yml b/.github/workflows/ci-windows.yml index 672f9eb99b..d60621a02a 100644 --- a/.github/workflows/ci-windows.yml +++ b/.github/workflows/ci-windows.yml @@ -77,7 +77,7 @@ jobs: - name: Upload artifact if: "${{ github.event_name != 'release' }}" - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: windows-installer path: ${{ github.workspace }}\build\\anope-*.exe diff --git a/.mailmap b/.mailmap index 776f660d53..39e6e7f0ee 100644 --- a/.mailmap +++ b/.mailmap @@ -15,7 +15,6 @@ Daniel Engel David Robson Dennis Friis -Dragone2 Fabio Scotoni Filippo Cortigiani Filippo Cortigiani diff --git a/data/anope.example.conf b/data/anope.example.conf index 427ca2cdc1..258b0e9e43 100644 --- a/data/anope.example.conf +++ b/data/anope.example.conf @@ -1084,6 +1084,34 @@ mail * The file that db_atheme will import your main database from. */ database = "atheme.db" + + /* + * If you have custom data in your Atheme database that you want converted + * to Anope misc data to be shown with cs_set_misc you can configure that + * using one or more cs_set_misc blocks. + */ + #cs_set_misc + { + /* The key name used by Atheme. */ + atheme = "private:misc:data" + + /* The cs_set_misc entry to import into. */ + anope = "MISC_DATA" + } + + /* + * If you have custom data in your Atheme database that you want converted + * to Anope misc data to be shown with ns_set_misc you can configure that + * using one or more ns_set_misc blocks. + */ + #ns_set_misc + { + /* The key name used by Atheme. */ + atheme = "private:misc:data" + + /* The ns_set_misc entry to import into. */ + anope = "MISC_DATA" + } } /* diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf index 17a22c20f9..4b966282b2 100644 --- a/data/chanserv.example.conf +++ b/data/chanserv.example.conf @@ -1264,12 +1264,22 @@ command { service = "ChanServ"; name = "SET SUCCESSOR"; command = "chanserv/set/ * * Provides the command chanserv/set/misc. * - * Allows you to create arbitrary commands to set data, and have that data show up in chanserv/info. - * A field named misc_description may be given for use with help output. + * Allows you to create arbitrary commands to set data, and have that data show + * up in chanserv/info. You can configure this using the following fields: + * + * misc_description: A description of the command to show in the help. + * misc_title: A human-readable description of the stored data. + * misc_numeric: If defined then the numeric (in the range 1-999) to send the + * data to users with when they join the channel. + * misc_pattern: If defined then a regex pattern (using the engine specified + * in to validate the data with). + * misc_syntax: If defined then the syntax to show in the help output and, if + * misc_pattern is defined, when a user specifies an invalid + * value. */ module { name = "cs_set_misc" } -command { service = "ChanServ"; name = "SET URL"; command = "chanserv/set/misc"; misc_description = _("Associate a URL with the channel"); misc_numeric = 328 } -command { service = "ChanServ"; name = "SET EMAIL"; command = "chanserv/set/misc"; misc_description = _("Associate an email address with the channel") } +command { service = "ChanServ"; name = "SET URL"; command = "chanserv/set/misc"; misc_description = _("Associate a URL with the channel"); misc_numeric = 328; misc_pattern = "^https?:\/\/\S+$" } +#command { service = "ChanServ"; name = "SET EMAIL"; command = "chanserv/set/misc"; misc_description = _("Associate an email address with the channel"); misc_pattern = "^\S+@\S.\S+$"; misc_title = _("Email address") } /* * cs_status diff --git a/data/nickserv.example.conf b/data/nickserv.example.conf index e751b7f52a..b0ea75b386 100644 --- a/data/nickserv.example.conf +++ b/data/nickserv.example.conf @@ -113,6 +113,7 @@ module * - memo_signon: Notify user if they have a new memo when they sign into the nick * - memo_receive: Notify user if they have a new memo as soon as it's received * - memo_mail: Notify user if they have a new memo by mail + * - autologin: User will be automatically logged in when they connect with a known SSL cert. * - autoop: User will be automatically opped in channels they enter and have access to * - neverop: User can not be added to access lists * - msg: Messages will be sent as PRIVMSGs instead of NOTICEs @@ -335,6 +336,9 @@ module max = 5 } command { service = "NickServ"; name = "CERT"; command = "nickserv/cert" } +command { service = "NickServ"; name = "SET AUTOLOGIN"; command = "nickserv/set/autologin" } +command { service = "NickServ"; name = "SASET AUTOLOGIN"; command = "nickserv/saset/autologin"; permission = "nickserv/saset/autologin" } + /* * ns_confirm @@ -732,15 +736,26 @@ command { service = "NickServ"; name = "SASET LAYOUT"; command = "nickserv/saset * * Provides the command nickserv/set/misc. * - * Allows you to create arbitrary commands to set data, and have that data show up in nickserv/info. - * A field named misc_description may be given for use with help output. + * Allows you to create arbitrary commands to set data, and have that data show + * up in nickserv/info. You can configure this using the following fields: + * + * misc_description: A description of the command to show in the help. + * misc_title: A human-readable description of the stored data. + * misc_pattern: If defined then a regex pattern (using the engine specified + * in to validate the data with). + * misc_syntax: If defined then the syntax to show in the help output and, if + * misc_pattern is defined, when a user specifies an invalid + * value. + * misc_swhois: Whether to also show the data in the WHOIS output of logged + * in users. Requires that your IRCd supports multiple swhois + entries. */ module { name = "ns_set_misc" } -command { service = "NickServ"; name = "SET URL"; command = "nickserv/set/misc"; misc_description = _("Associate a URL with your account") } +command { service = "NickServ"; name = "SET URL"; command = "nickserv/set/misc"; misc_description = _("Associate a URL with your account"); misc_pattern = "^https?:\/\/\S+$"; misc_swhois = yes } command { service = "NickServ"; name = "SASET URL"; command = "nickserv/saset/misc"; misc_description = _("Associate a URL with this account"); permission = "nickserv/saset/url"; group = "nickserv/admin" } -#command { service = "NickServ"; name = "SET MASTODON"; command = "nickserv/set/misc"; misc_description = _("Associate a Mastodon account with your account") } +#command { service = "NickServ"; name = "SET MASTODON"; command = "nickserv/set/misc"; misc_description = _("Associate a Mastodon account with your account"); misc_pattern = "^@\S+@\S+\.\S+$"; misc_title = _("Mastodon") } #command { service = "NickServ"; name = "SASET MASTODON"; command = "nickserv/saset/misc"; misc_description = _("Associate a Mastodon account with this account"); permission = "nickserv/saset/mastodon"; group = "nickserv/admin" } -#command { service = "NickServ"; name = "SET LOCATION"; command = "nickserv/set/misc"; misc_description = _("Associate a location with your account") } +#command { service = "NickServ"; name = "SET LOCATION"; command = "nickserv/set/misc"; misc_description = _("Associate a location with your account"); misc_title = _("Location") } #command { service = "NickServ"; name = "SASET LOCATION"; command = "nickserv/saset/misc"; misc_description = _("Associate a location with this account"); permission = "nickserv/saset/location"; group = "nickserv/admin" } /* diff --git a/docs/AUTHORS.txt b/docs/AUTHORS.txt index 2975857cc9..48281ae5b4 100644 --- a/docs/AUTHORS.txt +++ b/docs/AUTHORS.txt @@ -27,7 +27,6 @@ contributions they have made, are: * MatthewM * Sebastian V. * Alvaro Toledo - * Dragone2 * Björn Stiddien * n0kS Phr33d0m * Hendrik Jäger @@ -39,6 +38,7 @@ contributions they have made, are: * Federico G. Schwindt * Alexander Barton * Cronus + * Dragone2 * H7-25 * Jyzee * Sebastian Barfurth diff --git a/docs/CHANGES.md b/docs/CHANGES.md index afc911b7ca..59212f878e 100644 --- a/docs/CHANGES.md +++ b/docs/CHANGES.md @@ -1,14 +1,81 @@ # Anope Change Log -## Anope 2.1.22 (unreleased) +## Anope 2.1.22 (2026-03-01) ### Breaking Changes +* Automatic login using a known SSL fingerprint now requires the `AUTOLOGIN` option to be set on accounts with `/NS SET AUTOLOGIN ON`. Automatic login is largely obsolete now SASL EXTERNAL exists and is widely supported. + * Conan 2 is now used for packaging dependencies on Windows. If you are building from source you will need to upgrade Conan. * Non-breaking spaces in translatable messages now use 0x1B instead of 0x1A due to recent msgfmt releases treating 0x1A as an EOF character. If you have an out of tree translation you will need to update it. -## Changes +* User TLS certificates are now stored in their own `NSCert` table instead of as a column in the `NickCore` table. If you are reading this information you will need to update your code. + +### Changes + +* Fixed `{botserv}:botmodes` erroneously allowing setting non-status modes on channels. + +* Fixed echoing message tags on Solanum. + +* Fixed handling incoming `FIDENT` messages on InspIRCd. + +* Fixed matching stacked extended bans on InspIRCd and UnrealIRCd. + +* Fixed parameter modes in `chanserv/mode` locks erroneously requiring a parameter to unset a lock. + +* Fixed restoring the object identifier when unserialising objects in db_json. + +* Fixed the consistency of indenting and line wrapping command examples in help output. + +* Redesigned the output of `nickserv/list` to show more relevant information. + + ``` + /NICKSERV LIST * + -NickServ- List of entries matching *: + -NickServ- alice (account: alice) + -NickServ- alice|work (account: alice) + -NickServ- bob -- Unconfirmed (account: bob) + -NickServ- mallory -- Suspended (account: mallory) + -NickServ- End of list - 4/4 matches shown. + ``` + +* The cs_set_misc and ns_set_misc modules now can use a separate title from the command name. + + ``` + /NICKSERV SET MASTODON @example@mastodon.social + -NickServ- Mastodon for testuser set to @example@mastodon.social + ``` + +* The cs_set_misc and ns_set_misc modules now support validation of user-specified data. + + ``` + /NICKSERV SET MASTODON example.mastodon.social + -NickServ- Mastodon syntax is invalid. + -NickServ- Syntax: SET MASTODON [@user@host.tld] + ``` + +* The db_atheme module can now import arbitrary metadata to fields from the ns_set_misc module. + +* The local clock will now be checked for synchronisation with the IRCd clock on UnrealIRCd. + +* The `nickserv/cert` command will now show the time a TLS certificate was created and the nickname of the creator if the `VIEW` subcommand is used. + + ``` + /NICKSERV CERT VIEW + -NickServ- d41d8cd98f00b204e9800998ecf8427e -- created by nick1 at Wed 25 Feb 00:18:50 GMT + ``` + +* The ns_set_misc module can now add account data to the WHOIS output of authenticated users on InspIRCd (with the swhois_ext module) and UnrealIRCd. + + ``` + /WHOIS nick1 + * [nick1] (nick1@example.com): nick1 + * [nick1] Mastodon: @example@mastodon.social + * [nick1] irc.example.com :Example-IRC server + ... + * [nick1] End of WHOIS list. + ``` * The regex_posix module is now available on Windows (using the PCRE2 POSIX compatibility layer). diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index 5c4c8b9372..695fc64876 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -3,7 +3,7 @@ if(WIN32) # Only install given files from this directory # NOTE: I would've had this just find all files in the directory, but that would include files not needed (like this file) execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_BINARY_DIR}/README.txt) - set(DOCS CHANGES.md DEFCON FAQ INSTALL LANGUAGE MODULES ${CMAKE_CURRENT_BINARY_DIR}/README.txt WIN32.txt) + set(DOCS CHANGES.md DEFCON FAQ INSTALL LANGUAGE MODULES ${CMAKE_CURRENT_BINARY_DIR}/README.txt WIN32.md) install(FILES ${DOCS} DESTINATION ${DOC_DIR} ) diff --git a/docs/LANGUAGE b/docs/LANGUAGE index f324721e9a..f31c648cea 100644 --- a/docs/LANGUAGE +++ b/docs/LANGUAGE @@ -16,7 +16,7 @@ Anope Multi Language Support If you have already built Anope you will need to delete the build directory and rebuild from scratch. - Building Anope on Windows with gettext support is explained in docs/WIN32.txt + Building Anope on Windows with gettext support is explained in docs/WIN32.md 2) Adding a new language diff --git a/docs/WIN32.md b/docs/WIN32.md new file mode 100644 index 0000000000..ba10ac954b --- /dev/null +++ b/docs/WIN32.md @@ -0,0 +1,57 @@ +# Building Anope on Windows + +## Dependencies + +You will need the following software installed to build Anope: + +* [CMake 3.20 or newer](https://cmake.org/download/#latest) +* [Conan 2 or newer](https://conan.io/downloads) (optional if you don't want to build extra modules) +* [NSIS 3 or newer](https://nsis.sourceforge.io/Download) +* [Visual Studio 2022 or newer](https://visualstudio.microsoft.com/downloads/) (*NOT* Visual Studio Code) + +## Building + +First you need to download the latest version of the Anope source code from [the releases page](https://github.com/anope/anope/releases) and unpack it using Windows Explorer. + +--- + +Once you have the source code unpacked you need open the Command Prompt and move to the directory in which Anope has been unpacked. You can do this by pressing Control+R and then entering `cmd.exe` and pressing enter. Once the terminal opens you can move to the directory using the following command (assuming you unpacked to `C:\Users\Example\Downloads\anope-2.1`): + +```cmd +cd C:\Users\Example\Downloads\anope-2.1 +``` + +--- + +If you want to build with multiple-language support or want to use the enc_argon2, mysql, regex_pcre2, regex_posix, regex_tre, sqlite, or ssl_openssl extra modules you will now need to install the third-party dependencies using Conan. Before you can do this you need to create a Conan profile for C++17 using the following command: + +```cmd +conan profile detect +notepad ~\.conan2\profiles\default +``` + +When Notepad opens you should find the line beginning with `compiler.cppstd=` and replace the entire line with `compiler.cppstd=17` and save the file. + +Now you're ready to install the third-party dependencies using the following command: + + +```cmd +conan install .\src\win32 --build missing --deployer runtime_deploy --deployer-folder .\build\extradll --output-folder . +call .\conanbuild.bat +``` + +This will probably take a long time if its the first time you have run it. + +--- + +Now you're ready to build Anope. + +```cmd +cd .\build +cmake -A x64 -D "CMAKE_BUILD_TYPE=Release" -D "CMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake" .. +msbuild PACKAGE.vcxproj /P:Configuration=Release /P:Platform=x64 /VERBOSITY:MINIMAL +``` + +Once the build finishes the installer will be available in the build directory. You can install this by opening the directory in Windows Explorer and then running it as you would with most Windows installers. + +Once installed Anope will be available at `C:\Program Files\Anope`. diff --git a/docs/WIN32.txt b/docs/WIN32.txt deleted file mode 100644 index bf71530101..0000000000 --- a/docs/WIN32.txt +++ /dev/null @@ -1,161 +0,0 @@ -Anope for Windows ------------------ - -1) Building the Source -2) Installation -3) Compiling Modules -4) Other compile options -5) Credits - -1) Building the Source - - NOTE: If you have downloaded one of the pre-compiled installers, you do - NOT need to complete this step, and you can proceed to step 2. - - If you want to build Anope from source on a Win32 system, you will need - to follow this instructions: - - 1) Download the required files: - - * Current Anope source: - https://github.com/anope/anope/releases - - * CMake: - https://cmake.org/download/ - - (NOTE: When installing, tell CMake to add itself to the PATH.) - - If you have Visual C++ 10 or 11 (2010/2012) skip ahead to step 2, else you - need to download and install the following free component from Microsoft. - - * Microsoft Visual C++ 2010 Express Edition: - http://www.microsoft.com/visualstudio/eng/downloads#d-2010-express - - 2) Unpack the Anope tarball with your favorite uncompression program - (WinZip or WinRAR, etc). - - 3) Bring up the Visual C++ Command Prompt; This will launch a - DOS Command Prompt like window, which will set the environment - properties needed to make Anope. - - Create a new directory, which will be used to hold the build files. You can make it - be a directory under the source directory unpacked in step 2, or somewhere else entirely. - - Change directories to this new folder, by typing: - - cd - - e.g. - - cd c:\anope-build - - 4) You now need to configure Anope to your requirements. At the prompt type: - - \Config.exe - - NOTE: If you run an Anti-Virus program such as McAfee or Norton, you may - be unable to run this command due to the protection in place. Some Anti- - Virus programs may detect the Anope Configuration Tool as a worm, however - this is not the case. If you are prompted to allow or deny execution of - the script, you should choose allow. If the script fails to run, and no - notice is displayed, please check your Anti-Virus settings before seeking - assistance. - - An interactive configuration program should guide you through the install - options. You will be given a choice to use NMake or not. NMake will compile - inside the command prompt window you are in. If you want to build within - the Visual C++ IDE, say no to that option, and it'll create a Solution for - you to open up. - - If you cannot find whats causing the error, please visit our forums or - our IRC Support channel for assistance. - - Some Anope modules require third party libraries, such as mysql and - the SSL modules. If these libraries are installed in nonstandard - locations, cmake will probably not find them and should be told where - they are by passing their location to Config. - - The libraries used to build the 'extra' modules are available at - https://github.com/Adam-/windows-scripts. - - 5) You are now ready to compile. If you said you wanted to use NMake in step 4, - at the prompt type: - - nmake - - Once you are back at the command prompt again, if there have been no - errors, you are ready to go. - - If instead you decided to use the Visual C++ IDE, open up the Anope.sln - file. After the IDE has fully loaded, hit F7 to build everything. - - Should you encounter errors with the installation process, check the - messages displayed for advice on resolving them. If you are unable to - resolve the issues yourself, seek assistance on our forums or in our - IRC Support channel. - - 6) Finally you will need to install Anope. If you said you wanted to use NMake - in step 4, at the prompt type: - - nmake install - - Otherwise, if you decided to use the Visual C++ IDE, find the project called - INSTALL within the Solution Explorer. Right-click on INSTALL and choose Build. - - When you have done this, all the files will be installed to where they belong. - The only thing you need to do is rename "data/anope.example.conf" to be "data/anope.conf", - and then follow the steps to set up Anope. - - You have now completed the building phase of Anope for Windows. You can - now move on to the next section, which is related to setting up Anope. - -2) Installation - - Since Anope for Windows does not use a visual interface, you must do the - configuration with a text editor before proceeding with running Anope - itself. - - NOTE: You may need to open the configuration file with Wordpad, or a text - editor which supports UNIX line endings. Opening the configuration file in - Notepad will cause strange characters to appear, and you may not be able to - edit the file correctly. - - Open anope.conf, and read through it carefully and adjust the settings - you think you need to adjust. - - If you are unsure of the settings, you can go to the dos command prompt - and run "anope.exe --nofork --debug" and watch the information as it - attempts to connect. - - You can launch services in two ways. If you are sure that the entered - configuration information is correct, simply double clicking the Anope - executable will cause it to start; no window will pop up. If you'd rather - have a more textual output, you can start at the dos prompt and type in - "anope.exe". If services are successfully started up the dos prompt will - seem to hang; at this point you can safely close the dos window. - -3) Compiling Modules - - If you want to build other modules than the ones shipped by default, you - will need to rerun Config.exe - -4) Other compile options - - A) If you have trouble recompiling Anope, you should delete all files and folders - within the build folder you created in step 3 of section 1. Afterwards, follow - the directions from step 4 of section 1 down. - -5) Credits - - Anope is based on Epona and IRCServices. See CREDITS for more credits and - a complete list of all developers. - - Anope's Windows-specific code is provided by: - - * Dominick Meglio - * Trystan Scott Lee - * Chris Hogben - - Anope's Windows Installer was made using: - - * NSIS 2.20 diff --git a/include/commands.h b/include/commands.h index 2ce1430dd1..cf71ed664d 100644 --- a/include/commands.h +++ b/include/commands.h @@ -135,7 +135,7 @@ class CoreExport Command void ClearSyntax(); void SetSyntax(const Anope::string &s, const std::function &p = nullptr); - void SendSyntax(CommandSource &); + virtual void SendSyntax(CommandSource &); void AllowUnregistered(bool b); void RequireUser(bool b); diff --git a/include/defs.h b/include/defs.h index 62e1644369..5f35fa988a 100644 --- a/include/defs.h +++ b/include/defs.h @@ -42,6 +42,7 @@ struct ModeData; class Module; class NickAlias; class NickCore; +namespace NickServ { struct Cert; } struct Oper; namespace OperServ { struct Exception; } class OperType; diff --git a/include/language.h b/include/language.h index a1aff50c28..779f5f39f3 100644 --- a/include/language.h +++ b/include/language.h @@ -147,6 +147,7 @@ namespace Language #define CHAN_LIMIT_REACHED _("You have already reached your limit of \002%d\002 channels.") #define CHAN_NOT_ALLOWED_TO_JOIN _("You are not permitted to be on this channel.") #define CHAN_SETTING_CHANGED _("%s for %s set to %s.") +#define CHAN_SETTING_INVALID _("%s syntax is invalid.") #define CHAN_SETTING_UNSET _("%s for %s unset.") #define CHAN_SYMBOL_REQUIRED _("Please use the symbol of \002#\002 when attempting to register.") #define CHAN_X_INVALID _("Channel %s is not a valid channel.") diff --git a/include/modules.h b/include/modules.h index c39e2fe628..5e7774f5e4 100644 --- a/include/modules.h +++ b/include/modules.h @@ -793,13 +793,13 @@ class CoreExport Module * @param nc The nick * @param entry The entry */ - virtual void OnNickAddCert(NickCore *nc, const Anope::string &entry) ATTR_NOT_NULL(2) { throw NotImplementedException(); } + virtual void OnNickAddCert(NickCore *nc, const NickServ::Cert *entry) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); } /** Called from NickCore::EraseCert() * @param nc pointer to the NickCore * @param entry The fingerprint */ - virtual void OnNickEraseCert(NickCore *nc, const Anope::string &entry) ATTR_NOT_NULL(2) { throw NotImplementedException(); } + virtual void OnNickEraseCert(NickCore *nc, const NickServ::Cert *entry) ATTR_NOT_NULL(2, 3) { throw NotImplementedException(); } /** Called when a user requests info for a nick * @param source The user requesting info diff --git a/include/modules/nickserv/cert.h b/include/modules/nickserv/cert.h index cdf158502c..70e9816069 100644 --- a/include/modules/nickserv/cert.h +++ b/include/modules/nickserv/cert.h @@ -19,12 +19,31 @@ namespace NickServ { + struct Cert; class CertList; class CertService; ServiceReference cert_service(NICKSERV_CERT_SERVICE, NICKSERV_CERT_SERVICE); } +struct NickServ::Cert +{ + /** The account this cert is for. */ + Serialize::Reference account; + + /** The time at which this certificate was created. */ + time_t created = 0; + + /** The user who created this certificate. */ + Anope::string creator; + + /** If non-empty then a description of the certificate. */ + Anope::string description; + + /** The TLS fingerprint for the certificate. */ + Anope::string fingerprint; +}; + class NickServ::CertList { protected: @@ -39,7 +58,7 @@ class NickServ::CertList * * Adds a new entry into the cert list. */ - virtual void AddCert(const Anope::string &entry) = 0; + virtual NickServ::Cert *AddCert(const Anope::string &entry) = 0; /** Get an entry from the nick's cert list by index * @@ -48,7 +67,7 @@ class NickServ::CertList * * Retrieves an entry from the certificate list corresponding to the given index. */ - virtual Anope::string GetCert(unsigned entry) const = 0; + virtual NickServ::Cert *GetCert(unsigned entry) const = 0; virtual unsigned GetCertCount() const = 0; diff --git a/include/textproc.h b/include/textproc.h index 0634ebdc95..12f28be01b 100644 --- a/include/textproc.h +++ b/include/textproc.h @@ -101,6 +101,22 @@ namespace Anope extern CoreExport Anope::string Template(const Anope::string &str, const Anope::map &vars); } +class CoreExport ExampleWrapper final +{ +private: + struct Example final + { + Anope::string example; + Anope::string description; + Anope::string privilege; + }; + std::vector entries; + +public: + ExampleWrapper &AddEntry(const Anope::string &example, const Anope::string &desc, const Anope::string &priv = ""); + void SendTo(CommandSource &source); +}; + class CoreExport HelpWrapper final { private: diff --git a/language/anope.en_US.po b/language/anope.en_US.po index 26ec7cbcaf..e0bb5e6485 100644 --- a/language/anope.en_US.po +++ b/language/anope.en_US.po @@ -16,8 +16,8 @@ msgid "" msgstr "" "Project-Id-Version: Anope\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-01-28 19:44+0000\n" -"PO-Revision-Date: 2026-01-28 19:44+0000\n" +"POT-Creation-Date: 2026-02-24 18:55+0000\n" +"PO-Revision-Date: 2026-02-24 18:55+0000\n" "Last-Translator: Sadie Powell \n" "Language-Team: English\n" "Language: en_US\n" @@ -363,6 +363,18 @@ msgstr "" msgid "[auto-memo] The memo you sent to %s has been viewed." msgstr "" +msgid "{fingerprint}" +msgstr "" + +msgid "{fingerprint} ({description})" +msgstr "" + +msgid "{fingerprint} -- created by {creator} at {created}" +msgstr "" + +msgid "{fingerprint} -- created by {creator} at {created} ({description})" +msgstr "" + msgid "{host}: {session} sessions" msgstr "" @@ -405,13 +417,13 @@ msgstr "" msgid "{name}: {description}" msgstr "" -msgid "{nick}" +msgid "{nick} (account: {account})" msgstr "" -msgid "{nick} (last mask: {last_mask})" +msgid "{nick} ({mask}) [{real_name}]" msgstr "" -msgid "{nick} ({mask}) [{real_name}]" +msgid "{nick} -- {status} (account: {account})" msgstr "" msgid "{nick}: registered on {registered}" @@ -543,6 +555,10 @@ msgstr "" msgid "channel VIEW [mask | list]" msgstr "" +#, c-format +msgid "channel [%s]" +msgstr "" + msgid "channel [code]" msgstr "" @@ -552,9 +568,6 @@ msgstr "" msgid "channel [nick]" msgstr "" -msgid "channel [parameters]" -msgstr "" - msgid "channel [user]" msgstr "" @@ -660,13 +673,14 @@ msgstr "" msgid "nickname new-password" msgstr "" -msgid "nickname [code]" +#, c-format +msgid "nickname [%s]" msgstr "" -msgid "nickname [language]" +msgid "nickname [code]" msgstr "" -msgid "nickname [parameter]" +msgid "nickname [language]" msgstr "" msgid "nickname [password]" @@ -1123,6 +1137,10 @@ msgstr "" msgid "%s settings:" msgstr "" +#, c-format +msgid "%s syntax is invalid." +msgstr "" + #, c-format msgid "%s was not found on %s's auto join list." msgstr "" @@ -1135,6 +1153,14 @@ msgstr "" msgid "%s will not send you any notification of memos." msgstr "" +#, c-format +msgid "%s will now be automatically logged in when they connect using a known SSL certificate." +msgstr "" + +#, c-format +msgid "%s will now not be automatically logged in when they connect using a known SSL certificate." +msgstr "" + #, c-format msgid "%s will now notify you of memos when they are sent to you." msgstr "" @@ -1268,6 +1294,9 @@ msgstr "" msgid "ADD message" msgstr "" +msgid "ADD nickname fingerprint" +msgstr "" + msgid "ADD oper type" msgstr "" @@ -1280,10 +1309,10 @@ msgstr "" msgid "ADD [+expiry] mask limit reason" msgstr "" -msgid "ADD [nickname] channel [key]" +msgid "ADD [nickname fingerprint]" msgstr "" -msgid "ADD [nickname] [fingerprint]" +msgid "ADD [nickname] channel [key]" msgstr "" msgid "ADD [+expiry] mask reason" @@ -1439,6 +1468,15 @@ msgstr "" msgid "Additionally, if fantasy is enabled fantasy commands can be executed by prefixing the command name with one of the following fantasy prefixes: %s" msgstr "" +msgid "Adds a mode lock on the moderated, no external messages, topic lock flag modes as well as a ban on *!*@*.example.com." +msgstr "" + +msgid "Adds the specified fingerprint to the certificate list of nickname." +msgstr "" + +msgid "Adds your current fingerprint to your certificate list." +msgstr "" + #, c-format msgid "All O:lines of %s have been reset." msgstr "" @@ -1711,11 +1749,7 @@ msgstr "" msgid "Allows you to change and view Services Operators. Note that operators removed by this command but are still set in the configuration file are not permanently affected by this." msgstr "" -msgid "" -"Allows you to change and view configuration settings. Settings changed by this command are temporary and will not be reflected back into the configuration file, and will be lost if Anope is shut down, restarted, or the configuration is reloaded.\n" -"\n" -"Example:\n" -" MODIFYnickservregdelay15m" +msgid "Allows you to change and view configuration settings. Settings changed by this command are temporary and will not be reflected back into the configuration file, and will be lost if Anope is shut down, restarted, or the configuration is reloaded." msgstr "" msgid "Allows you to choose the way services are communicating with the given user. With MSG set, services will use messages, else they'll use notices." @@ -1774,9 +1808,6 @@ msgstr "" msgid "Associate a greet message with your nickname" msgstr "" -msgid "Associate an email address with the channel" -msgstr "" - msgid "Associate an email address with your nickname" msgstr "" @@ -2101,6 +2132,9 @@ msgstr "" msgid "Changes the password used to identify you as the nick's owner." msgstr "" +msgid "Changes the registration delay to 15 minutes." +msgstr "" + msgid "Changes the successor of a channel. If the founder's nickname expires or is dropped while the channel is still registered, the successor will become the new founder of the channel. The successor's nickname must be a registered one. If there's no successor set, then the first nickname on the access list (with the highest access, if applicable) will become the new founder, but if the access list is empty, the channel will be dropped." msgstr "" @@ -2262,6 +2296,9 @@ msgstr "" msgid "Cleared info from %s." msgstr "" +msgid "Clears all extended bans that start with channel:." +msgstr "" + msgid "Colors kicker" msgstr "" @@ -2431,6 +2468,12 @@ msgstr "" msgid "DEL entry-num" msgstr "" +msgid "DEL fingerprint" +msgstr "" + +msgid "DEL nickname fingerprint" +msgstr "" + msgid "DEL oper" msgstr "" @@ -2663,20 +2706,13 @@ msgstr[1] "" msgid "Deleted info from %s." msgstr "" -msgid "" -"Deletes the specified memo or memos. You can supply multiple memo numbers or ranges of numbers instead of a single number, as in the second example below.\n" -"\n" -"If LAST is given, the last memo will be deleted.\n" -"\n" -"If ALL is given, deletes all of your memos.\n" -"\n" -"Examples:\n" -"\n" -" DEL1\n" -" Deletes your first memo.\n" -"\n" -" DEL2-5,7-9\n" -" Deletes memos numbered 2 through 5 and 7 through 9." +msgid "Deletes all of your memos." +msgstr "" + +msgid "Deletes memos numbered 2 through 5 and 7 through 9." +msgstr "" + +msgid "Deletes the specified memo or memos. You can supply multiple memo numbers or ranges of numbers instead of a single number, as in the second example below." msgstr "" msgid "Deletes the vhost assigned to the given nick from the database." @@ -2688,6 +2724,12 @@ msgstr "" msgid "Deletes the vhost for all nicks in the same account as that of the given nick." msgstr "" +msgid "Deletes your first memo." +msgstr "" + +msgid "Deletes your last memo." +msgstr "" + #, c-format msgid "Depooled %s." msgstr "" @@ -2728,6 +2770,12 @@ msgstr "" msgid "Displayed records matching key %s (count: %d)." msgstr "" +msgid "Displays all of your memos." +msgstr "" + +msgid "Displays any new memos." +msgstr "" + msgid "Displays information about a given nickname" msgstr "" @@ -2737,9 +2785,18 @@ msgstr "" msgid "Displays information about your memos" msgstr "" +msgid "Displays memos numbered 2 through 5 and 7 through 9." +msgstr "" + msgid "Displays one or more vhost entries" msgstr "" +msgid "Displays the current certificate list of nickname as well as the details about who added each entry and when they added it." +msgstr "" + +msgid "Displays the current certificate list of nickname." +msgstr "" + msgid "Displays the top 10 users of a channel" msgstr "" @@ -2761,6 +2818,15 @@ msgstr "" msgid "Displays your Global Stats" msgstr "" +msgid "Displays your current certificate list as well the details about who added each entry and when they added it." +msgstr "" + +msgid "Displays your current certificate list." +msgstr "" + +msgid "Displays your last memo." +msgstr "" + msgid "Don't use AMSGs!" msgstr "" @@ -2996,6 +3062,9 @@ msgstr "" msgid "Error! The vident is too long, please use an ident shorter than %zu characters." msgstr "" +msgid "Examples:" +msgstr "" + #, c-format msgid "Exception for %s has been updated to %d." msgstr "" @@ -3029,6 +3098,9 @@ msgstr "" msgid "Find a user's status on a channel" msgstr "" +msgid "Fingerprint" +msgstr "" + #, c-format msgid "Fingerprint %s already present on %s's certificate list." msgstr "" @@ -3289,6 +3361,9 @@ msgstr "" msgid "LIMIT enforced on %s, %zu users removed." msgstr "" +msgid "LIST nickname" +msgstr "" + msgid "LIST threshold" msgstr "" @@ -3312,9 +3387,6 @@ msgstr "" msgid "Language for %s changed to %s." msgstr "" -msgid "Last mask" -msgstr "" - #, c-format msgid "Last memo to %s has been cancelled." msgstr "" @@ -3412,6 +3484,24 @@ msgstr "" msgid "List your memos" msgstr "" +msgid "Lists AKILL entries numbered 2 through 5 and 7 through 9." +msgstr "" + +msgid "Lists SNLINE entries numbered 2 through 5 and 7 through 9." +msgstr "" + +msgid "Lists SQLINE entries numbered 2 through 5 and 7 through 9." +msgstr "" + +msgid "Lists access entries numbered 2 through 5 and 7 through 9." +msgstr "" + +msgid "Lists access entries on #channel numbered 2 through 5 and 7 through 9." +msgstr "" + +msgid "Lists access entries on #channel that match *nick*." +msgstr "" + msgid "" "Lists all available bots on this network.\n" "\n" @@ -3449,19 +3539,19 @@ msgid "" "\n" "Note that a preceding '#' specifies a range, channel names are to be written without '#'.\n" "\n" -"If the SUSPENDED or NOEXPIRE options are given, only channels which, respectively, are SUSPENDED or have the NOEXPIRE flag set will be displayed. If multiple options are given, all channels matching at least one option will be displayed. Note that these options are limited to Services Operators.\n" -"\n" -"Examples:\n" -"\n" -" LIST*anope*\n" -" Lists all registered channels with anope in their\n" -" names (case insensitive).\n" -"\n" -" LIST*NOEXPIRE\n" -" Lists all registered channels which have been set to not expire.\n" -"\n" -" LIST #51-100\n" -" Lists all registered channels within the given range (51-100)." +"If the SUSPENDED or NOEXPIRE options are given, only channels which, respectively, are SUSPENDED or have the NOEXPIRE flag set will be displayed. If multiple options are given, all channels matching at least one option will be displayed. Note that these options are limited to Services Operators." +msgstr "" + +msgid "Lists all registered channels that have been set to not expire." +msgstr "" + +msgid "Lists all registered channels that have been suspended." +msgstr "" + +msgid "Lists all registered channels with anope in their name (case insensitive). " +msgstr "" + +msgid "Lists all registered channels within the given range (51-100)." msgstr "" msgid "" @@ -3469,22 +3559,25 @@ msgid "" "\n" "Note that a preceding '#' specifies a range.\n" "\n" -"If the DISPLAY, NOEXPIRE, SUSPENDED, or UNCONFIRMED options are given only nicks which, respectively, are display nicks, will not expire, are suspended, or are unconfirmed will be shown. If multiple options are given, nicks must match every option to be shown. Note that these options are limited to Services Operators.\n" -"\n" -"Examples:\n" -"\n" -" LIST *!joeuser@foo.com\n" -" Lists all registered nicks owned by joeuser@foo.com.\n" -"\n" -" LIST *Bot*!*@*\n" -" Lists all registered nicks with Bot in their\n" -" names (case insensitive).\n" -"\n" -" LIST * NOEXPIRE\n" -" Lists all registered nicks which have been set to not expire.\n" -"\n" -" LIST #51-100\n" -" Lists all registered nicks within the given range (51-100)." +"If the DISPLAY, NOEXPIRE, SUSPENDED, or UNCONFIRMED options are given only nicks which, respectively, are display nicks, will not expire, are suspended, or are unconfirmed will be shown. If multiple options are given, nicks must match every option to be shown. Note that these options are limited to Services Operators." +msgstr "" + +msgid "Lists all registered nicks that are the display nickname for their account." +msgstr "" + +msgid "Lists all registered nicks that have been set to not expire." +msgstr "" + +msgid "Lists all registered nicks that have been suspended." +msgstr "" + +msgid "Lists all registered nicks that have not been confirmed yet." +msgstr "" + +msgid "Lists all registered nicks with Bot in their name (case insensitive)." +msgstr "" + +msgid "Lists all registered nicks within the given range (51-100)." msgstr "" msgid "Lists all user records" @@ -3496,15 +3589,21 @@ msgid "" "If pattern is given, lists only users that match it (it must be in the format nick!user@host[#realname]). If channel is given, lists only users that are on the given channel. If INVISIBLE is specified, only users with the +i flag will be listed." msgstr "" -msgid "" -"Lists any memos you currently have. With NEW, lists only new (unread) memos. Unread memos are marked with a \"*\" to the left of the memo number. You can also specify a list of numbers, as in the example below:\n" -" LIST 2-5,7-9\n" -" Lists memos numbered 2 through 5 and 7 through 9." +msgid "Lists any memos you currently have. With NEW, lists only new (unread) memos. Unread memos are marked with a \"*\" to the left of the memo number. You can also specify a list of numbers." +msgstr "" + +msgid "Lists any new memos." msgstr "" msgid "Lists available bots" msgstr "" +msgid "Lists bad word entries on #channel numbered 2 through 5 and 7 through 9." +msgstr "" + +msgid "Lists bad word entries on #channel that match *UwU*." +msgstr "" + msgid "Lists currently loaded modules." msgstr "" @@ -3514,6 +3613,9 @@ msgstr "" msgid "Lists information about the specified registered channel, including its founder, time of registration, last time used, and description. If the user issuing the command has the appropriate access for it, then the successor, last topic set, settings and expiration time will also be displayed when applicable." msgstr "" +msgid "Lists memos numbered 2 through 5 and 7 through 9." +msgstr "" + msgid "Load a module" msgstr "" @@ -3569,19 +3671,8 @@ msgid "" "\n" "The %sLOCK command allows you to add, delete, and view mode locks on a channel. If a mode is locked on or off, services will not allow that mode to be changed. The SET command will clear all existing mode locks and set the new one given, while ADD and DEL modify the existing mode lock.\n" "\n" -"Example:\n" -" %s#channelLOCKADD+bmnt*!*@*.example.com\n" -"\n" -"\n" "The %sSET command allows you to set modes through services. Wildcards * and ? may be given as parameters for list and status modes.\n" "\n" -"Example:\n" -" %s#channelSET+v*\n" -" Sets voice status to all users in the channel.\n" -"\n" -" %s#channelSET-b~c:*\n" -" Clears all extended bans that start with ~c:\n" -"\n" "The %sCLEAR command is an easy way to clear modes on a channel. what may be any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and voices. If what is not given then all basic modes are removed." msgstr "" @@ -3627,10 +3718,7 @@ msgid "" "\n" "The DEL command removes the given word from the bad words list. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The LIST command displays the bad words list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" #channelLIST2-5,7-9\n" -" Lists bad words entries numbered 2 through 5 and\n" -" 7 through 9.\n" +"The LIST command displays the bad words list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "The CLEAR command clears all entries from the bad words list." msgstr "" @@ -3787,22 +3875,7 @@ msgstr "" msgid "Modes cleared on %s and the channel destroyed." msgstr "" -#, c-format -msgid "" -"Modifies or displays the certificate list for your nick. If you connect to IRC and provide a client certificate with a matching fingerprint in the cert list, you will be automatically identified to services. Services Operators may provide a nick to modify other users' certificate lists.\n" -"\n" -"Examples:\n" -"\n" -" %sADD\n" -" Adds your current fingerprint to the certificate list and\n" -" automatically identifies you when you connect to IRC\n" -" using this fingerprint.\n" -"\n" -" %sDEL\n" -" Removes the fingerprint from your certificate list.\n" -"\n" -" %sLIST\n" -" Displays the current certificate list." +msgid "Modifies or displays the certificate list for your nick. If you connect to IRC and provide a client certificate with a matching fingerprint in the cert list, you will be automatically identified to services. Services Operators may provide a nick to modify other users' certificate lists." msgstr "" #, c-format @@ -4530,6 +4603,15 @@ msgstr "" msgid "Removes a selected nicks status modes on a channel. If nick is omitted then your status is removed. If channel is omitted then your channel status is removed on every channel you are in." msgstr "" +msgid "Removes all entries that were added in the last 30 minutes." +msgstr "" + +msgid "Removes the specified fingerprint from the certificate list of nickname." +msgstr "" + +msgid "Removes the specified fingerprint from your certificate list." +msgstr "" + #, c-format msgid "Removing %s because %s covers it." msgstr "" @@ -4617,6 +4699,9 @@ msgstr "" msgid "Searches logs for a matching pattern" msgstr "" +msgid "Searches the last 21 days worth of logs for messages containing Anope and lists the most recent 500 of them." +msgstr "" + msgid "Secure founder" msgstr "" @@ -4679,6 +4764,15 @@ msgstr "" msgid "Sends a memo and requests a read receipt" msgstr "" +msgid "Sends a memo to the channel when someone uses the chanserv/xop command on #anope." +msgstr "" + +msgid "Sends a message to channel operators and above when someone uses the chanserv/access command on #anope." +msgstr "" + +msgid "Sends a notice to channel voices and above when someone uses the chanserv/flags command on #anope." +msgstr "" + msgid "Sends all registered users a memo containing memo-text." msgstr "" @@ -4691,11 +4785,7 @@ msgstr "" msgid "Sends the named nick or channel a memo containing memo-text. When sending to a nickname, the recipient will receive a notice that they have a new memo. The target nickname/channel must be registered. Once the memo is read by its recipient, an automatic notification memo will be sent to the sender informing them that the memo has been read." msgstr "" -msgid "" -"Sends you the text of the memos specified. If LAST is given, sends you the memo you most recently received. If NEW is given, sends you all of your new memos. If ALL is given, sends you all of your memos. Otherwise, sends you memo number num. You can also give a list of numbers, as in this example:\n" -"\n" -" READ 2-5,7-9\n" -" Displays memos numbered 2 through 5 and 7 through 9." +msgid "Sends you the text of the memos specified. If LAST is given, sends you the memo you most recently received. If NEW is given, sends you all of your new memos. If ALL is given, sends you all of your memos. Otherwise, sends you memo number num. You can also give a list of numbers." msgstr "" msgid "Server" @@ -5020,6 +5110,9 @@ msgstr "" msgid "Sets various nickname options. option can be one of:" msgstr "" +msgid "Sets voice status on all users in the channel." +msgstr "" + msgid "Sets whether services should set channel status modes on you automatically." msgstr "" @@ -5029,6 +5122,10 @@ msgstr "" msgid "Sets whether the given nickname can be added to a channel access list." msgstr "" +#, c-format +msgid "Sets whether the given nickname should automatically be logged in when they connect using a known SSL certificate. You can configure their SSL certificate using the %s command." +msgstr "" + #, c-format msgid "Sets whether the given nickname will be given its status modes in channels automatically. Set to ON to allow %s to set status modes on the given nickname automatically when it is entering channels. Note that depending on channel settings some modes may not get set automatically." msgstr "" @@ -5039,6 +5136,13 @@ msgstr "" msgid "Sets whether you can be added to a channel access list." msgstr "" +msgid "Sets whether you should automatically be logged in when you connect using a known SSL certificate." +msgstr "" + +#, c-format +msgid "Sets whether you should automatically be logged in when you connect using a known SSL certificate. You can configure your SSL certificate using the %s command." +msgstr "" + #, c-format msgid "Sets whether you will be given your channel status modes automatically. Set to ON to allow %s to set status modes on you automatically when entering channels. Note that depending on channel settings some modes may not get set automatically." msgstr "" @@ -5069,6 +5173,9 @@ msgstr "" msgid "Showed %zu/%zu matches for %s." msgstr "" +msgid "Shows the current server configuration." +msgstr "" + msgid "Sign kicks that are done with the KICK command" msgstr "" @@ -5096,6 +5203,9 @@ msgstr "" msgid "Statistics reset." msgstr "" +msgid "Status" +msgstr "" + msgid "Status updated (memos, vhost, chmodes, flags)." msgstr "" @@ -5278,10 +5388,7 @@ msgid "" "\n" "The %sDEL command removes the given nick from the %s list. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The %sLIST command displays the %s list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" %s#channelLIST2-5,7-9\n" -" Lists %s entries numbered 2 through 5 and\n" -" 7 through 9.\n" +"The %sLIST command displays the %s list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "The %sCLEAR command clears all entries of the %s list." msgstr "" @@ -5290,10 +5397,7 @@ msgstr "" msgid "" "The %sDEL command removes the given mask from the AKILL list if it is present. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The %sLIST command displays the AKILL list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" %sLIST2-5,7-9\n" -" Lists AKILL entries numbered 2 through 5 and 7\n" -" through 9.\n" +"The %sLIST command displays the AKILL list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "%sVIEW is a more verbose version of %sLIST, and will show who added an AKILL, the date it was added, and when it expires, as well as the user@host/ip mask and reason.\n" "\n" @@ -5304,10 +5408,7 @@ msgstr "" msgid "" "The %sDEL command removes the given nick from the access list. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.) You may remove yourself from an access list, even if you do not have access to modify that list otherwise.\n" "\n" -"The %sLIST command displays the access list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" %s#channelLIST2-5,7-9\n" -" Lists access entries numbered 2 through 5 and\n" -" 7 through 9.\n" +"The %sLIST command displays the access list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "The %sVIEW command displays the access list similar to %sLIST but shows the creator and last used time.\n" "\n" @@ -5317,10 +5418,7 @@ msgstr "" msgid "" "The SNLINEDEL command removes the given mask from the SNLINE list if it is present. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The SNLINELIST command displays the SNLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" SNLINELIST2-5,7-9\n" -" Lists SNLINE entries numbered 2 through 5 and 7\n" -" through 9.\n" +"The SNLINELIST command displays the SNLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "SNLINEVIEW is a more verbose version of SNLINELIST, and will show who added an SNLINE, the date it was added, and when it expires, as well as the realname mask and reason.\n" "\n" @@ -5330,25 +5428,17 @@ msgstr "" msgid "" "The SQLINEDEL command removes the given mask from the SQLINE list if it is present. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The SQLINELIST command displays the SQLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" SQLINELIST2-5,7-9\n" -" Lists SQLINE entries numbered 2 through 5 and 7\n" -" through 9.\n" +"The SQLINELIST command displays the SQLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "SQLINEVIEW is a more verbose version of SQLINELIST, and will show who added an SQLINE, the date it was added, and when it expires, as well as the mask and reason.\n" "\n" "SQLINECLEAR clears all entries of the SQLINE list." msgstr "" -#, c-format msgid "" "The STATS command prints out statistics about stored nicks and memory usage.\n" "\n" -"The CLEAR command lets you clean the database by removing all entries from the database that were added within time.\n" -"\n" -"Example:\n" -" %sCLEAR30m\n" -" Will remove all entries that were added within the last 30 minutes." +"The CLEAR command lets you clean the database by removing all entries from the database that were added within time." msgstr "" msgid "The email parameter is optional and will set the email address for your nick immediately. You may also wish to SETHIDE it after registering if it isn't the default setting already." @@ -5364,11 +5454,7 @@ msgid "" "\n" "Which are used to message, notice, and memo the channel respectively. With MESSAGE or NOTICE you must have a service bot assigned to and joined to your channel. Status may be a channel status such as @ or +.\n" "\n" -"To remove a logging method use the same syntax as you would to add it.\n" -"\n" -"Example:\n" -" %s#anopechanserv/accessMESSAGE@\n" -" Would message any channel operators whenever someone used the ACCESS command on ChanServ on the channel." +"To remove a logging method use the same syntax as you would to add it." msgstr "" #, c-format @@ -5683,13 +5769,7 @@ msgstr "" msgid "This command retrieves the vhost requests." msgstr "" -msgid "" -"This command searches the services logfiles for messages that match the given pattern. The day and limit argument may be used to specify how many days of logs to search and the number of replies to limit to. By default this command searches one week of logs, and limits replies to 50.\n" -"\n" -"For example:\n" -" LOGSEARCH+21d+500lAnope\n" -" Searches the last 21 days worth of logs for messages\n" -" containing Anope and lists the most recent 500 of them." +msgid "This command searches the services logfiles for messages that match the given pattern. The day and limit argument may be used to specify how many days of logs to search and the number of replies to limit to. By default this command searches one week of logs, and limits replies to 50." msgstr "" msgid "This command tells you what a users access is on a channel and what access entries, if any, they match. Additionally it will tell you of any auto kick entries they match. Usage of this command is limited to users who have the ability to modify access entries on the channel." @@ -5877,6 +5957,9 @@ msgstr "" msgid "Unassigns a bot from a channel. When you use this command, the bot won't join the channel anymore. However, bot configuration for the channel is kept, so you will always be able to reassign a bot later without having to reconfigure it entirely." msgstr "" +msgid "Unconfirmed" +msgstr "" + msgid "Underlines kicker" msgstr "" @@ -6042,12 +6125,18 @@ msgstr "" msgid "VIEW host" msgstr "" +msgid "VIEW nickname" +msgstr "" + msgid "VIEW [mask | list | id]" msgstr "" msgid "VIEW [mask | list]" msgstr "" +msgid "VIEW [nickname]" +msgstr "" + msgid "VIEW [vhost-mask | entry-num | list]" msgstr "" @@ -6712,15 +6801,9 @@ msgstr "" msgid "[+expiry] channel reason" msgstr "" -msgid "[Hostname hidden]" -msgstr "" - msgid "[Suspended]" msgstr "" -msgid "[Unconfirmed]" -msgstr "" - msgid "[{pattern | channel} [INVISIBLE]]" msgstr "" @@ -6744,6 +6827,9 @@ msgstr "" msgid "not assigned yet" msgstr "" +msgid "value" +msgstr "" + msgid "vhost" msgstr "" diff --git a/language/anope.ro_RO.po b/language/anope.ro_RO.po index 0fe04c6efb..067a339648 100644 --- a/language/anope.ro_RO.po +++ b/language/anope.ro_RO.po @@ -15,9 +15,9 @@ msgid "" msgstr "" "Project-Id-Version: Anope\n" -"Report-Msgid-Bugs-To: #anope.ro at TeraNova IRC Network\n" -"POT-Creation-Date: 2025-10-09 17:10+0100\n" -"PO-Revision-Date: 2025-10-09 17:10+0100\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-03-01 16:00+0000\n" +"PO-Revision-Date: 2026-03-01 17:00+0000\n" "Last-Translator: Cristian Anghel \n" "Language-Team: Romanian\n" "Language: ro_RO\n" @@ -73,6 +73,10 @@ msgstr "%s a fost adăugat(ă) în lista de %s." msgid "%s added to the AKILL list." msgstr "%s a fost adăugat(ă) în lista de AKILL." +#, c-format +msgid "%s added to the host offer list." +msgstr "%s a fost adăugat(ă) în lista de oferte pentru gazde." + #, c-format msgid "%s allows you to execute \"fantasy\" commands in the channel. Fantasy commands are commands that can be executed from messaging a channel, and provide a more convenient way to execute commands. Commands that require a channel as a parameter will automatically have that parameter given." msgstr "%s vă permite să executați comenzile fanteziste ( \"fantasy\") în canal. Comenzile fanteziste sunt comenzi care pot fi executate prin trimiterea de mesaje într-un canal și oferă astfel o modalitate mai convenabilă de a executa comenzi. Comenzile care necesită un canal ca parametru vor avea automat acel parametru atribuit." @@ -149,6 +153,10 @@ msgstr "%s a fost înlăturat(ă) din lista de %s." msgid "%s deleted from the AKILL list." msgstr "%s a fost înlăturat(ă) din lista de AKILL." +#, c-format +msgid "%s deleted from the host offer list." +msgstr "%s a fost înlăturat(ă) din lista de oferte pentru gazde." + #, c-format msgid "%s disabled on channel %s." msgstr "%s a fost dezactivat(ă) în canalul %s." @@ -307,6 +315,10 @@ msgstr "%s este de negăsit în lista de %s." msgid "%s not found on the AKILL list." msgstr "%s este de negăsit în lista de AKILL." +#, c-format +msgid "%s not found on the host offer list." +msgstr "%s este de negăsit în lista de oferte pentru gazde." + #, c-format msgid "%s removed from the %s access list." msgstr "%s a fost înlăturat(ă) din lista de accese aparținând %s." @@ -354,6 +366,18 @@ msgstr "Nivelurile de acces ale utilizatorilor pot fi văzute folosind comanda msgid "[auto-memo] The memo you sent to %s has been viewed." msgstr "[confirmare] Misiva pe care ați expediat-o către %s a fost vizualizată." +msgid "{fingerprint}" +msgstr "{fingerprint}" + +msgid "{fingerprint} ({description})" +msgstr "{fingerprint} ({description})" + +msgid "{fingerprint} -- created by {creator} at {created}" +msgstr "{fingerprint} -- creat de {creator} pe {created}" + +msgid "{fingerprint} -- created by {creator} at {created} ({description})" +msgstr "{fingerprint} -- creat de {creator} la {created} ({description})" + msgid "{host}: {session} sessions" msgstr "{host}: {session} sesiuni" @@ -396,15 +420,15 @@ msgstr "{name} = {value}" msgid "{name}: {description}" msgstr "{name}: {description}" -msgid "{nick}" -msgstr "{nick}" - -msgid "{nick} (last mask: {last_mask})" -msgstr "{nick} (ultima mască: {last_mask})" +msgid "{nick} (account: {account})" +msgstr "{nick} (cont: {account})" msgid "{nick} ({mask}) [{real_name}]" msgstr "{nick} ({mask}) [{real_name}]" +msgid "{nick} -- {status} (account: {account})" +msgstr "{nick} -- {status} (cont: {account})" + msgid "{nick}: registered on {registered}" msgstr "{nick}: înregistrat(ă) pe {registered}" @@ -430,7 +454,7 @@ msgid "channel bantype" msgstr "canal tip-blocare" msgid "channel command method [status]" -msgstr "canal commandă metodă [statut]" +msgstr "canal commandă metodă [stare]" msgid "channel mask [reason]" msgstr "canal mască [motiv]" @@ -534,6 +558,10 @@ msgstr "canal VIEW [mască | număr-intrare | listă]" msgid "channel VIEW [mask | list]" msgstr "canal VIEW [mască | listă]" +#, c-format +msgid "channel [%s]" +msgstr "canal [%s]" + msgid "channel [code]" msgstr "canal [cod]" @@ -543,9 +571,6 @@ msgstr "canal [descriere]" msgid "channel [nick]" msgstr "canal [pseudonim]" -msgid "channel [parameters]" -msgstr "canal [parametri]" - msgid "channel [user]" msgstr "canal [utilizator]" @@ -571,16 +596,16 @@ msgid "channel {ON|OFF}" msgstr "canal {ON|OFF}" msgid "channel {ON|OFF} [ttb [ln [secs]]]" -msgstr "canal {ON|OFF} [ttb [linii [secunde]]]" +msgstr "canal {ON|OFF} [tentative [linii [secunde]]]" msgid "channel {ON|OFF} [ttb [min [percent]]]" -msgstr "canal {ON|OFF} [ttb [minim [procentaj]]]" +msgstr "canal {ON|OFF} [tentative [minim [procentaj]]]" msgid "channel {ON|OFF} [ttb [num]]" -msgstr "canal {ON|OFF} [ttb [număr]]" +msgstr "canal {ON|OFF} [tentative [număr]]" msgid "channel {ON|OFF} [ttb]" -msgstr "canal {ON|OFF} [ttb]" +msgstr "canal {ON|OFF} [tentative]" msgid "channel {DIS | DISABLE} type" msgstr "channel {DIS | DISABLE} tip" @@ -597,9 +622,6 @@ msgstr "cod" msgid "email" msgstr "email" -msgid "language" -msgstr "limbă" - msgid "memo-text" msgstr "text-misivă" @@ -645,9 +667,6 @@ msgstr "pseudonim adresă" msgid "nickname email" msgstr "pseudonim email" -msgid "nickname language" -msgstr "pseudonim limbă" - msgid "nickname message" msgstr "pseudonim mesaj" @@ -657,18 +676,22 @@ msgstr "pseudonim afișaj-nou" msgid "nickname new-password" msgstr "pseudonim parolă-nouă" -msgid "nickname timezone" -msgstr "pseudonim fus-orar" +#, c-format +msgid "nickname [%s]" +msgstr "pseudonim [%s]" msgid "nickname [code]" msgstr "pseudonim [cod]" -msgid "nickname [parameter]" -msgstr "pseudonim [parametru]" +msgid "nickname [language]" +msgstr "pseudonim [limbă]" msgid "nickname [password]" msgstr "pseudonim [parolă]" +msgid "nickname [timezone]" +msgstr "pseudonim [fus-orar]" + msgid "nickname [+expiry] [reason]" msgstr "pseudonim [+expirare] [motiv]" @@ -711,21 +734,18 @@ msgstr "parolă [email]" msgid "password email" msgstr "parolă email" +msgid "pattern [DISPLAY] [NOEXPIRE] [SUSPENDED] [UNCONFIRMED]" +msgstr "model [DISPLAY] [NOEXPIRE] [SUSPENDED] [UNCONFIRMED]" + msgid "pattern [SUSPENDED] [NOEXPIRE]" msgstr "model [SUSPENDED] [NOEXPIRE]" -msgid "pattern [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]" -msgstr "model [SUSPENDED] [NOEXPIRE] [UNCONFIRMED]" - msgid "server [message]" msgstr "server [mesaj]" msgid "server [reason]" msgstr "server [motiv]" -msgid "timezone" -msgstr "fus-orar" - msgid "type parameters" msgstr "tip parametri" @@ -771,15 +791,7 @@ msgstr "%2d %-16s litere: %s, cuvinte: %s, linii: %s, zâmbete: %s, acțiuni: #, c-format msgid "%c is an unknown status mode." -msgstr "%c este un mod de statut necunoscut." - -#, c-format -msgid "%c%c is not locked on %s." -msgstr "%c%c nu este încuiat în %s." - -#, c-format -msgid "%c%c%s has been unlocked from %s." -msgstr "%c%c%s a fost descuiat din %s." +msgstr "%c este un mod de stare necunoscut." #, c-format msgid "%d access entries from %s have been cloned to %s." @@ -903,6 +915,10 @@ msgstr "%s (%s) a fost văzut(ă) ultima dată îndepărtându-se dintr-un canal msgid "%s (%s) was last seen quitting (%s) %s ago (%s)." msgstr "%s (%s) a fost văzut(ă) ultima dată plecând din rețea (%s) acum %s (%s)." +#, c-format +msgid "%s (ID: %zu)" +msgstr "%s (Identificator: %zu)" + #, c-format msgid "%s (minimum %d/%d%%)" msgstr "%s (minim %d/%d%%)" @@ -911,6 +927,10 @@ msgstr "%s (minim %d/%d%%)" msgid "%s (now)" msgstr "%s (acum)" +#, c-format +msgid "%s [Invalid]" +msgstr "%s [Invalid]" + #, c-format msgid "%s access list is empty." msgstr "Lista de accese aparținând %s este goală." @@ -935,6 +955,10 @@ msgstr "Lista de cuvinte nepotrivite aparținând %s este goală." msgid "%s can no longer be added to channel access lists." msgstr "%s nu mai poate fi adăugat(ă) în listele de acces ale canalelor." +#, c-format +msgid "%s can not be locked on %s." +msgstr "%s nu poate fi încuiat în %s." + #, c-format msgid "%s can now be added to channel access lists." msgstr "%s poate fi adăugat(ă) acum în listele de accese ale canalelor." @@ -979,6 +1003,10 @@ msgstr "%s are momentan 1 misivă." msgid "%s currently has no memos." msgstr "%s nu are momentan nicio misivă." +#, c-format +msgid "%s currently has too many memos and cannot receive more." +msgstr "%s are în prezent prea multe misive și nu mai poate primi altele." + #, c-format msgid "%s deleted from the %s forbid list." msgstr "%s a fost înlăturat(ă) din lista de interziceri %s." @@ -995,6 +1023,14 @@ msgstr "%s pentru %s a fost de-setat." msgid "%s had an invalid key specified, and was thus ignored." msgstr "%s a avut specificată o cheie invalidă, prin urmare a fost ignorată." +#, c-format +msgid "%s has been locked on %s." +msgstr "%s a fost descuiat din %s." + +#, c-format +msgid "%s has been unlocked from %s." +msgstr "%s a fost descuiat din %s." + #, c-format msgid "%s has no memo limit." msgstr "%s nu are limită de misive." @@ -1023,6 +1059,10 @@ msgstr "%s este deja acoperit(ă) de %s." msgid "%s is already on %s's auto join list." msgstr "%s se află deja în lista de alăturări automate aparținând %s." +#, c-format +msgid "%s is an invalid host offer entry number." +msgstr "%s este un număr de intrare invalid pentru oferta de gazdă." + #, c-format msgid "%s is an unconfirmed nickname." msgstr "%s este un pseudonim neconfirmat." @@ -1073,6 +1113,10 @@ msgstr "%s nu este o comandă validă." msgid "%s is not a valid logging method." msgstr "%s nu este o metodă de jurnalizare validă." +#, c-format +msgid "%s is not locked on %s." +msgstr "%s nu este încuiat în %s." + #, c-format msgid "%s is not notified of new memos." msgstr "%s nu este notificat(ă) despre noile misive." @@ -1097,10 +1141,6 @@ msgstr "Lista de %s pentru %s" msgid "%s list is empty." msgstr "Lista de %s este goală." -#, c-format -msgid "%s locked on %s." -msgstr "%s este încuiat pentru %s." - #, c-format msgid "%s not found." msgstr "%s nu a fost găsit(ă)." @@ -1109,6 +1149,10 @@ msgstr "%s nu a fost găsit(ă)." msgid "%s settings:" msgstr "Setările %s sunt după cum urmează:" +#, c-format +msgid "%s syntax is invalid." +msgstr "Sintaxa %s este invalidă" + #, c-format msgid "%s was not found on %s's auto join list." msgstr "%s nu a fost găsit(ă) în lista de alăturări automate aparținând %s." @@ -1121,6 +1165,14 @@ msgstr "%s a fost înlăturat(ă) din lista de alăturări automate aparținând msgid "%s will not send you any notification of memos." msgstr "%s nu vă va expedia nicio notificare despre misive." +#, c-format +msgid "%s will now be automatically logged in when they connect using a known SSL certificate." +msgstr "%s va fi autentificat(ă) automat atunci când se conectează utilizând un certificat SSL cunoscut." + +#, c-format +msgid "%s will now not be automatically logged in when they connect using a known SSL certificate." +msgstr "%s nu va fi autentificat(ă) automat atunci când se conectează utilizând un certificat SSL cunoscut." + #, c-format msgid "%s will now notify you of memos when they are sent to you." msgstr "%s vă va notifica despre misive atunci când vă sunt expediate." @@ -1222,9 +1274,6 @@ msgstr ", dar %s s-a dematerializat în mod misterios." msgid ". %s is still online." msgstr ". %s este încă online." -msgid "" -msgstr "" - msgid "@nickname" msgstr "@pseudonim" @@ -1257,6 +1306,9 @@ msgstr "ADD expirare {pseudonim|mască} [motiv]" msgid "ADD message" msgstr "ADD mesaj" +msgid "ADD nickname fingerprint" +msgstr "ADD pseudonim amprentă-digitală" + msgid "ADD oper type" msgstr "ADD Operator tip" @@ -1269,20 +1321,23 @@ msgstr "ADD text" msgid "ADD [+expiry] mask limit reason" msgstr "ADD [+expirare] mască limită motiv" +msgid "ADD [nickname fingerprint]" +msgstr "ADD [pseudonim amprentă-digitală]" + msgid "ADD [nickname] channel [key]" msgstr "ADD [pseudonim] canal [cheie]" -msgid "ADD [nickname] [fingerprint]" -msgstr "ADD [pseudonim] [amprentă-digitală]" - msgid "ADD [+expiry] mask reason" msgstr "ADD [+expirare] mască motiv" msgid "ADD [+expiry] mask:reason" msgstr "ADD [+expirare] mască:motiv" -msgid "ADD {NICK|CHAN|EMAIL|REGISTER} [+expiry] entry reason" -msgstr "ADD {NICK|CHAN|EMAIL|REGISTER} [+expirare] intrare motiv" +msgid "ADD [+expiry] vhost [reason]" +msgstr "ADD [+expirare] mască [motiv]" + +msgid "ADD {CHAN|EMAIL|NICK|PASSWORD|REGISTER} [+expiry] entry reason" +msgstr "ADD {CHAN|EMAIL|NICK|PASSWORD|REGISTER} [+expirare] intrare motiv" msgid "ADDIP server.name ip" msgstr "ADDIP nume.server ip" @@ -1349,9 +1404,6 @@ msgstr "Contul %s a atins deja numărul maxim de identificări simultane (%u). msgid "Account registered" msgstr "Cont înregistrat" -msgid "Accounts can not be registered right now. Please try again later." -msgstr "Nu pot fi înregistrate conturi în acest moment. Vă rugăm încercați mai târziu." - #, c-format msgid "Accounts that are not used anymore are subject to the automatic expiration, i.e. they will be deleted after %s if not used." msgstr "Conturile care nu mai sunt utilizate expiră automat, adică vor fi radiate după %s dacă nu sunt folosite." @@ -1425,8 +1477,17 @@ msgid "Additionally, Services Operators with the nickserv/resend permission ca msgstr "În plus, Operatorii de Servicii cu permisiunea nickserv/resend pot specifica un pseudonim pentru a retrimite un mesaj email de confirmare pentru un alt cont." #, c-format -msgid "Additionally, if fantasy is enabled fantasy commands can be executed by prefixing the command name with one of the following characters: %s" -msgstr "În plus, dacă este activată fantezia, comenzile fanteziste pot fi executate prin prefixarea numelui comenzii cu unul dintre următoarele caractere: %s" +msgid "Additionally, if fantasy is enabled fantasy commands can be executed by prefixing the command name with one of the following fantasy prefixes: %s" +msgstr "În plus, dacă este activată fantezia, comenzile fanteziste pot fi executate prin prefixarea numelui comenzii cu unul dintre următoarele prefixe de fantezie: %s" + +msgid "Adds a mode lock on the moderated, no external messages, topic lock flag modes as well as a ban on *!*@*.example.com." +msgstr "Adaugă o încuiere de mod pentru modurile moderat, fără mesaje externe, încuierea subiectului, precum și o blocare pentru *!*@*.exemplu.ro." + +msgid "Adds the specified fingerprint to the certificate list of nickname." +msgstr "Adaugă amprenta digitală specificată la lista de certificate a pseudonimului." + +msgid "Adds your current fingerprint to your certificate list." +msgstr "Adaugă amprenta digitală curentă la lista de certificate a dumneavoastră." #, c-format msgid "All O:lines of %s have been reset." @@ -1459,8 +1520,15 @@ msgstr "Toate misivele pentru canalul %s au fost șterse." msgid "All modes cleared on %s." msgstr "Toate modurile au fost golite în canalul %s." -msgid "All new accounts must be validated by an administrator. Please wait for your registration to be confirmed." -msgstr "Toate conturile noi trebuie să fie validate manual de un administrator. Vă rugăm așteptați confirmarea înregistrării dumneavoastră." +msgid "All new accounts must be confirmed by an administrator. Please wait for your registration to be confirmed." +msgstr "Toate conturile noi trebuie să fie confirmate de un administrator. Vă rugăm așteptați confirmarea înregistrării dumneavoastră." + +msgid "All new accounts must be confirmed. To confirm your account, follow the instructions that were emailed to you." +msgstr "Toate conturile noi trebuie să fie confirmate. Pentru a confirma contul dumneavoastră, urmați instrucțiunile care v-au fost trimise prin email." + +#, c-format +msgid "All new accounts must be confirmed. To confirm your account, type %s." +msgstr "Toate conturile noi trebuie să fie confirmate. Pentru a confirma contul dumneavoastră, tastați %s." msgid "All of your memos have been deleted." msgstr "Toate misivele dumneavoastră au fost șterse." @@ -1575,7 +1643,7 @@ msgid "Allowed to view the access list" msgstr "Permite a vizualiza lista de accese" msgid "Allows Services Operators to change modes for any channel. Parameters are the same as for the standard /MODE command. Alternatively, CLEAR may be given to clear all modes on the channel. If CLEARALL is given then all modes, including user status, is removed." -msgstr "Permite Operatorilor de Servicii să schimbe moduri pentru orice canal. Parametrii sunt aceiași ca și pentru comanda standard /MODE. Alternativ, se poate da CLEAR pentru a goli toate modurile din canal. Dacă se dă CLEARALL, atunci toate modurile, inclusiv statutul utilizatorului, sunt înlăturate." +msgstr "Permite Operatorilor de Servicii să schimbe moduri pentru orice canal. Parametrii sunt aceiași ca și pentru comanda standard /MODE. Alternativ, se poate da CLEAR pentru a goli toate modurile din canal. Dacă se dă CLEARALL, atunci toate modurile, inclusiv starea utilizatorului, sunt înlăturate." msgid "Allows Services Operators to change modes for any user. Parameters are the same as for the standard /MODE command." msgstr "Permite Operatorilor de Servicii să schimbe moduri pentru orice utilizator. Parametrii sunt aceiași ca și pentru comanda standard /MODE." @@ -1756,16 +1824,8 @@ msgstr "" msgid "Allows you to change and view Services Operators. Note that operators removed by this command but are still set in the configuration file are not permanently affected by this." msgstr "Vă permite să schimbați și să vizualizați Operatorii de Servicii. Rețineți că Operatorii înlăturați de această comandă, dar care se află încă setați în fișierul de configurare, nu sunt afectați permanent de aceasta." -msgid "" -"Allows you to change and view configuration settings. Settings changed by this command are temporary and will not be reflected back into the configuration file, and will be lost if Anope is shut down, restarted, or the configuration is reloaded.\n" -"\n" -"Example:\n" -" MODIFYnickservregdelay15m" -msgstr "" -"Vă permite să modificați și să vizualizați setările de configurare. Setările schimbate prin această comandă sunt temporare și nu se vor reflecta în fișierul de configurare. Aceste modificări vor fi pierdute dacă Anope este oprit, repornit, ori dacă se reîncarcă configurarea.\n" -"\n" -"Exemplu:\n" -" MODIFYnickservregdelay15m" +msgid "Allows you to change and view configuration settings. Settings changed by this command are temporary and will not be reflected back into the configuration file, and will be lost if Anope is shut down, restarted, or the configuration is reloaded." +msgstr "Vă permite să modificați și să vizualizați setările de configurare. Setările schimbate prin această comandă sunt temporare și nu se vor reflecta în fișierul de configurare. Aceste modificări vor fi pierdute dacă Anope este oprit, repornit, ori dacă se reîncarcă configurarea." msgid "Allows you to choose the way services are communicating with the given user. With MSG set, services will use messages, else they'll use notices." msgstr "Vă permite să alegeți metoda prin care serviciile comunică cu utilizatorul precizat. Cu MSG setat, serviciile vor folosi mesaje, altfel vor folosi notificări." @@ -1782,11 +1842,11 @@ msgstr "Vă permite să deconectați un utilizator din rețea. Parametrii sunt a #, c-format msgid "Allows you to prevent certain pieces of information from being displayed when someone does a %sINFO on the nick. You can hide the email address (EMAIL), last seen user@host mask (MASK), the services access status (STATUS) and last quit message (QUIT). The second parameter specifies whether the information should be displayed (OFF) or hidden (ON)." -msgstr "Vă permite să împiedicați afișarea anumitor informații atunci când cineva utilizează %sINFO asupra pseudonimului. Puteți ascunde adresa de email (EMAIL), ultima mască utilizator@gazdă văzută (MASK), statutul accesului la servicii (STATUS) și ultimul mesaj de plecare din rețea (QUIT). Al doilea parametru specifică dacă informațiile ar trebui afișate (OFF) sau ascunse (ON)." +msgstr "Vă permite să împiedicați afișarea anumitor informații atunci când cineva utilizează %sINFO asupra pseudonimului. Puteți ascunde adresa de email (EMAIL), ultima mască utilizator@gazdă văzută (MASK), starea accesului la servicii (STATUS) și ultimul mesaj de plecare din rețea (QUIT). Al doilea parametru specifică dacă informațiile ar trebui afișate (OFF) sau ascunse (ON)." #, c-format msgid "Allows you to prevent certain pieces of information from being displayed when someone does a %sINFO on your nick. You can hide your email address(EMAIL), last seen user@host mask (MASK), your services access status (STATUS) and last quit message (QUIT). The second parameter specifies whether the information should be displayed (OFF) or hidden (ON)." -msgstr "Vă permite să împiedicați afișarea anumitor informații atunci când cineva utilizează %sINFO asupra pseudonimului dumneavoastră. Vă puteți ascunde adresa de email (EMAIL), ultima mască utilizator@gazdă văzută (MASK), statutul accesului la servicii (STATUS) și ultimul mesaj de plecare din rețea (QUIT). Al doilea parametru specifică dacă informațiile ar trebui afișate (OFF) sau ascunse (ON)." +msgstr "Vă permite să împiedicați afișarea anumitor informații atunci când cineva utilizează %sINFO asupra pseudonimului dumneavoastră. Vă puteți ascunde adresa de email(EMAIL), ultima mască utilizator@gazdă văzută (MASK), starea accesului la servicii (STATUS) și ultimul mesaj de plecare din rețea (QUIT). Al doilea parametru specifică dacă informațiile ar trebui afișate (OFF) sau ascunse (ON)." #, c-format msgid "Allows you to see %s information about a channel or a bot" @@ -1823,9 +1883,6 @@ msgstr "Atribuie o pagină web contului dumneavoastră" msgid "Associate a greet message with your nickname" msgstr "Atribuie un mesaj de întâmpinare pseudonimului dumneavoastră" -msgid "Associate an email address with the channel" -msgstr "Atribuie o adresă de email unui canal" - msgid "Associate an email address with your nickname" msgstr "Atribuie o adresă de email pseudonimului dumneavoastră" @@ -2139,11 +2196,13 @@ msgstr "Schimbă pseudonimul de afișare folosit pentru a face refire la contul msgid "Changes the founder of a channel. The new nickname must be a registered one." msgstr "Schimbă fondatorul unui canal. Noul pseudonim trebuie să fie unul înregistrat." -msgid "Changes the language services uses when sending messages to the given user (for example, when responding to a command they send). language should be chosen from the following list of supported languages:" -msgstr "Schimbă limba folosită de servicii pentru a trimite mesaje către utilizatorul precizat (spre exemplu, când li se răspunde unei comenzi). Limba ar trebui să fie aleasă din următoarea listă de limbi acceptate, după cum urmează:" +#, c-format +msgid "Changes the language services uses when sending messages to the given user (for example, when responding to a command they send). If language is not specified the default (%s) will be used. Otherwise, language should be chosen from the following list of supported languages:" +msgstr "Schimbă limba folosită de servicii pentru a trimite mesaje către utilizatorul precizat (spre exemplu, când li se răspunde unei comenzi). Dacă limba nu este specificată, va fi utilizată valoarea implicită (%s). În caz contrar limba ar trebui să fie aleasă din următoarea listă de limbi acceptate după cum urmează:" -msgid "Changes the language services uses when sending messages to you (for example, when responding to a command you send). language should be chosen from the following list of supported languages:" -msgstr "Schimbă limba folosită de servicii pentru a vă trimite mesaje dumneavoastră (spre exemplu, când vi se răspunde unei comenzi). Limba ar trebui să fie aleasă din următoarea listă de limbi acceptate, după cum urmează:" +#, c-format +msgid "Changes the language services uses when sending messages to you (for example, when responding to a command you send). If language is not specified the default (%s) will be used. Otherwise, language should be chosen from the following list of supported languages:" +msgstr "Schimbă limba folosită de servicii pentru a vă trimite mesaje dumneavoastră (spre exemplu, când vi se răspunde unei comenzi). Dacă limba nu este specificată, va fi utilizată valoarea implicită (%s). În caz contrar limba ar trebui să fie aleasă din următoarea listă de limbi acceptate după cum urmează:" msgid "Changes the password used to identify as the nick's owner." msgstr "Schimbă parola folosită pentru identificarea drept proprietar(ă) a pseudonimului." @@ -2151,14 +2210,17 @@ msgstr "Schimbă parola folosită pentru identificarea drept proprietar(ă) a ps msgid "Changes the password used to identify you as the nick's owner." msgstr "Schimbă parola folosită pentru a vă identifica drept proprietar(ă) a pseudonimului." +msgid "Changes the registration delay to 15 minutes." +msgstr "Modifică întârzierea înregistrării la 15 minute." + msgid "Changes the successor of a channel. If the founder's nickname expires or is dropped while the channel is still registered, the successor will become the new founder of the channel. The successor's nickname must be a registered one. If there's no successor set, then the first nickname on the access list (with the highest access, if applicable) will become the new founder, but if the access list is empty, the channel will be dropped." msgstr "Schimbă succesorul unui canal. Dacă pseudonimul fondatorului expiră sau este radiat în timp ce canalul este încă înregistrat, succesorul va deveni noul fondator al canalului. Pseudonimul succesorului trebuie să fie unul înregistrat. Dacă nu este stabilit un succesor, atunci primul pseudonim din lista de accese (cu cel mai mare acces, dacă este cazul) va deveni noul fondator, dar dacă lista de accese este goală, atunci canalul va fi radiat." -msgid "Changes the timezone services uses when sending messages to the given user (for example, when responding to a command they send). timezone should be chosen from an entry in one of the supported timezone regions:" -msgstr "Schimbă fusul orar pe care îl folosesc serviciile atunci când trimit mesaje către utilizatorul precizat (de exemplu, când se răspunde la o comandă primită). Fusul orar trebuie ales dintr-una dintre regiunile de fus orar acceptate după cum urmează:" +msgid "Changes the timezone services uses when sending messages to the given user (for example, when responding to a command they send). If timezone is not specified the default (UTC) will be used. Otherwise, timezone should be chosen from an entry in one of the supported timezone regions:" +msgstr "Schimbă fusul orar pe care îl folosesc serviciile atunci când trimit mesaje către utilizatorul precizat (de exemplu, când li se răspunde la o comandă). Dacă nu este specificat un fus orar, se va utiliza ora implicită (UTC). În caz contrar, fusul orar trebuie ales dintr-una dintre regiunile de fus orar acceptate după cum urmează:" -msgid "Changes the timezone services uses when sending messages to you (for example, when responding to a command you send). timezone should be chosen from an entry in one of the supported timezone regions:" -msgstr "Schimbă fusul orar pe care îl folosesc serviciile atunci când vă trimit mesaje dumneavoastră (de exemplu, când vi se răspunde la o comandă). Fusul orar trebuie ales dintr-una dintre regiunile de fus orar acceptate după cum urmează:" +msgid "Changes the timezone services uses when sending messages to you (for example, when responding to a command you send). If timezone is not specified the default (UTC) will be used. Otherwise, timezone should be chosen from an entry in one of the supported timezone regions:" +msgstr "Schimbă fusul orar pe care îl folosesc serviciile atunci când vă trimit mesaje dumneavoastră (de exemplu, când vi se răspunde la o comandă). Dacă nu este specificat un fus orar, se va utiliza ora implicită (UTC). În caz contrar, fusul orar trebuie ales dintr-una dintre regiunile de fus orar acceptate după cum urmează:" msgid "Changes when you will be notified about new memos (only for nicknames)" msgstr "Schimbă momentele când veți fi notificat(ă) despre noile misive (doar pentru pseudonime)" @@ -2312,6 +2374,9 @@ msgstr "Verifică dacă _ultima_ misivă expediată pseudonimului a fost citit msgid "Cleared info from %s." msgstr "Informațiile din %s au fost golite." +msgid "Clears all extended bans that start with channel:." +msgstr "Curăță toate blocările extinse care pornesc cu canalul:" + msgid "Colors kicker" msgstr "Izgonire la culori" @@ -2482,7 +2547,10 @@ msgid "Current AKILL list:" msgstr "Lista AKILL curentă este după cum urmează:" msgid "Current Session Limit Exception list:" -msgstr "Lista de excepții curentă privind limita de sesiuni este după cum urmează:" +msgstr "Lista curentă de excepții privind limita de sesiuni este după cum urmează:" + +msgid "Current host offer list:" +msgstr "Lista curentă de oferte pentru gazde este după cum urmează:" msgid "Current module list:" msgstr "Lista curentă de module este după cum urmează:" @@ -2506,6 +2574,12 @@ msgstr "Utilizatori curenți: %zu (%zu operatori)" msgid "DEL entry-num" msgstr "DEL număr-intrare" +msgid "DEL fingerprint" +msgstr "DEL amprentă-digitală" + +msgid "DEL nickname fingerprint" +msgstr "DEL pseudonim amprentă-digitală" + msgid "DEL oper" msgstr "DEL Operator" @@ -2519,7 +2593,7 @@ msgid "DEL [nickname] fingerprint" msgstr "DEL [pseudonim] amprentă-digitală" msgid "DEL {mask | entry-num | list | id}" -msgstr "DEL {mască | număr-intrare | listă | id}" +msgstr "DEL {mască | număr-intrare | listă | identificator}" msgid "DEL {mask | entry-num | list}" msgstr "DEL {mască | număr-intrare | listă}" @@ -2530,8 +2604,11 @@ msgstr "DEL {pseudonim|mască}" msgid "DEL {num | ALL}" msgstr "DEL {număr | ALL}" -msgid "DEL {NICK|CHAN|EMAIL|REGISTER} entry" -msgstr "DEL {NICK|CHAN|EMAIL|REGISTER} intrare" +msgid "DEL {vhost | entry-num | list}" +msgstr "DEL {gazdă-virtuală | număr-intrare | listă}" + +msgid "DEL {CHAN|EMAIL|NICK|PASSWORD|REGISTER} entry" +msgstr "DEL {CHAN|EMAIL|NICK|PASSWORD|REGISTER} intrare" msgid "DELIP server.name ip" msgstr "DELIP nume.server ip" @@ -2715,44 +2792,34 @@ msgstr "A fost înlăturat(ă) %s din lista %s." msgid "Deleted %s from the AKILL list." msgstr "A fost înlăturat(ă) %s din lista AKILL." +#, c-format +msgid "Deleted %s from the host offer list." +msgstr "A fost înlăturat(ă) %s din lista de oferte pentru gazde." + #, c-format msgid "Deleted %u entry from your message queue." msgid_plural "Deleted %u entries from your message queue." msgstr[0] "%u intrare a fost ștearsă din coada de mesaje." msgstr[1] "%u intrări au fost șterse din coada de mesaje." +#, c-format +msgid "Deleted %zu entry from the host offer list." +msgid_plural "Deleted %zu entries from the host offer list." +msgstr[0] "%zu intrare a fost înlăturată din lista de oferte pentru gazde." +msgstr[1] "%zu intrări au fost înlăturate din lista de oferte pentru gazde." + #, c-format msgid "Deleted info from %s." msgstr "Informațiile din %s au fost șterse." -msgid "" -"Deletes the specified memo or memos. You can supply multiple memo numbers or ranges of numbers instead of a single number, as in the second example below.\n" -"\n" -"If LAST is given, the last memo will be deleted.\n" -"\n" -"If ALL is given, deletes all of your memos.\n" -"\n" -"Examples:\n" -"\n" -" DEL1\n" -" Deletes your first memo.\n" -"\n" -" DEL2-5,7-9\n" -" Deletes memos numbered 2 through 5 and 7 through 9." -msgstr "" -"Șterge misiva sau misivele specificate. Puteți furniza mai multe numere de misive, sau intervale de numere în loc de un singur număr, ca în al doilea exemplu de mai jos.\n" -"\n" -"Dacă LAST este specificat, atunci ultima misivă este ștearsă.\n" -"\n" -"Dacă ALL este specificat, atunci sunt șterse toate misivele.\n" -"\n" -"Exemple:\n" -"\n" -" DEL1\n" -" Șterge prima misivă a dumneavoastră.\n" -"\n" -" DEL2-5,7-9\n" -" Șterge misivele numerotate de la 2 la 5 și de la 7 la 9." +msgid "Deletes all of your memos." +msgstr "Șterge toate misivele dumneavoastră." + +msgid "Deletes memos numbered 2 through 5 and 7 through 9." +msgstr "Șterge misivele numerotate de la 2 la 5 și de la 7 la 9." + +msgid "Deletes the specified memo or memos. You can supply multiple memo numbers or ranges of numbers instead of a single number, as in the second example below." +msgstr "Șterge misiva sau misivele specificate. Puteți oferi mai multe numere de misive ori intervale de numere în locul unui singur număr, precum în al doilea exemplu de mai jos." msgid "Deletes the vhost assigned to the given nick from the database." msgstr "Șterge gazda virtuală atribuită pseudonimului precizat din baza de date." @@ -2763,6 +2830,12 @@ msgstr "Șterge gazda virtuală pentru toate pseudonimele dintr-un cont" msgid "Deletes the vhost for all nicks in the same account as that of the given nick." msgstr "Șterge gazda virtuală pentru toate pseudonimele din același cont cu cel al pseudonimului precizat." +msgid "Deletes your first memo." +msgstr "Șterge prima misivă a dumneavoastră." + +msgid "Deletes your last memo." +msgstr "Șterge ultima misiva a dumneavoastră." + #, c-format msgid "Depooled %s." msgstr "%s a fost decolectivizat." @@ -2806,6 +2879,12 @@ msgstr "S-au afișat înregistrările de la %d la %d." msgid "Displayed records matching key %s (count: %d)." msgstr "S-au afișat înregistrările corespunzând cheii %s (număr: %d)." +msgid "Displays all of your memos." +msgstr "Afișează toate misivele dumneavoastră." + +msgid "Displays any new memos." +msgstr "Afișează noile misive." + msgid "Displays information about a given nickname" msgstr "Afișează informații despre un pseudonim specificat" @@ -2815,9 +2894,18 @@ msgstr "Afișează informații despre pseudonimul specificat, cum ar fi propriet msgid "Displays information about your memos" msgstr "Afișează informații despre misivele dumneavoastră" +msgid "Displays memos numbered 2 through 5 and 7 through 9." +msgstr "Afișează misivele numerotate de la 2 la 7 și de la 7 la 9." + msgid "Displays one or more vhost entries" msgstr "Afișează una sau mai multe intrări de gazde virtuale" +msgid "Displays the current certificate list of nickname as well as the details about who added each entry and when they added it." +msgstr "Afișează lista curentă de certificate a pseudonimului precum și detalii despre cine a adăugat fiecare intrare și când a adăugat-o." + +msgid "Displays the current certificate list of nickname." +msgstr "Afișează lista curentă de certificate a pseudonimului." + msgid "Displays the top 10 users of a channel" msgstr "Afișează top 10 utilizatori ai unui canal" @@ -2839,6 +2927,15 @@ msgstr "Afișează statisticile canalului dumneavoastră" msgid "Displays your Global Stats" msgstr "Afișează statisticile globale ale dumneavoastră" +msgid "Displays your current certificate list as well the details about who added each entry and when they added it." +msgstr "Afișează certificatul curent al dumneavoastră precum și detalii despre cine a adăugat fiecare intrare și când a adăugat-o." + +msgid "Displays your current certificate list." +msgstr "Afișează lista de certificate curente ale dumneavoastră." + +msgid "Displays your last memo." +msgstr "Afișează ultima misivă a dumneavoastră." + msgid "Don't use AMSGs!" msgstr "Nu folosiți AMSG!" @@ -2908,11 +3005,11 @@ msgstr "Activat" #, c-format msgid "" -"Enables or disables fantasy mode on a channel. When it is enabled, users will be able to use fantasy commands on a channel when prefixed with one of the following fantasy characters: %s\n" +"Enables or disables fantasy mode on a channel. When it is enabled, users will be able to use fantasy commands on a channel when prefixed with one of the following fantasy prefixes: %s\n" "\n" "Note that users wanting to use fantasy commands MUST have enough access for both the FANTASY privilege and the command they are executing." msgstr "" -"Activează sau dezactivează modul fantezie într-un canal. Când acesta este activat, utilizatorii vor putea folosi comenzile fanteziste într-un canal, atunci când au ca prefix unul dintre următoarele caractere de fantezie: %s\n" +"Activează sau dezactivează modul fantezie într-un canal. Când acesta este activat, utilizatorii vor putea folosi comenzile fanteziste într-un canal, atunci când au ca prefix unul dintre următoarele prefixe de fantezie: %s\n" "\n" "Rețineți că utilizatorii care doresc să utilizeze comenzile fanteziste TREBUIE să aibă acces suficient atât pentru privilegiul FANTASY, cât și pentru comanda pe care o execută." @@ -2927,7 +3024,7 @@ msgstr "Activează sau dezactivează modul de protecție voce într-un canal. #, c-format msgid "Enables or disables %s's autoop feature for a channel. When disabled, users who join the channel will not automatically gain any status from %s." -msgstr "Activează sau dezactivează operarea automată de către %s într-un canal. Când este dezactivată, utilizatorii care se alătură canalului nu vor obține automat niciun statut de la %s." +msgstr "Activează sau dezactivează operarea automată de către %s într-un canal. Când este dezactivată, utilizatorii care se alătură canalului nu vor obține automat nicio stare de la %s." msgid "Enables or disables keepmodes for the given channel. If keep modes is enabled, services will remember modes set on the channel and attempt to re-set them the next time the channel is created." msgstr "Activează sau dezactivează păstrarea modurilor pentru canalul precizat. Dacă este activată opțiunea de păstrare a modurilor, serviciile vor reține modurile setate în canal și vor încerca să le reașeze data viitoare când canalul este creat." @@ -2949,7 +3046,7 @@ msgstr "" #, c-format msgid "Enables or disables the peace option for a channel. When peace is set, a user won't be able to kick, ban or remove a channel status of a user that has a level superior or equal to theirs via %s commands." -msgstr "Activează sau dezactivează opțiunea de pace într-un canal. Când opțiunea de pace este activă, un utilizator nu va putea izgoni, bloca sau înlătura statutul în canal al altui utilizator care are un nivel superior sau egal cu al său prin comenzile %s." +msgstr "Activează sau dezactivează opțiunea de pace într-un canal. Când opțiunea de pace este activă, un utilizator nu va putea izgoni, bloca sau înlătura starea în canal a altui utilizator care are un nivel superior sau egal cu al său prin comenzile %s." msgid "Enables or disables the private option for a channel." msgstr "Activează sau dezactivează opțiunea de privat într-un canal." @@ -2961,7 +3058,7 @@ msgid "Enables or disables the secure founder option for a channel. When secu msgstr "Activează sau dezactivează opțiunea de fondator securizat într-un canal. Când opțiunea de fondator securizat este activă, doar fondatorul real va avea dreptul să radieze canalul, să schimbe fondatorul și succesorul acestuia; dar nu și cei care au acces la nivel de fondator prin comanda acces/qop." msgid "Enables or disables the secure ops option for a channel. When secure ops is set, users who are not on the access list will not be allowed channel operator status." -msgstr "Activează sau dezactivează opțiunea de operator securizat într-un canal. Când opțiunea de operator securizat este activă, utilizatorii care nu se află în lista de accese nu vor putea avea statut de operator în canal." +msgstr "Activează sau dezactivează opțiunea de operator securizat într-un canal. Când opțiunea de operator securizat este activă, utilizatorii care nu se află în lista de accese nu vor putea avea starea de operator în canal." #, c-format msgid "Enables or disables the topic retention option for a channel. When %s is set, the topic for the channel will be remembered by %s even after the last user leaves the channel, and will be restored the next time the channel is created." @@ -3021,6 +3118,9 @@ msgstr "Sfârșitul listei de interziceri - %zu/%zu intrări afișate." msgid "End of forbid list." msgstr "Sfârșitul listei de interziceri." +msgid "End of host offer list." +msgstr "Sfârșitul listei de oferte pentru gazde." + #, c-format msgid "End of list - %d channels shown." msgstr "Sfârșitul listei - %d canale afișate." @@ -3087,6 +3187,9 @@ msgstr "Eroare! Gazda virtuală este prea lungă, vă rugăm să utilizați un n msgid "Error! The vident is too long, please use an ident shorter than %zu characters." msgstr "Eroare! Identitatea virtuală este prea lungă, vă rugăm utilizați o identitate mai scurtă de %zu caractere." +msgid "Examples:" +msgstr "Exemple:" + #, c-format msgid "Exception for %s has been updated to %d." msgstr "Excepția pentru %s a fost actualizată la %d." @@ -3106,8 +3209,8 @@ msgid "Fantasy" msgstr "Fantezie" #, c-format -msgid "Fantasy commands may be prefixed with one of the following characters: %s" -msgstr "Comenzile fanteziste pot avea ca prefix unul dintre următoarele caractere: %s" +msgid "Fantasy commands may be prefixed with one of the following fantasy prefixes: %s" +msgstr "Comenzile fanteziste pot avea ca prefix unul dintre următoarele prefixe de fantezie: %s" #, c-format msgid "Fantasy mode is now off on channel %s." @@ -3118,7 +3221,10 @@ msgid "Fantasy mode is now on on channel %s." msgstr "Modul fantezie este acum activat în canalul %s." msgid "Find a user's status on a channel" -msgstr "Află statutul unui utilizator într-un canal" +msgstr "Află starea unui utilizator într-un canal" + +msgid "Fingerprint" +msgstr "Amprentă digitală" #, c-format msgid "Fingerprint %s already present on %s's certificate list." @@ -3157,6 +3263,10 @@ msgstr "Lista de interziceri este goală." msgid "Forbid list:" msgstr "Lista de interziceri este după cum urmează:" +#, c-format +msgid "Forbid on %s can not be removed as it is from a file." +msgstr "Interzicerea pentru %s nu poate fi înlăturată deoarece provine dintr-un fișier." + #, c-format msgid "Forbid on %s was not found." msgstr "Interzicerea pentru %s nu a fost găsită." @@ -3197,11 +3307,11 @@ msgstr "Utilizatorul fantomă folosind pseudonimul dumneavoastră a fost deconec #, c-format msgid "Gives %s status to the selected nicks on a channel. If nick is not given, it will %s you." -msgstr "Oferă statutul de %s pseudonimului selectat într-un canal. Dacă pseudonimul nu este precizat, atunci veți primi dumneavoastră statutul de %s." +msgstr "Oferă starea de %s pseudonimului selectat într-un canal. Dacă pseudonimul nu este precizat, atunci veți primi dumneavoastră starea de %s." #, c-format msgid "Gives you or the specified nick %s status on a channel" -msgstr "Vă oferă dumneavoastră sau pseudonimului specificat statutul de %s într-un canal" +msgstr "Vă oferă dumneavoastră sau pseudonimului specificat starea de %s într-un canal" msgid "Greet" msgstr "Întâmpinare" @@ -3237,12 +3347,26 @@ msgstr "Ascunde canalul din comanda LIST" msgid "Host" msgstr "Gazdă" +#, c-format +msgid "Host offer %s already exists." +msgstr "Oferta de gazdă %s există deja." + +msgid "Host offer list has been cleared." +msgstr "Lista de oferte pentru gazdă a fost golită." + +msgid "Host offer list is empty." +msgstr "Lista de oferte pentru gazde este goală." + #, c-format msgid "Hosts with at least %d sessions:" msgstr "Gazdele cu cel puțin %d sesiuni sunt după cum urmează:" +#, c-format +msgid "I have not seen %s." +msgstr "Nu am văzut pe %s." + msgid "ID" -msgstr "ID" +msgstr "Identificator" msgid "INFO [type]" msgstr "INFO [tip]" @@ -3365,11 +3489,14 @@ msgstr "LIMIT impus de " msgid "LIMIT enforced on %s, %zu users removed." msgstr "LIMIT impus pentru %s, %zu utilizatori înlăturați." +msgid "LIST nickname" +msgstr "LIST pseudonim" + msgid "LIST threshold" msgstr "LIST de prag" msgid "LIST [mask | list | id]" -msgstr "LIST [mască | listă | id]" +msgstr "LIST [mască | listă | identificator]" msgid "LIST [mask | list]" msgstr "LIST [mască | listă]" @@ -3377,6 +3504,9 @@ msgstr "LIST [mască | listă]" msgid "LIST [nickname]" msgstr "LIST [pseudonim]" +msgid "LIST [vhost-mask | entry-num | list]" +msgstr "LIST [mască-virtuală | număr-intrare | listă]" + #, c-format msgid "Language changed to %s." msgstr "Limba a fost schimbată în %s." @@ -3385,9 +3515,6 @@ msgstr "Limba a fost schimbată în %s." msgid "Language for %s changed to %s." msgstr "Limba pentru %s a fost schimbată în %s." -msgid "Last mask" -msgstr "Ultima mască" - #, c-format msgid "Last memo to %s has been cancelled." msgstr "Ultima misivă către %s a fost anulată." @@ -3444,8 +3571,8 @@ msgid "List channels you have access on" msgstr "Listează canalele la care aveți acces" #, c-format -msgid "List for mode %c is full." -msgstr "Lista pentru modul %c este plină." +msgid "List for modes %s is full." +msgstr "Lista pentru moduri %s este plină." msgid "List loaded modules" msgstr "Listează modulele încărcate" @@ -3461,12 +3588,57 @@ msgstr "Lista pseudonimelor care aparțin lui %s este după cum urmează:" msgid "List of nicknames belonging to your account:" msgstr "Lista pseudonimelor aparținând contului dumneavoastră este după cum urmează:" +msgid "List or take a vhost from the host offer list" +msgstr "Listați sau luați o gazdă virtuală din lista de oferte pentru gazde" + +#, c-format +msgid "" +"List or take an offered vhost.\n" +"\n" +"With no parameters, a user@host or host mask, an entry number, or a list (e.g. 1-3,5) offered vhosts will be shown. If ALL is specified vhosts that can not be taken will be labelled with [Invalid] instead of being omitted.\n" +"The offered vhosts may contain template variables. The supported template variables are:\n" +" {account} - Your current account.\n" +" {network} - The name of this IRC network.\n" +" {nick} - Your current nickname.\n" +" {regdate} - The YYYY-MM-DD date at which your nick was registered.\n" +" {regepoch} - The UNIX time at which your nick was registered.\n" +"\n" +"With %sTAKE an offered vhost will be applied. You must specify the offered template variable or the entry number for the offered vhost you want to use. Once a vhost is taken you can not take another one for %s." +msgstr "" +"Listați sau luați o gazdă virtuală oferită.\n" +"Fără parametri, fără un utilizator@gazdă sau fără masca gazdei, fără un număr de intrare ori fără o listă (de exemplu: 1-3,5), vor fi afișate gazdele virtuale oferite. Dacă se specifică ALL, gazdele virtuale care nu pot fi preluate vor fi etichetate cu [Invalid] în loc să fie omise. Gazdele virtuale oferite pot conține variabile șablon. Variabilele șablon acceptate sunt:\n" +" {account} - Contul curent al dumneavoastră.\n" +" {network} - Numele acestei rețele IRC.\n" +" {nick} - Pseudonimul curent al dumneavoastră.\n" +" {regdate} - Data AAAA-LL-ZZ la care a fost înregistrat pseudonimul dumneavoastră.\n" +" {regepoch} - Timpul în format UNIX la care a fost înregistrat pseudonimul dumneavoastră.\n" +"\n" +"Cu %sTAKE se va aplica o gazdă virtuală oferită. Trebuie să specificați variabila șablon oferită sau numărul de intrare pentru gazda virtuală oferită pe care doriți să o utilizați. Odată ce un vhost este ocupat, nu mai puteți lua altul timp de %s." + msgid "List the options" msgstr "Listează opțiunile" msgid "List your memos" msgstr "Listează misivele dumneavoastră" +msgid "Lists AKILL entries numbered 2 through 5 and 7 through 9." +msgstr "Listează intrările AKILL numerotate de la 2 la 5 și de la 7 la 9." + +msgid "Lists SNLINE entries numbered 2 through 5 and 7 through 9." +msgstr "Listează intrările SNLINE numerotate de la 2 la 5 și de la 7 la 9." + +msgid "Lists SQLINE entries numbered 2 through 5 and 7 through 9." +msgstr "Listează intrările SQLINE numerotate de la 2 la 5 și de la 7 la 9." + +msgid "Lists access entries numbered 2 through 5 and 7 through 9." +msgstr "Listează intrările de accese numerotate de la 2 la 5 și de la 7 la 9." + +msgid "Lists access entries on #channel numbered 2 through 5 and 7 through 9." +msgstr "Listează intrările de accese în #channel numerotate de la 2 la 5 și de la 7 la 9." + +msgid "Lists access entries on #channel that match *nick*." +msgstr "Listează intrările de accese în #channel care corespund *nick*." + msgid "" "Lists all available bots on this network.\n" "\n" @@ -3515,78 +3687,56 @@ msgid "" "\n" "Note that a preceding '#' specifies a range, channel names are to be written without '#'.\n" "\n" -"If the SUSPENDED or NOEXPIRE options are given, only channels which, respectively, are SUSPENDED or have the NOEXPIRE flag set will be displayed. If multiple options are given, all channels matching at least one option will be displayed. Note that these options are limited to Services Operators.\n" -"\n" -"Examples:\n" -"\n" -" LIST*anope*\n" -" Lists all registered channels with anope in their\n" -" names (case insensitive).\n" -"\n" -" LIST*NOEXPIRE\n" -" Lists all registered channels which have been set to not expire.\n" -"\n" -" LIST #51-100\n" -" Lists all registered channels within the given range (51-100)." +"If the SUSPENDED or NOEXPIRE options are given, only channels which, respectively, are SUSPENDED or have the NOEXPIRE flag set will be displayed. If multiple options are given, all channels matching at least one option will be displayed. Note that these options are limited to Services Operators." msgstr "" "Listează toate canalele înregistrate care corespund modelului specificat. Canalele cu opțiunea PRIVATE setată vor fi afișate numai Operatorilor de Servicii cu acces corespunzător. Canalele cu opțiunea NOEXPIRE setată vor avea ca prefix un ! pentru ca Operatorii de Servicii să le poată vedea.\n" "\n" "Rețineți că precedarea cu '#' specifică un interval, numele canalelor trebuie scrise fără '#'.\n" "\n" -"Dacă sunt precizate opțiunile SUSPENDED sau NOEXPIRE, vor fi afișate doar canalele care sunt SUSPENDED sau care au stegulețul NOEXPIRE setat. Dacă sunt specificate mai multe opțiuni, vor fi afișate toate canalele care corespund cel puțin uneia dintre opțiuni. Rețineți că aceste opțiuni sunt limitate la Operatorii de Servicii.\n" -"\n" -"Exemple:\n" -"\n" -" LIST*anope*\n" -" Listează toate canalele înregistrate cu anope în numele lor (fără distincție între majuscule și minuscule).\n" -"\n" -" LIST*NOEXPIRE\n" -" Listează toate canalele înregistrate care au fost setate să nu expire.\n" -"\n" -" LIST #51-100\n" -" Listează toate canalele înregistrate din intervalul menționat (51-100)." +"Dacă sunt precizate opțiunile SUSPENDED sau NOEXPIRE, vor fi afișate doar canalele care sunt SUSPENDED sau care au stegulețul NOEXPIRE setat. Dacă sunt specificate mai multe opțiuni, vor fi afișate toate canalele care corespund cel puțin uneia dintre opțiuni. Rețineți că aceste opțiuni sunt limitate la Operatorii de Servicii." + +msgid "Lists all registered channels that have been set to not expire." +msgstr "Listează toate canalele înregistrate care au fost setate să nu expire." + +msgid "Lists all registered channels that have been suspended." +msgstr "Listează toate canalele înregistrate care au fost suspendate." + +msgid "Lists all registered channels with anope in their name (case insensitive). " +msgstr "Listează toate canalele înregistrate cu anope în numele lor (fără a ține cont de majuscule ori minuscule)." + +msgid "Lists all registered channels within the given range (51-100)." +msgstr "Listează toate canalele înregistrate în intervalul menționat (51-100)." msgid "" "Lists all registered nicknames which match the given pattern, in nick!user@host format. Nicks with the PRIVATE option set will only be displayed to Services Operators with the proper access. Nicks with the NOEXPIRE option set will have a ! prefixed to the nickname for Services Operators to see.\n" "\n" "Note that a preceding '#' specifies a range.\n" "\n" -"If the SUSPENDED, UNCONFIRMED or NOEXPIRE options are given, only nicks which, respectively, are SUSPENDED, UNCONFIRMED or have the NOEXPIRE flag set will be displayed. If multiple options are given, all nicks matching at least one option will be displayed. Note that these options are limited to Services Operators.\n" -"\n" -"Examples:\n" -"\n" -" LIST *!joeuser@foo.com\n" -" Lists all registered nicks owned by joeuser@foo.com.\n" -"\n" -" LIST *Bot*!*@*\n" -" Lists all registered nicks with Bot in their\n" -" names (case insensitive).\n" -"\n" -" LIST * NOEXPIRE\n" -" Lists all registered nicks which have been set to not expire.\n" -"\n" -" LIST #51-100\n" -" Lists all registered nicks within the given range (51-100)." +"If the DISPLAY, NOEXPIRE, SUSPENDED, or UNCONFIRMED options are given only nicks which, respectively, are display nicks, will not expire, are suspended, or are unconfirmed will be shown. If multiple options are given, nicks must match every option to be shown. Note that these options are limited to Services Operators." msgstr "" "Listează toate pseudonimele înregistrate care corespund modelului precizat, în formatul pseudonim!utilizator@gazdă. Pseudonimele cu opțiunea PRIVATE setată vor fi afișate doar Operatorilor de Servicii cu accesul corespunzător. Pseudonimele cu opțiunea NOEXPIRE setată vor avea ca prefix un ! pentru ca Operatorii de Servicii să le poată vedea.\n" "\n" "Rețineți că precedarea cu '#' specifică un interval.\n" "\n" -"Dacă sunt precizate opțiunile SUSPENDED, UNCONFIRMED sau NOEXPIRE, vor fi afișate doar pseudonimele care sunt SUSPENDED, UNCONFIRMED sau au stegulețul NOEXPIRE setat. Dacă sunt specificate mai multe opțiuni, vor fi afișate toate pseudonimele care corespund cu cel puțin o opțiune. Rețineți că aceste opțiuni sunt limitate la Operatorii de Servicii.\n" -"\n" -"Exemple:\n" -"\n" -" LIST *!ion@popescu.com\n" -" Listează toate pseudonimele înregistrate deținute de ion@popescu.com.\n" -"\n" -" LIST *Bot*!*@*\n" -" Listează toate pseudonimele înregistrate cu Bot în numele lor (fără distincție între majuscule și minuscule).\n" -"\n" -" LIST * NOEXPIRE\n" -" Listează toate pseudonimele înregistrate care au fost setate să nu expire.\n" -"\n" -" LIST #51-100\n" -" Listează toate pseudonimele înregistrate în intervalul menționat (51-100)." +"Dacă sunt precizate opțiunile DISPLAY, NOEXPIRE, SUSPENDED sau UNCONFIRMED, vor fi afișate doar pseudonimele care sunt de afișare, nu vor expira, sunt suspendate sau sunt neconfirmate. Dacă sunt oferite mai multe opțiuni, pseudonimele trebuie să corespundă fiecărei opțiuni pentru a fi afișate. Rețineți că aceste opțiuni sunt limitate la Operatorii de Servicii." + +msgid "Lists all registered nicks that are the display nickname for their account." +msgstr "Listează toate pseudonimele înregistrate care sunt pseudonime de afișare pentru contul lor." + +msgid "Lists all registered nicks that have been set to not expire." +msgstr "Listează toate pseudonimele înregistrate care au fost setate să nu expire." + +msgid "Lists all registered nicks that have been suspended." +msgstr "Listează toate pseudonimele înregistrate care au fost suspendate." + +msgid "Lists all registered nicks that have not been confirmed yet." +msgstr "Listează toate pseudonimele înregistrate care nu au fost încă confirmate." + +msgid "Lists all registered nicks with Bot in their name (case insensitive)." +msgstr "Listează toate pseudonimele înregistrate cu Bot în numele lor (fără a ține cont de majuscule ori minuscule)." + +msgid "Lists all registered nicks within the given range (51-100)." +msgstr "Listează toate pseudonimele în intervalul menționat (51-100)." msgid "Lists all user records" msgstr "Listează toate înregistrările utilizatorilor" @@ -3600,18 +3750,21 @@ msgstr "" "\n" "Dacă este specificat un model, listează doar utilizatorii care corespund acestuia (trebuie să aibă formatul pseudonim!utilizator@gazdă[#nume-real]). Dacă este specificat canalul, sunt listați doar utilizatorii care se află în canalul precizat. Dacă este specificat INVISIBLE, vor fi listați doar utilizatorii cu stegulețul +i." -msgid "" -"Lists any memos you currently have. With NEW, lists only new (unread) memos. Unread memos are marked with a \"*\" to the left of the memo number. You can also specify a list of numbers, as in the example below:\n" -" LIST 2-5,7-9\n" -" Lists memos numbered 2 through 5 and 7 through 9." -msgstr "" -"Listează toate misivele pe care le aveți în prezent. Cu NEW, listează doar misivele noi (necitite). Misivele necitite sunt marcate cu o \"*\" în stânga numărului misivei. De asemenea, puteți specifica o listă de numere, ca în exemplul de mai jos:\n" -" LIST 2-5,7-9\n" -" Listează misivele numerotate de la 2 la 5 și de la 7 la 9." +msgid "Lists any memos you currently have. With NEW, lists only new (unread) memos. Unread memos are marked with a \"*\" to the left of the memo number. You can also specify a list of numbers." +msgstr "Listează toate misivele pe care le aveți în prezent. Cu NEW, listează doar misivele noi (necitite). Misivele necitite sunt marcate cu o \"*\" în stânga numărului misivei. De asemenea, puteți specifica o listă de numere." + +msgid "Lists any new memos." +msgstr "Listează misivele noi." msgid "Lists available bots" msgstr "Listează boții disponibili" +msgid "Lists bad word entries on #channel numbered 2 through 5 and 7 through 9." +msgstr "Listează intrările de cuvinte nepotrivite în #channel numerotate de la 2 la 5 și de la 7 la 9." + +msgid "Lists bad word entries on #channel that match *UwU*." +msgstr "Listează intrările de cuvinte nepotrivite în #channel care corespund *UwU*." + msgid "Lists currently loaded modules." msgstr "Listează modulele încărcate în prezent." @@ -3621,6 +3774,9 @@ msgstr "Listează informații despre canalul înregistrat specificat" msgid "Lists information about the specified registered channel, including its founder, time of registration, last time used, and description. If the user issuing the command has the appropriate access for it, then the successor, last topic set, settings and expiration time will also be displayed when applicable." msgstr "Listează informații despre canalul înregistrat specificat, inclusiv fondatorul său, ora înregistrării, ultima utilizare și descrierea acestuia. Dacă utilizatorul care execută comanda are accesul corespunzător pentru aceasta, atunci când este cazul vor fi afișate și succesorul, ultimul subiect stabilit, setările și timpul de expirare." +msgid "Lists memos numbered 2 through 5 and 7 through 9." +msgstr "Listează misivele numerotate de la 2 la 5 și de la 7 la 9." + msgid "Load a module" msgstr "Încarcă un modul" @@ -3676,37 +3832,15 @@ msgid "" "\n" "The %sLOCK command allows you to add, delete, and view mode locks on a channel. If a mode is locked on or off, services will not allow that mode to be changed. The SET command will clear all existing mode locks and set the new one given, while ADD and DEL modify the existing mode lock.\n" "\n" -"Example:\n" -" %s#channel%sADD+bmnt*!*@*aol*\n" -"\n" -"\n" "The %sSET command allows you to set modes through services. Wildcards * and ? may be given as parameters for list and status modes.\n" "\n" -"Example:\n" -" %s#channelSET+v*\n" -" Sets voice status to all users in the channel.\n" -"\n" -" %s#channelSET-b~c:*\n" -" Clears all extended bans that start with ~c:\n" -"\n" "The %sCLEAR command is an easy way to clear modes on a channel. what may be any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and voices. If what is not given then all basic modes are removed." msgstr "" "Controlează în principal încuierile modurilor în canale și accesul la moduri în canale (care sunt diferite de accesele în canale).\n" "\n" -"Comanda %sLOCK vă permite să adăugați, să ștergeți și să vizualizați blocări de mod într-un canal. Dacă un mod este încuiat sau nu, serviciile nu vor permite schimbarea modului respectiv. Comanda SET va goli toate încuierile de mod existente și va seta pe cea precizată, în timp ce ADD și DEL modifică încuierea de mod existentă.\n" -"\n" -"Exemplu:\n" -" %s#canal%sADD+bmnt*!*@*aol*\n" -"\n" -"\n" -"Comanda %sSET vă permite să setați modurile prin intermediul serviciilor. Caracterele wildcard * și ? pot fi menționate ca parametri pentru modurile de listă și statut.\n" -"\n" -"Exemplu:\n" -" %s#canalSET+v*\n" -" Setează statutul de membru voce pentru toți utilizatorii din canal.\n" +"Comanda %sLOCK vă permite să adăugați, să ștergeți și să vizualizați încuieri de mod într-un canal. Dacă un mod este încuiat sau nu, serviciile nu vor permite schimbarea modului respectiv. Comanda SET va goli toate încuierile de mod existente și va seta pe cea precizată, în timp ce ADD și DEL modifică încuierea de mod existentă.\n" "\n" -" %s#canalSET-b~c:*\n" -" Golește toate blocările extinse care încep cu ~c:\n" +"Comanda %sSET vă permite să setați modurile prin intermediul serviciilor. Caracterele wildcard * și ? pot fi menționate ca parametri pentru modurile de listă și stare.\n" "\n" "Comanda %sCLEAR este o modalitate ușoară de a goli modurile dintr-un canal. ce poate fi orice nume de mod. Exemplele includ blocări, excepții, suprascrieri de invitații, operatori, semi-operatori și membri voce. Dacă ce nu este menționat, atunci toate modurile de bază sunt înlăturate." @@ -3756,7 +3890,7 @@ msgid "" "\n" "The %sADD command adds the given mask to the access list with the given user level; if the mask is already present on the list, its access level is changed to the level specified in the command. The level specified may be a numerical level or the name of a privilege (eg AUTOOP). When a user joins the channel the access they receive is from the highest level entry in the access list." msgstr "" -"Întreține lista de accese într-un canal. Lista de accese specifică căror utilizatori li se permite statutul de operator de canal sau accesul la comenzile %s în canal. Diferite niveluri de utilizator permit accesul la diferite subseturi de privilegii. Orice utilizator înregistrat care nu se află în lista de accese are un nivel de utilizator de 0, iar orice utilizator neînregistrat are un nivel de utilizator de -1.\n" +"Întreține lista de accese într-un canal. Lista de accese specifică căror utilizatori li se permite starea de operator de canal sau accesul la comenzile %s în canal. Diferite niveluri de utilizator permit accesul la diferite subseturi de privilegii. Orice utilizator înregistrat care nu se află în lista de accese are un nivel de utilizator de 0, iar orice utilizator neînregistrat are un nivel de utilizator de -1.\n" "\n" "Comanda %sADD adaugă masca precizată la lista de accese cu nivelul de utilizator precizat; dacă masca este deja prezentă în listă, nivelul său de acces este modificat la nivelul specificat în comandă. Nivelul specificat poate fi un nivel numeric sau numele unui privilegiu (de exemplu AUTOOP). Când un utilizator se alătură canalului, accesul pe care îl primește este cel de la intrarea cu cel mai înalt nivel din lista de accese." @@ -3768,10 +3902,7 @@ msgid "" "\n" "The DEL command removes the given word from the bad words list. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The LIST command displays the bad words list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" #channelLIST2-5,7-9\n" -" Lists bad words entries numbered 2 through 5 and\n" -" 7 through 9.\n" +"The LIST command displays the bad words list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "The CLEAR command clears all entries from the bad words list." msgstr "" @@ -3781,9 +3912,7 @@ msgstr "" "\n" "Comanda DEL înlătură cuvântul precizat din lista de cuvinte nepotrivite. Dacă este furnizată o listă de numere de intrare, acele intrări sunt șterse. (Vezi exemplul pentru LIST de mai jos.)\n" "\n" -"Comanda LIST afișează lista de cuvinte nepotrivite. Dacă este precizată o mască wildcard, vor fi afișate doar intrările care corespund măștii. Dacă este furnizată o listă de numere de intrare, sunt afișate doar acele intrări; de exemplu:\n" -" #canalLIST2-5,7-9\n" -" Listează intrările de cuvinte vulgare numerotate de la 2 la 5 și de la 7 la 9.\n" +"Comanda LIST afișează lista de cuvinte nepotrivite. Dacă este precizată o mască wildcard, vor fi afișate doar intrările care corespund măștii. Dacă este furnizată o listă de numere de intrare, sunt afișate doar acele intrări.\n" "\n" "Comanda CLEAR golește toate intrările din lista de cuvinte nepotrivite." @@ -3833,6 +3962,9 @@ msgstr "Manipulează lista de AKILL" msgid "Manipulate the DefCon system" msgstr "Manipulează sistemul DEFCON" +msgid "Manipulate the host offer list" +msgstr "Manipulează lista de oferte pentru gazde" + msgid "Manipulate the topic of the specified channel" msgstr "Manipulează subiectul canalului specificat" @@ -3904,8 +4036,8 @@ msgid "Method" msgstr "Metodă" #, c-format -msgid "Missing parameter for mode %c." -msgstr "Parametru lipsă pentru modul %c." +msgid "Missing parameter for modes %s." +msgstr "Parametru lipsă pentru modurile %s." #, c-format msgid "Missing passwords: %zu" @@ -3920,7 +4052,7 @@ msgstr "Modul %s este un mod virtual și nu poate fi golit." #, c-format msgid "Mode %s is not a status or list mode." -msgstr "Modul %s nu este un mod de statut sau de listă." +msgstr "Modul %s nu este un mod de stare sau de listă." msgid "Mode lock" msgstr "Încuiere de mod" @@ -3936,35 +4068,8 @@ msgstr "Moduri" msgid "Modes cleared on %s and the channel destroyed." msgstr "Modurile au fost golite în %s și canalul a fost distrus." -#, c-format -msgid "" -"Modifies or displays the certificate list for your nick. If you connect to IRC and provide a client certificate with a matching fingerprint in the cert list, you will be automatically identified to services. Services Operators may provide a nick to modify other users' certificate lists.\n" -"\n" -"Examples:\n" -"\n" -" %sADD\n" -" Adds your current fingerprint to the certificate list and\n" -" automatically identifies you when you connect to IRC\n" -" using this fingerprint.\n" -"\n" -" %sDEL\n" -" Removes the fingerprint from your certificate list.\n" -"\n" -" %sLIST\n" -" Displays the current certificate list." -msgstr "" -"Modifică sau afișează lista de certificate pentru pseudonimul dumneavoastră. Dacă vă conectați la IRC și furnizați un certificat de client cu o amprentă digitală potrivită în lista de certificate, veți fi identificat(ă) automat la servicii. Operatorii de Servicii pot prezenta un pseudonim pentru a modifica listele de certificate ale altor utilizatori.\n" -"\n" -"Exemple:\n" -"\n" -" %sADD\n" -" Adaugă amprenta digitală curentă a dumneavoastră la lista de certificate și vă identifică automat atunci când vă conectați la IRC folosind această amprentă.\n" -"\n" -" %sDEL\n" -" Înlătură amprenta digitală din lista de certificate.\n" -"\n" -" %sLIST\n" -" Afișează lista curentă de certificate." +msgid "Modifies or displays the certificate list for your nick. If you connect to IRC and provide a client certificate with a matching fingerprint in the cert list, you will be automatically identified to services. Services Operators may provide a nick to modify other users' certificate lists." +msgstr "Modifică sau afișează lista de certificate pentru pseudonimul dumneavoastră. Dacă vă conectați la IRC și furnizați un certificat de client cu o amprentă digitală potrivită în lista de certificate, veți fi identificat(ă) automat la servicii. Operatorii de Servicii pot prezenta un pseudonim pentru a modifica listele de certificate ale altor utilizatori." #, c-format msgid "Modify the list of %s users" @@ -4214,6 +4319,9 @@ msgstr "Nu există intrări corespunzătoare în lista %s." msgid "No matching entries on the AKILL list." msgstr "Nu există intrări corespunzătoare în lista AKILL." +msgid "No matching entries on the host offer list." +msgstr "Nu există intrări corespunzătoare în lista de oferte pentru gazde." + msgid "No memo was cancelable." msgstr "Nicio misivă nu putea fi anulată." @@ -4265,7 +4373,7 @@ msgstr "Modul fără boți este acum activat în canalul %s." #, c-format msgid "Non-status modes cleared on %s." -msgstr "Modurile fără de statut au fost golite în %s." +msgstr "Modurile fără stare au fost golite în %s." msgid "None" msgstr "Niciuna" @@ -4281,9 +4389,49 @@ msgstr "Rețineți, totuși, dacă succesorul are deja prea multe canale înregi msgid "Nothing to do." msgstr "Nu este nimic de făcut." +msgid "Now" +msgstr "Acum" + msgid "Number" msgstr "Număr" +#, c-format +msgid "" +"Offer stock vhosts to unprivileged users.\n" +"The %sADD command adds an offered vhost. If expiry is provided then the offered vhost will only be available for a limited time. The vhost field may contain template variables. The supported template variables are:\n" +" {account} - Your current account.\n" +" {network} - The name of this IRC network.\n" +" {nick} - Your current nickname.\n" +" {regdate} - The YYYY-MM-DD date at which your nick was registered.\n" +" {regepoch} - The UNIX time at which your nick was registered.\n" +"\n" +"The %sCLEAR command removes all offered vhosts.\n" +"\n" +"The %sDEL command removes an offered vhost.\n" +"\n" +"The %sLIST command displays the offered vhosts, or optionally only those offered vhosts which match the given mask.\n" +"\n" +"The %sVIEW command is a more verbose version of the %sLIST command." +msgstr "" +"Oferă gazde virtuale standard utilizatorilor neprivilegiați.\n" +"Comanda %sADD adaugă un vhost oferit. Dacă este furnizată o perioadă de expiry, atunci gazda virtuală oferită va fi disponibilă doar pentru o perioadă limitată de timp. Câmpul vhost poate conține variabile șablon. Variabilele șablon acceptate sunt:\n" +" {account} - Contul dumneavoastră curent.\n" +" {network} - Numele acestei rețele IRC.\n" +" {nick} - Pseudonimul dumneavoastră curent.\n" +" {regdate} - Data AAAA-LL-ZZ la care pseudonimul dumneavoastră a fost înregistrat.\n" +" {regepoch} - Timpul UNIX la care pseudonimul dumneavoastră a fost înregistrat.\n" +"\n" +"Comanda %sCLEAR îlătură toate gazdele virtuale oferite.\n" +"\n" +"Comanda %sDEL înlătură o gazdă virtuală oferită.\n" +"\n" +"Comanda %sLIST afișează gazdele virtuale oferite sau, opțional, doar acele gazde virtuale oferite care corespund măștii date.\n" +"\n" +"Comanda %sVIEW este o versiune mai detaliată a comenzii %sLIST." + +msgid "Offered vhost" +msgstr "Gazdă virtuală oferită" + msgid "Online from" msgstr "Conectat(ă) din" @@ -4358,9 +4506,6 @@ msgstr "Parola este incorectă." msgid "Password reset email for %s has been sent." msgstr "A fost trimis mesajul de email de resetare a parolei pentru %s." -msgid "Passwords can not be changed right now. Please try again later." -msgstr "Parolele nu pot fi schimbate momentan. Vă rugăm să încercați din nou mai târziu." - #, c-format msgid "Passwords encrypted with %s: %zu" msgstr "Parolele criptate cu %s: %zu" @@ -4386,8 +4531,8 @@ msgstr "Vă rugăm confirmați că doriți să radiați %s cu %s%s%s" msgid "Please contact an Operator to get a vhost assigned to this nick." msgstr "Vă rugăm să contactați un Operator pentru a obține o gazdă virtuală atribuită acestui pseudonim." -msgid "Please try again with a more obscure password. Passwords should not be something that could be easily guessed (e.g. your real name or your nick) and cannot contain the space or tab characters." -msgstr "Vă rugăm să încercați din nou cu o parolă mai puțin cunoscută. Parolele nu ar trebui să fie ceva care ar putea fi ușor de ghicit (de exemplu, numele dumneavoastră real sau pseudonimul dumneavoastră) și trebuie să nu conțină spațiu ori caractere de tabulare." +msgid "Please try again with a more obscure password. Passwords should not be something that could be easily guessed (e.g. your real name or your nick) and cannot contain a space character." +msgstr "Vă rugăm să încercați din nou cu o parolă mai puțin cunoscută. Parolele nu ar trebui să fie ceva care ar putea fi ușor de ghicit (de exemplu, numele dumneavoastră real sau pseudonimul dumneavoastră) și pot conține caracterul spațiu." msgid "Please use a valid server name when juping." msgstr "Vă rugăm să folosiți un nume de server valid pentru juping." @@ -4403,6 +4548,10 @@ msgstr "Vă rugăm să așteptați %s și să încercați din nou." msgid "Please wait %s before requesting a new vhost." msgstr "Vă rugăm să așteptați %s înainte de a solicita o nouă gazdă virtuală." +#, c-format +msgid "Please wait %s before taking a new vhost." +msgstr "Vă rugăm să așteptați %s înainte de a lua o nouă gazdă virtuală." + #, c-format msgid "Please wait %s before using the %s command again." msgstr "Vă rugăm să așteptați %s înainte de a utiliza iar comanda %s." @@ -4658,17 +4807,26 @@ msgstr "Serverul %s a fost înlăturat." #, c-format msgid "Removes %s status from the selected nicks on a channel. If nick is not given, it will de%s you." -msgstr "Înlătură statutul %s de la pseudonimul selectat într-un canal. Dacă pseudonimul nu este specificat, statutul dumneavoastră %s va fi înlăturat." +msgstr "Înlătură starea %s de la pseudonimul selectat într-un canal. Dacă pseudonimul nu este specificat, starea dumneavoastră %s va fi înlăturată." #, c-format msgid "Removes %s status from you or the specified nick on a channel" -msgstr "Înlătură statutul %s de la dumneavoastră sau de la pseudonimul specificat dintr-un canal" +msgstr "Înlătură starea %s de la dumneavoastră sau de la pseudonimul specificat într-un canal" msgid "Removes a selected nicks status from a channel" -msgstr "Înlătură statutul unui pseudonim selectat într-un canal" +msgstr "Înlătură starea unui pseudonim selectat într-un canal" msgid "Removes a selected nicks status modes on a channel. If nick is omitted then your status is removed. If channel is omitted then your channel status is removed on every channel you are in." -msgstr "Înlătură modurile de statut ale pseudonimului selectat într-un canal. Dacă pseudonimul nu este specificat, atunci statutul dumneavoastră este înlăturat. Dacă canalul nu este specificat, atunci statutul duneavoastră de canal este înlăturat din fiecare canal în care vă aflați." +msgstr "Înlătură modurile de stare ale pseudonimului selectat într-un canal. Dacă pseudonimul nu este specificat, atunci starea dumneavoastră este înlăturată. Dacă canalul nu este specificat, atunci starea duneavoastră de canal este înlăturată din fiecare canal în care vă aflați." + +msgid "Removes all entries that were added in the last 30 minutes." +msgstr "Înlătură toate intrările care au fost adăugate în ultimele 30 de minute." + +msgid "Removes the specified fingerprint from the certificate list of nickname." +msgstr "Înlătură amprenta digitală specificată din lista de certificate a pseudonimului." + +msgid "Removes the specified fingerprint from your certificate list." +msgstr "Înlătură amprenta digitală specificată din lista de certificate a dumneavoastră." #, c-format msgid "Removing %s because %s covers it." @@ -4757,6 +4915,9 @@ msgstr "Salvează bazele de date și reporniți serviciile" msgid "Searches logs for a matching pattern" msgstr "Caută în jurnale un model corespunzător" +msgid "Searches the last 21 days worth of logs for messages containing Anope and lists the most recent 500 of them." +msgstr "Caută în jurnalele din ultimele 21 de zile mesaje care conțin Anope și listează cele mai recente 500 dintre acestea." + msgid "Secure founder" msgstr "Fondator securizat" @@ -4819,6 +4980,15 @@ msgstr "Trimite un cod de confirmare la adresa de email a pseudonimului cu instr msgid "Sends a memo and requests a read receipt" msgstr "Expediază o misivă și solicită o confirmare de citire" +msgid "Sends a memo to the channel when someone uses the chanserv/xop command on #anope." +msgstr "Expediază o misivă către canal atunci când cineva utilizează comanda chanserv/xop în #anope." + +msgid "Sends a message to channel operators and above when someone uses the chanserv/access command on #anope." +msgstr "Expediază o misivă către operatorii de canal și superiorilor atunci când cineva utilizează comanda chanserv/access în #anope." + +msgid "Sends a notice to channel voices and above when someone uses the chanserv/flags command on #anope." +msgstr "Trimite o notificare utilizatorilor voce sau superiorilor unui canal atunci când cineva utilizează comanda chanserv/flags în #anope." + msgid "Sends all registered users a memo containing memo-text." msgstr "Expediază tuturor utilizatorilor înregistrați o misivă care conține un mesaj-text." @@ -4826,21 +4996,13 @@ msgid "Sends all services staff a memo containing memo-text." msgstr "Expediază întregului personal de Servicii o misivă care conține un mesaj-text." msgid "Sends the named nick or channel a memo containing memo-text. When sending to a nickname, the recipient will receive a notice that they have a new memo. The target nickname/channel must be registered." -msgstr "Expediază pseudonimului sau canalului specificat o misivă care conține un mesaj-text. Când expediați mesaj către un pseudonim, destinatarul va primi o notificare că are un nou mesaj. Pseudonimul ori canalul destinație trebuie să fie înregistrate." +msgstr "Expediază pseudonimului sau canalului specificat o misivă care conține un mesaj-text. Când expediați mesaj către un pseudonim, destinatarul va primi o notificare că are un nou mesaj. Pseudonimul ori canalul destinație trebuie să fie înregistrate." msgid "Sends the named nick or channel a memo containing memo-text. When sending to a nickname, the recipient will receive a notice that they have a new memo. The target nickname/channel must be registered. Once the memo is read by its recipient, an automatic notification memo will be sent to the sender informing them that the memo has been read." -msgstr "Expediază pseudonimului sau canalului specificat o misivă care conține un mesaj-text. Când expediați un mesaj către un pseudonim, destinatarul va primi o notificare că are un nou mesaj. Pseudonimul ori canalul destinație trebuie să fie înregistrate. După ce misiva este citită de destinatar, o misivă de notificare automată va fi trimisă expeditorului, ca o informare că mesajul a fost citit." +msgstr "Expediază pseudonimului sau canalului specificat o misivă care conține un mesaj-text. Când expediați un mesaj către un pseudonim, destinatarul va primi o notificare că are un nou mesaj. Pseudonimul ori canalul destinație trebuie să fie înregistrate. După ce misiva este citită de destinatar, o misivă de notificare automată va fi trimisă expeditorului, ca o informare că mesajul a fost citit." -msgid "" -"Sends you the text of the memos specified. If LAST is given, sends you the memo you most recently received. If NEW is given, sends you all of your new memos. If ALL is given, sends you all of your memos. Otherwise, sends you memo number num. You can also give a list of numbers, as in this example:\n" -"\n" -" READ 2-5,7-9\n" -" Displays memos numbered 2 through 5 and 7 through 9." -msgstr "" -"Vă afișează textul misivelor specificate. Dacă se introduce LAST, vă afișează cea mai recentă misivă primită. Dacă este specificat NEW, vă afișează toate noile misive. Dacă se dă ALL, vă afișează toate notițele dumneavoastră. Altfel, vă afișează numărul misivei număr. De asemenea, puteți oferi o listă de numere, ca în exemplul următor:\n" -"\n" -" READ 2-5,7-9\n" -" Afișează misivele numerotate de la 2 la 5 și de la 7 la 9." +msgid "Sends you the text of the memos specified. If LAST is given, sends you the memo you most recently received. If NEW is given, sends you all of your new memos. If ALL is given, sends you all of your memos. Otherwise, sends you memo number num. You can also give a list of numbers." +msgstr "Vă afișează textul misivelor specificate. Dacă se introduce LAST, vă afișează cea mai recentă misivă primită. Dacă este specificat NEW, vă afișează toate noile misive. Dacă se dă ALL, vă afișează toate notițele dumneavoastră. Altfel, vă afișează numărul misivei număr. De asemenea, puteți oferi o listă de numere." msgid "Server" msgstr "Server" @@ -4894,7 +5056,7 @@ msgid "Server %s must be quit before it can be deleted." msgstr "Serverul %s trebuie îndepărtat înainte de a putea fi șters." msgid "Server: {server} = {ip} -- limit: {limit}; state: {state}" -msgstr "Server: {server} = {ip} -- limită: {limit}; statut: {state}" +msgstr "Server: {server} = {ip} -- limită: {limit}; stare: {state}" msgid "Servers" msgstr "Servere" @@ -4962,7 +5124,7 @@ msgstr "Servicii active %s." #, c-format msgid "Services will from now on set status modes on %s in channels." -msgstr "Serviciile vor seta de acum înainte moduri de statut pentru %s în canale." +msgstr "Serviciile vor seta de acum înainte moduri de stare pentru %s în canale." #, c-format msgid "Services will no longer automatically give modes to users in %s." @@ -4970,7 +5132,7 @@ msgstr "Serviciile nu vor mai oferi automat moduri utilizatorilor în %s." #, c-format msgid "Services will no longer set status modes on %s in channels." -msgstr "Serviciile nu vor mai seta moduri de statut pentru %s în canale." +msgstr "Serviciile nu vor mai seta moduri de stare pentru %s în canale." #, c-format msgid "Services will now automatically give modes to users in %s." @@ -5067,7 +5229,7 @@ msgid "" msgstr "" "Activează sau dezactivează izgonirea la AMSG. Când este activată, botul va izgoni utilizatorii care trimit același mesaj către mai multe canale unde se află %s boți.\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." #, c-format msgid "" @@ -5081,7 +5243,7 @@ msgstr "" "\n" "Puteți defini cuvinte nepotrivite pentru canalul dumneavoastră folosind comanda BADWORDS. Tastați %sBADWORDS pentru mai multe informații.\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." msgid "" "Sets the ban type that will be used by services whenever they need to ban someone from your channel.\n" @@ -5109,7 +5271,7 @@ msgid "" msgstr "" "Activează sau dezactivează izgonirea la îngroșări. Când este activată, această opțiune informează botul să izgonească utilizatorii care folosesc caractere îngroșate.\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." #, c-format msgid "" @@ -5123,7 +5285,7 @@ msgstr "" "\n" "Botul izgonește doar dacă există un cel puțin un minim de caractere majuscule iar acestea constituie cel puțin un procentaj%% din totalul liniei de text (dacă nu sunt specificate, valorile implicite sunt de 10 caractere și 25%%).\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." msgid "" "Sets the colors kicker on or off. When enabled, this option tells the bot to kick users who use colors.\n" @@ -5132,7 +5294,7 @@ msgid "" msgstr "" "Activează sau dezactivează izgonirea la culori. Când este activată, această opțiune informează botul să izgonească utilizatorii care folosesc culori.\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." msgid "Sets the description for the channel, which shows up with the LIST and INFO commands." msgstr "Setează descrierea canalului, care va apărea prin comenzile LIST și INFO." @@ -5144,7 +5306,7 @@ msgid "" msgstr "" "Activează sau dezactivează izgonirea la inundări. Când este activată, această opțiune informează botul să izgonească utilizatorii care inundă în canal folosind un minim de linii în secunde (dacă nu sunt specificate, valorile implicite sunt 6 linii în 10 secunde).\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." msgid "" "Sets the italics kicker on or off. When enabled, this option tells the bot to kick users who use italics. \n" @@ -5153,7 +5315,7 @@ msgid "" msgstr "" "Activează sau dezactivează izgonirea la înclinări. Când este activată, această opțiune informează botul să izgonească utilizatorii care folosesc caractere înclinate.\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." msgid "Sets the maximum number of memos you can receive" msgstr "Setează numărul maxim de misive pe care le puteți primi" @@ -5165,7 +5327,7 @@ msgid "" msgstr "" "Activează sau dezactivează izgonirea la repetări. Când este activată, această opțiune informează botul să izgonească utilizatorii care se repetă de un număr de ori (dacă valoarea numerică nu este specificată, valoarea implicită este 3).\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." msgid "" "Sets the reverses kicker on or off. When enabled, this option tells the bot to kick users who use reverses. \n" @@ -5174,7 +5336,7 @@ msgid "" msgstr "" "Activează sau dezactivează izgonirea la inversări. Când este activată, această opțiune informează botul să izgonească utilizatorii care folosesc inversări.\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." msgid "Sets the time bot bans expire in. If enabled, any bans placed by bots, such as flood kicker, badwords kicker, etc. will automatically be removed after the given time. Set to 0 to disable bans from automatically expiring." msgstr "Setează timpul în care expiră blocările făcute de boți. Dacă este activată, orice blocare plasată de boți, cum ar fi izgonirea la inundări, izgonirea la cuvinte nepotrivite și așa mai departe, vor fi înlăturate automat după expirarea timpului precizat. Setați 0 pentru a dezactiva expirarea automată a blocărilor." @@ -5186,7 +5348,7 @@ msgid "" msgstr "" "Activează sau dezactivează izgonirea la sublinieri. Când este activată, această opțiune informează botul să izgonească utilizatorii care folosesc sublinieri.\n" "\n" -"ttb reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați ttb pentru a dezactiva blocările activate." +"tentative reprezintă de câte ori un utilizator poate fi izgonit înainte de a fi blocat. Nu utilizați tentative pentru a dezactiva blocările activate." msgid "" "Sets the vhost for all nicks in the same account as that of the given nick. If your IRCD supports vidents, then using SETALL @ will set idents for users as well as vhosts.\n" @@ -5209,8 +5371,11 @@ msgstr "Setează diverse opțiuni ale misivelor. opțiunea poate fi după cum msgid "Sets various nickname options. option can be one of:" msgstr "Setează diverse opțiuni ale pseudonimului. opțiunea poate fi după cum urmează:" +msgid "Sets voice status on all users in the channel." +msgstr "Setează starea voce pentru toți utilizatorii din canal." + msgid "Sets whether services should set channel status modes on you automatically." -msgstr "Setează dacă serviciile ar trebui să seteze automat modurile de statut în canal pentru dumneavoastră." +msgstr "Setează dacă serviciile ar trebui să seteze automat modurile de stare în canal pentru dumneavoastră." msgid "Sets whether the given channel will expire. Setting this to ON prevents the channel from expiring." msgstr "Setează dacă canalul precizat va expira. Activarea acestei opțiuni previne expirarea canalului." @@ -5218,9 +5383,13 @@ msgstr "Setează dacă canalul precizat va expira. Activarea acestei opțiuni pr msgid "Sets whether the given nickname can be added to a channel access list." msgstr "Setează dacă pseudonimul precizat poate fi adăugat la o listă de accese a vreunui canal." +#, c-format +msgid "Sets whether the given nickname should automatically be logged in when they connect using a known SSL certificate. You can configure their SSL certificate using the %s command." +msgstr "Setează dacă pseudonimul precizat ar trebui să fie autentificat automat atunci când se conectează utilizând un certificat SSL cunoscut. Puteți configura certificatul SSL al acestuia utilizând comanda %s." + #, c-format msgid "Sets whether the given nickname will be given its status modes in channels automatically. Set to ON to allow %s to set status modes on the given nickname automatically when it is entering channels. Note that depending on channel settings some modes may not get set automatically." -msgstr "Setează dacă pseudonimul precizat va primi automat modurile sale de statut în canale. Setați la ON pentru a permite %s să seteze automat modurile de statut pentru pseudonimul precizat atunci când acesta intră în canale. Rețineți că, în funcție de setările canalelor, este posibil ca unele moduri să nu fie setate automat." +msgstr "Setează dacă pseudonimul precizat va primi automat modurile sale de stare în canale. Setați la ON pentru a permite %s să seteze automat modurile de stare pentru pseudonimul precizat atunci când acesta intră în canale. Rețineți că, în funcție de setările canalelor, este posibil ca unele moduri să nu fie setate automat." msgid "Sets whether the given nickname will expire. Setting this to ON prevents the nickname from expiring." msgstr "Setează dacă pseudonimul precizat va expira. Setarea acestei opțiuni la ON previne expirarea pseudonimului." @@ -5228,13 +5397,20 @@ msgstr "Setează dacă pseudonimul precizat va expira. Setarea acestei opțiuni msgid "Sets whether you can be added to a channel access list." msgstr "Setează dacă puteți fi adăugat(ă) la o listă de accese a vreunui canal." +msgid "Sets whether you should automatically be logged in when you connect using a known SSL certificate." +msgstr "Setează dacă ar trebui să fiți autentificat(ă) automat atunci când vă conectați utilizând un certificat SSL cunoscut." + +#, c-format +msgid "Sets whether you should automatically be logged in when you connect using a known SSL certificate. You can configure your SSL certificate using the %s command." +msgstr "Setează dacă ar trebui să fiți autentificat(ă) automat atunci când vă conectați utilizând un certificat SSL cunoscut. Puteți configura certificatul SSL al dumneavoastră utilizând comanda %s." + #, c-format msgid "Sets whether you will be given your channel status modes automatically. Set to ON to allow %s to set status modes on you automatically when entering channels. Note that depending on channel settings some modes may not get set automatically." -msgstr "Setează dacă veți primi automat modurile de statut în canale. Setați la ON pentru a permite %s să vă seteze automat modurile de statut atunci când intrați în canale. Rețineți că, în funcție de setările canalelor, este posibil ca unele moduri să nu fie setate automat." +msgstr "Setează dacă veți primi automat modurile de stare în canale. Setați la ON pentru a permite %s să vă seteze automat modurile de stare atunci când intrați în canale. Rețineți că, în funcție de setările canalelor, este posibil ca unele moduri să nu fie setate automat." #, c-format msgid "Setting %s not known. Type %sLEVELS for a list of valid settings." -msgstr "Setarea %s nu este cunoscută. Tastați %sLEVELS pentru o listă de setări valide." +msgstr "Setarea %s nu este cunoscută. Tastați %sLEVELS pentru o listă de setări valide." msgid "Setting for DEBUG must be ON, OFF, or a positive number." msgstr "Setarea pentru DEBUG trebuie să fie ON, OFF sau un număr pozitiv." @@ -5249,15 +5425,18 @@ msgid "Setting for super admin must be ON or OFF." msgstr "Setarea pentru SUPERADMIN trebuie să fie ON sau OFF." msgid "Should services automatically give status to users" -msgstr "Setează automatizarea statutului utilizatorilor" +msgstr "Setează automatizarea stării utilizatorilor" msgid "Show status of services and network" -msgstr "Afișează statutul serviciilor și al rețelei" +msgstr "Afișează starea serviciilor și al rețelei" #, c-format msgid "Showed %zu/%zu matches for %s." msgstr "Au fost afișate %zu/%zu corespunderi pentru %s." +msgid "Shows the current server configuration." +msgstr "Afișează configurația curentă a serverului." + msgid "Sign kicks that are done with the KICK command" msgstr "Semnează izgonirie executate prin comanda KICK" @@ -5276,52 +5455,8 @@ msgstr "Opțiunea de izgoniri semnate pentru %s este acum activată." msgid "Signed kicks" msgstr "Izgoniri semnate" -#, c-format -msgid "Sorry, %s currently has too many memos and cannot receive more." -msgstr "Ne pare rău, %s are în prezent prea multe misive și nu mai poate primi altele." - -#, c-format -msgid "Sorry, %s is temporarily unavailable." -msgstr "Ne pare rău, %s este temporar indisponibil." - -#, c-format -msgid "Sorry, I have not seen %s." -msgstr "Ne pare rău, nu am văzut pe %s." - -#, c-format -msgid "Sorry, the maximum of %d auto join entries has been reached." -msgstr "Ne pare rău, a fost atins numărul maxim de %d intrări pentru alăturări automate." - -#, c-format -msgid "Sorry, the maximum of %d certificate entries has been reached." -msgstr "Ne pare rău, a fost atins numărul maxim de %d intrări pentru certificate." - -#, c-format -msgid "Sorry, the memo ignore list for %s is full." -msgstr "Ne pare rău, lista de ignorare a misivelor pentru %s este plină." - -#, c-format -msgid "Sorry, you can only have %d access entries on a channel, including access entries from other channels." -msgstr "Ne pare rău, puteți avea doar %d intrări de accese într-un canal, inclusiv intrările de accese în alte canale." - -#, c-format -msgid "Sorry, you can only have %d autokick masks on a channel." -msgstr "Ne pare rău, puteți avea doar %d măști de izgoniri automate într-un canal." - -#, c-format -msgid "Sorry, you can only have %d bad words entries on a channel." -msgstr "Ne pare rău, puteți avea doar %d intrări de cuvinte nepotrivite într-un canal." - -#, c-format -msgid "Sorry, you have already exceeded your limit of %d channels." -msgstr "Ne pare rău, ați depășit deja limita de %d canale." - -#, c-format -msgid "Sorry, you have already reached your limit of %d channels." -msgstr "Ne pare rău, ați atins deja limita de %d canale." - msgid "State" -msgstr "Statut" +msgstr "Stare" msgid "Statistics and maintenance for seen data" msgstr "Statistici și întreținere pentru datele vizualizate" @@ -5329,8 +5464,11 @@ msgstr "Statistici și întreținere pentru datele vizualizate" msgid "Statistics reset." msgstr "Statisticile au fost resetate." +msgid "Status" +msgstr "Stare" + msgid "Status updated (memos, vhost, chmodes, flags)." -msgstr "Statutul a fost actualizat (misive, gazde virtuale, moduri, stegulețe)." +msgstr "Starea a fost actualizată (misive, gazde virtuale, moduri, stegulețe)." msgid "Stop flooding!" msgstr "Vă rugăm opriți inundarea!" @@ -5339,10 +5477,10 @@ msgid "Stop repeating yourself!" msgstr "Vă rugăm nu vă mai repetați!" msgid "Stricter control of channel founder status" -msgstr "Securizează statutul fondatorului de canal" +msgstr "Securizează starea fondatorului de canal" msgid "Stricter control of chanop status" -msgstr "Securizează statutul operatorului de canal" +msgstr "Securizează starea operatorului de canal" msgid "Successor" msgstr "Succesor" @@ -5490,6 +5628,9 @@ msgstr "" "\n" "Această opțiune nu este persistentă și ar trebui utilizată doar atunci când este nevoie, apoi setată din nou pe OFF când nu mai este necesară." +msgid "TAKE {vhost | entry-num}" +msgstr "TAKE {gazdă-virtuală | număr-intrare}" + #, c-format msgid "Tells %s that you are really the owner of this nick. Many commands require you to authenticate yourself with this command before you use them. The password should be the same one you sent with the REGISTER command." msgstr "Informează %s că sunteți proprietarul real al acestui pseudonim. Multe comenzi necesită identificare cu această comandă înainte de a fi utilizate. Parola este cea pe care ați furnizat-o odată cu comanda REGISTER." @@ -5547,16 +5688,17 @@ msgstr "" "\n" "Pentru o listă a caracteristicilor și funcțiilor ale căror niveluri pot fi setate, consultați HELP%sDESC." +#, c-format +msgid "The %s command is temporarily unavailable. Please try again later." +msgstr "Comanda %s este temporar indisponibilă. Vă rugăm să încercați din nou mai târziu." + #, c-format msgid "" "The %sADD command adds the given nickname to the %s list.\n" "\n" "The %sDEL command removes the given nick from the %s list. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The %sLIST command displays the %s list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" %s#channelLIST2-5,7-9\n" -" Lists %s entries numbered 2 through 5 and\n" -" 7 through 9.\n" +"The %sLIST command displays the %s list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "The %sCLEAR command clears all entries of the %s list." msgstr "" @@ -5564,9 +5706,7 @@ msgstr "" "\n" "Comanda %sDEL înlătură pseudonimul precizat din lista %s. Dacă este specificată o listă cu numere de intrare, acele intrări sunt înlăturate. (Vedeți exemplul pentru LIST de mai jos.)\n" "\n" -"Comanda %sLIST afișează lista %s. Dacă este precizată o mască wildcard, sunt afișate doar intrările care corespund măștii. Dacă este specificată o listă de numere de intrare, sunt afișate doar acele intrări; de exemplu:\n" -" %s#canalLIST2-5,7-9\n" -" Listează intrările %s numerotate de la 2 la 5 și de la 7 la 9.\n" +"Comanda %sLIST afișează lista %s. Dacă este precizată o mască wildcard, sunt afișate doar intrările care corespund măștii. Dacă este specificată o listă de numere de intrare, sunt afișate doar acele intrări.\n" "\n" "Comanda %sCLEAR golește toate intrările din lista %s." @@ -5574,10 +5714,7 @@ msgstr "" msgid "" "The %sDEL command removes the given mask from the AKILL list if it is present. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The %sLIST command displays the AKILL list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" %sLIST2-5,7-9\n" -" Lists AKILL entries numbered 2 through 5 and 7\n" -" through 9.\n" +"The %sLIST command displays the AKILL list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "%sVIEW is a more verbose version of %sLIST, and will show who added an AKILL, the date it was added, and when it expires, as well as the user@host/ip mask and reason.\n" "\n" @@ -5585,22 +5722,17 @@ msgid "" msgstr "" "Comanda %sDEL înlătură masca precizată din lista AKILL dacă este prezentă. Dacă este specificată o listă de numere de intrare, acele intrări sunt înlăturate. (Vedeți exemplul pentru LIST de mai jos.)\n" "\n" -"Comanda %sLIST afișează lista AKILL. Dacă este precizată o mască wildcard, sunt afișate doar intrările care corespund măștii. Dacă este specificată o listă de numere de intrare, sunt afișate doar acele intrări; de exemplu:\n" -" %sLIST2-5,7-9\n" -" Listează intrările AKILL numerotate de la 2 la 5 și de la 7 la 9.\n" +"Comanda %sLIST afișează lista AKILL. Dacă este precizată o mască wildcard, sunt afișate doar intrările care corespund măștii. Dacă este specificată o listă de numere de intrare, sunt afișate doar acele intrări.\n" "\n" -"%sVIEW este o versiune mai detaliată a %sLIST și va afișa cine a adăugat un AKILL, data la care a fost adăugat și când expiră, precum și masca utilizator@gazdă/ip și motivul.\n" +"Comanda %sVIEW este o versiune mai detaliată a %sLIST și va afișa cine a adăugat un AKILL, data la care a fost adăugat și când expiră, precum și masca utilizator@gazdă/ip și motivul.\n" "\n" -"%sCLEAR golește toate intrările din lista AKILL." +"Comanda %sCLEAR golește toate intrările din lista AKILL." #, c-format msgid "" "The %sDEL command removes the given nick from the access list. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.) You may remove yourself from an access list, even if you do not have access to modify that list otherwise.\n" "\n" -"The %sLIST command displays the access list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" %s#channelLIST2-5,7-9\n" -" Lists access entries numbered 2 through 5 and\n" -" 7 through 9.\n" +"The %sLIST command displays the access list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "The %sVIEW command displays the access list similar to %sLIST but shows the creator and last used time.\n" "\n" @@ -5608,21 +5740,16 @@ msgid "" msgstr "" "Comanda %sDEL înlătură pseudonimul precizat din lista de accese. Dacă este furnizată o listă de numere de intrare, acele intrări sunt înlăturate. (Vedeți exemplul pentru LIST de mai jos.) Vă puteți înlătura dintr-o listă de acces, chiar dacă nu aveți acces pentru a modifica lista respectivă în alt mod.\n" "\n" -"Comanda %sLIST afișează lista de accese. Dacă este precizată o mască wildcard, sunt afișate doar intrările care corespund măștii. Dacă este specificată o listă de numere de intrare, sunt afișate doar acele intrări; de exemplu:\n" -" %s#canalLIST2-5,7-9\n" -" Listează intrările de accese numerotate de la 2 la 5 și de la 7 la 9.\n" +"Comanda %sLIST afișează lista de accese. Dacă este precizată o mască wildcard, sunt afișate doar intrările care corespund măștii. Dacă este specificată o listă de numere de intrare, sunt afișate doar acele intrări.\n" "\n" "Comanda %sVIEW afișează lista de accese similară cu comanda %sLIST, dar arată în plus creatorul și timpul ultimei utilizări.\n" "\n" -"%sCLEAR golește toate intrările din lista de accese." +"Comanda %sCLEAR golește toate intrările din lista de accese." msgid "" "The SNLINEDEL command removes the given mask from the SNLINE list if it is present. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The SNLINELIST command displays the SNLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" SNLINELIST2-5,7-9\n" -" Lists SNLINE entries numbered 2 through 5 and 7\n" -" through 9.\n" +"The SNLINELIST command displays the SNLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "SNLINEVIEW is a more verbose version of SNLINELIST, and will show who added an SNLINE, the date it was added, and when it expires, as well as the realname mask and reason.\n" "\n" @@ -5630,21 +5757,16 @@ msgid "" msgstr "" "Comanda SNLINEDEL înlătură masca precizată din lista SNLINE dacă aceasta este prezentă. Dacă este furnizată o listă de numere de intrare, acele intrări sunt înlăturate. (Vedeți exemplul pentru LIST de mai jos.)\n" "\n" -"Comanda SNLINELIST LIST afișează lista SNLINE. Dacă este precizată o mască wildcard, vor fi afișate doar intrările care corespund măștii. Dacă este furnizată o listă de numere de intrare, sunt afișate doar acele intrări; de exemplu:\n" -" SNLINELIST2-5,7-9\n" -" Listează intrările SNLINE numerotate de la 2 la 5 și de la 7 la 9.\n" +"Comanda SNLINELIST LIST afișează lista SNLINE. Dacă este precizată o mască wildcard, vor fi afișate doar intrările care corespund măștii. Dacă este furnizată o listă de numere de intrare, sunt afișate doar acele intrări.\n" "\n" -"SNLINEVIEW este o versiune mai detaliată a SNLINELIST și va afișa cine a adăugat un SNLINE, data la care a fost adăugat și când expiră, precum și masca numelui real și motivul.\n" +"Comanda SNLINEVIEW este o versiune mai detaliată a SNLINELIST și va afișa cine a adăugat un SNLINE, data la care a fost adăugat și când expiră, precum și masca numelui real și motivul.\n" "\n" -"SNLINECLEAR golește toate intrările din lista SNLINE." +"Comanda SNLINECLEAR golește toate intrările din lista SNLINE." msgid "" "The SQLINEDEL command removes the given mask from the SQLINE list if it is present. If a list of entry numbers is given, those entries are deleted. (See the example for LIST below.)\n" "\n" -"The SQLINELIST command displays the SQLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown; for example:\n" -" SQLINELIST2-5,7-9\n" -" Lists SQLINE entries numbered 2 through 5 and 7\n" -" through 9.\n" +"The SQLINELIST command displays the SQLINE list. If a wildcard mask is given, only those entries matching the mask are displayed. If a list of entry numbers is given, only those entries are shown.\n" "\n" "SQLINEVIEW is a more verbose version of SQLINELIST, and will show who added an SQLINE, the date it was added, and when it expires, as well as the mask and reason.\n" "\n" @@ -5652,31 +5774,20 @@ msgid "" msgstr "" "Comanda SQLINEDEL înlătură masca precizată din lista SQLINE dacă aceasta este prezentă. Dacă este furnizată o listă de numere de intrare, acele intrări sunt înlăturate. (Vedeți exemplul pentru LIST de mai jos.)\n" "\n" -"Comanda SQLINELIST afișează lista SQLINE. Dacă este precizată o mască wildcard, sunt afișate doar intrările care corespund măștii. Dacă este specificată o listă de numere de intrare, sunt afișate doar acele intrări; de exemplu:\n" -" SQLINELIST2-5,7-9\n" -" Listează intrările SQLINE numerotate de la 2 la 5 și de la 7 la 9.\n" +"Comanda SQLINELIST afișează lista SQLINE. Dacă este precizată o mască wildcard, sunt afișate doar intrările care corespund măștii. Dacă este specificată o listă de numere de intrare, sunt afișate doar acele intrări.\n" "\n" -"SQLINEVIEW este o versiune mai detaliată a SQLINELIST și va afișa cine a adăugat un SQLINE, data la care a fost adăugat și când expiră, precum și masca și motivul.\n" +"Comanda SQLINEVIEW este o versiune mai detaliată a SQLINELIST și va afișa cine a adăugat un SQLINE, data la care a fost adăugat și când expiră, precum și masca și motivul.\n" "\n" -"SQLINECLEAR golește toate intrările din lista SQLINE." +"Comanda SQLINECLEAR golește toate intrările din lista SQLINE." -#, c-format msgid "" "The STATS command prints out statistics about stored nicks and memory usage.\n" "\n" -"The CLEAR command lets you clean the database by removing all entries from the database that were added within time.\n" -"\n" -"Example:\n" -" %sCLEAR30m\n" -" Will remove all entries that were added within the last 30 minutes." +"The CLEAR command lets you clean the database by removing all entries from the database that were added within time." msgstr "" "Comanda STATS oferă statistici despre pseudonimele stocate și utilizarea memoriei.\n" "\n" -"Comanda CLEAR vă permite să goliți baza de date prin ștergerea tuturor intrărilor din baza de date care au fost adăugate în intervalul de timp specificat.\n" -"\n" -"Exemplu:\n" -" %sCLEAR30m\n" -" Va goli toate intrările adăugate în ultimele 30 de minute." +"Comanda CLEAR vă permite să goliți baza de date prin ștergerea tuturor intrărilor din baza de date care au fost adăugate în intervalul de timp specificat." msgid "The email parameter is optional and will set the email address for your nick immediately. You may also wish to SETHIDE it after registering if it isn't the default setting already." msgstr "Parametrul email este opțional și va seta imediat adresa de email pentru pseudonimul dumneavoastră. Este posibil să doriți, de asemenea, a utiliza SETHIDE după înregistrare, dacă ascunderea adresei de email nu este deja o setare implicită." @@ -5691,25 +5802,17 @@ msgid "" "\n" "Which are used to message, notice, and memo the channel respectively. With MESSAGE or NOTICE you must have a service bot assigned to and joined to your channel. Status may be a channel status such as @ or +.\n" "\n" -"To remove a logging method use the same syntax as you would to add it.\n" -"\n" -"Example:\n" -" %s#anopechanserv/accessMESSAGE@\n" -" Would message any channel operators whenever someone used the ACCESS command on ChanServ on the channel." +"To remove a logging method use the same syntax as you would to add it." msgstr "" "Comanda %s permite utilizatorilor să configureze setările de înregistrare în jurnal pentru canalele lor. Dacă nu sunt furnizați parametri, această comandă listează metodele de înregistrare curente pentru acest canal.\n" "\n" "Altfel, comanda trebuie să fie un nume de comandă, iar metoda este una dintre următoarele metode de înregistrare în jurnal:\n" "\n" -" MESSAGE [statut], NOTICE [statut], MEMO\n" +" MESSAGEtare], NOTICEtare], MEMO\n" "\n" -"Care sunt folosite pentru a trimite mesaje, a notifica, și a trimite misive canalului respectiv. Pentru mesaj (MESSAGE) sau notificare (NOTICE) trebuie să aveți un bot de serviciu asociat și alăturat canalului dumneavoastră. Statutul poate fi un statut al canalului, cum ar fi @ sau +.\n" +"Care sunt folosite pentru a trimite mesaje, a notifica, și a trimite misive canalului respectiv. Pentru mesaj (MESSAGE) sau notificare (NOTICE) trebuie să aveți un bot de serviciu asociat și alăturat canalului dumneavoastră. Starea poate fi una de canal, cum ar fi @ sau +.\n" "\n" -"Pentru a înlătura o metodă de înregistrare în jurnal, utilizați aceeași sintaxă ca pentru a o adăuga.\n" -"\n" -"Examplu:\n" -" %s#anopechanserv/accessMESSAGE@\n" -" Trimite un mesaj tuturor operatorilor de fiecare dată când cineva folosește în canal comanda ACCESS aparținând serviciului ChanServ." +"Pentru a înlătura o metodă de înregistrare în jurnal, utilizați aceeași sintaxă ca pentru a o adăuga." #, c-format msgid "The %s list for %s is full." @@ -5804,13 +5907,29 @@ msgstr "Limita pentru %s nu este validă." msgid "The mask must contain at least one non wildcard character." msgstr "Masca trebuie să conțină cel puțin un caracter non-wildcard." +#, c-format +msgid "The maximum of %u auto join entry has been reached." +msgid_plural "The maximum of %u auto join entries has been reached." +msgstr[0] "Ne pare rău, a fost atins numărul maxim de %u intrări pentru alăturări automate." +msgstr[1] "Ne pare rău, a fost atins numărul maxim de %u intrări pentru alăturări automate." + +#, c-format +msgid "The maximum of %u certificate entry has been reached." +msgid_plural "The maximum of %u certificate entries has been reached." +msgstr[0] "Ne pare rău, a fost atins numărul maxim de %u intrări pentru certificate." +msgstr[1] "Ne pare rău, a fost atins numărul maxim de %u intrări pentru certificate." + +#, c-format +msgid "The memo ignore list for %s is full." +msgstr "Ne pare rău, lista de ignorare a misivelor pentru %s este plină." + #, c-format msgid "The memo limit for %s may not be changed." msgstr "Limita de misive pentru %s nu poate fi modificată." #, c-format -msgid "The mode lock list of %s is full." -msgstr "Lista de încuieri de mod pentru %s este plină." +msgid "The mode lock list of %s is full, unable to lock %s." +msgstr "Lista de încuieri de mod pentru %s este plină, prin urmare nu se poate încuia %s." #, c-format msgid "The network name you specified is incorrect. Did you mean to run %s on a different network?" @@ -5847,17 +5966,24 @@ msgstr "Codul de resetare a parolei specificat pentru %s este incorect." msgid "The password reset request for %s has expired." msgstr "Solicitarea de resetare a parolei pentru %s a expirat." +#, c-format +msgid "The password you specified is forbidden by %s: %s" +msgstr "Parola specificată de dumneavoastră este interzisă de %s: %s" + +msgid "The password you specified is forbidden." +msgstr "Parola specificată de dumneavoastră este interzisă." + #, c-format msgid "The registration confirmation code you specified for %s is incorrect." msgstr "Codul de confirmare a înregistrării specificat pentru %s este incorect." #, c-format msgid "The services access status of %s will now be hidden from %s INFO displays." -msgstr "Statutul accesului la servicii al utilizatorului %s va fi acum ascuns în comanda INFO a %s." +msgstr "Starea accesului la servicii a utilizatorului %s va fi de acum ascunsă în comanda INFO a %s." #, c-format msgid "The services access status of %s will now be shown in %s INFO displays." -msgstr "Statutul accesului la servicii al utilizatorului %s va fi acum afișat în comanda INFO a %s." +msgstr "Starea accesului la servicii a utilizatorului %s va fi de acum afișată în comanda INFO a %s." msgid "The session exception list is empty." msgstr "Lista de excepții de sesiune este goală." @@ -5952,7 +6078,7 @@ msgid "" "\n" "The POOL and DEPOOL commands actually add and remove servers to their given zones." msgstr "" -"Această comandă permite gestionarea zonelor DNS utilizate pentru controlul serverelor către care sunt direcționați utilizatorii la conectare. Omiterea tuturor parametrilor afișează statutul zonei DNS.\n" +"Această comandă permite gestionarea zonelor DNS utilizate pentru controlul serverelor către care sunt direcționați utilizatorii la conectare. Omiterea tuturor parametrilor afișează starea zonei DNS.\n" "\n" "ADDZONE adaugă o zonă, de exemplu ro.rețeaua-dumneavoastră.tld. Serverele pot fi apoi adăugate la această zonă prin comanda ADDSERVER.\n" "\n" @@ -6022,19 +6148,8 @@ msgstr "Această comandă reîncarcă modulul numit nume-modul." msgid "This command retrieves the vhost requests." msgstr "Această comandă preia solicitările de gazdă virtuală." -msgid "" -"This command searches the services logfiles for messages that match the given pattern. The day and limit argument may be used to specify how many days of logs to search and the number of replies to limit to. By default this command searches one week of logs, and limits replies to 50.\n" -"\n" -"For example:\n" -" LOGSEARCH+21d+500lAnope\n" -" Searches the last 21 days worth of logs for messages\n" -" containing Anope and lists the most recent 500 of them." -msgstr "" -"Această comandă caută în fișierele de jurnal ale serviciilor mesaje care se potrivesc cu modelul precizat. Argumentele zi și limită pot fi folosite pentru a specifica câte zile de jurnale să caute și numărul de răspunsuri la care să se limiteze. În mod implicit, această comandă caută o săptămână de jurnale și limitează răspunsurile la 50.\n" -"\n" -"De exemplu:\n" -" LOGSEARCH+21d+500lAnope\n" -" Caută în jurnalele din ultimele 21 de zile mesajele care conțin Anope și listează cele mai recente 500 dintre acestea." +msgid "This command searches the services logfiles for messages that match the given pattern. The day and limit argument may be used to specify how many days of logs to search and the number of replies to limit to. By default this command searches one week of logs, and limits replies to 50." +msgstr "Această comandă caută în fișierele de jurnal ale serviciilor mesaje care se potrivesc cu modelul precizat. Argumentele zi și limită pot fi folosite pentru a specifica câte zile de jurnale să caute și numărul de răspunsuri la care să se limiteze. În mod implicit, această comandă caută o săptămână de jurnale și limitează răspunsurile la 50." msgid "This command tells you what a users access is on a channel and what access entries, if any, they match. Additionally it will tell you of any auto kick entries they match. Usage of this command is limited to users who have the ability to modify access entries on the channel." msgstr "Această comandă vă informează ce acces are un utilizator într-un canal și ce intrări de acces corespund, dacă există. În plus, vă va informa despre intrările de izgoniri automate care se potrivesc. Utilizarea acestei comenzi este limitată la utilizatorii care au posibilitatea de a modifica intrările de acces în canal." @@ -6200,10 +6315,7 @@ msgstr "Tastați %sopțiunea pentru mai multe informații despre o anumită #, c-format msgid "Type %sregion to list timezones for a region." -msgstr "Tastați %sregiune pentru a lista fusurile orare ale unei regiuni." - -msgid "Un-Load a module" -msgstr "Aruncă un modul" +msgstr "Tastați %sregiunea pentru a lista fusurile orare ale unei regiuni." #, c-format msgid "Unable to find regex engine %s." @@ -6227,9 +6339,15 @@ msgstr "Disociază un bot dintr-un canal" msgid "Unassigns a bot from a channel. When you use this command, the bot won't join the channel anymore. However, bot configuration for the channel is kept, so you will always be able to reassign a bot later without having to reconfigure it entirely." msgstr "Disociază un bot dintr-un canal. Când utilizați această comandă, botul nu se va mai alătura canalului. Cu toate acestea, configurația botului pentru canal este păstrată, astfel încât veți putea întotdeauna să reasociați un bot mai târziu, fără a fi nevoie să-l reconfigurați în întregime." +msgid "Unconfirmed" +msgstr "Neconfirmat" + msgid "Underlines kicker" msgstr "Izgonire la sublinieri" +msgid "Unknown" +msgstr "Necunoscut" + msgid "Unknown SET option." msgstr "Opțiune SET necunoscută." @@ -6254,8 +6372,8 @@ msgid "Unknown command %s. Type %s for help." msgstr "Comandă necunoscută %s. Tastați %s pentru ajutor." #, c-format -msgid "Unknown mode character %c ignored." -msgstr "Caracterul de mod necunoscut %c este ignorat." +msgid "Unknown modes %s ignored." +msgstr "Modurile necunoscute %s au fost ignorate." #, c-format msgid "Unknown parameter: %s" @@ -6265,6 +6383,9 @@ msgstr "Parametru necunoscut: %s" msgid "Unknown passwords: %zu" msgstr "Parole necunoscute: %zu" +msgid "Unload a module" +msgstr "Descarcă un modul" + msgid "Unpooled" msgstr "Decolectivizat" @@ -6281,16 +6402,16 @@ msgid "Unsuspends a nickname which allows it to be used again." msgstr "Anulează suspendarea unui pseudonim, ceea ce permite utilizarea acestuia." msgid "Updates a selected nicks status modes on a channel. If nick is omitted then your status is updated. If channel is omitted then your channel status is updated on every channel you are in." -msgstr "Actualizează modurile de statut ale pseudonimului selectat într-un canal. Dacă pseudonimul este omis, atunci statutul dumneavoastră este actualizat. Dacă canalul este omis, atunci statutul dumneavoastră de canal este actualizat în fiecare canal în care vă aflați." +msgstr "Actualizează modurile de stare ale pseudonimului selectat într-un canal. Dacă pseudonimul este omis, atunci starea dumneavoastră este actualizată. Dacă canalul este omis, atunci starea dumneavoastră de canal este actualizată în fiecare canal în care vă aflați." msgid "Updates a selected nicks status on a channel" -msgstr "Actualizează statutul pseudonimului selectat într-un canal" +msgstr "Actualizează starea pseudonimului selectat într-un canal" msgid "Updates your current status, i.e. it checks for new memos" -msgstr "Actualizează statutul dumneavoastră actual, adică verifică dacă există noi misive" +msgstr "Actualizează starea dumneavoastră actuală, adică verifică dacă există noi misive" msgid "Updates your current status, i.e. it checks for new memos, sets needed channel modes and updates your vhost and your userflags (lastseentime, etc)." -msgstr "Actualizează statutul dumneavoastră actual, adică verifică dacă există noi misive, setează modurile de canal necesare apoi vă actualizează gazda virtuală și datele salvate (ultima conectare și altele)." +msgstr "Actualizează starea dumneavoastră actuală, adică verifică dacă există noi misive, setează modurile de canal necesare apoi vă actualizează gazda virtuală și datele salvate (ultima conectare și altele)." msgid "Updating databases." msgstr "Se actualizează bazele de date." @@ -6317,7 +6438,7 @@ msgid "Used to manage the list of privileged users" msgstr "Vă permite să gestionați lista de utilizatori privilegiați" msgid "Used to modify the channel status of you or other users" -msgstr "Vă permite să modificați statutul de canal al dumneavoastră sau al altor utilizatori" +msgstr "Vă permite să modificați starea de canal a dumneavoastră sau a altor utilizatori" #, c-format msgid "User %s isn't currently logged in to an account." @@ -6386,12 +6507,21 @@ msgstr "Gazda virtuală pentru contul %s a fost înlăturată." msgid "VIEW host" msgstr "VIEW gazdă" +msgid "VIEW nickname" +msgstr "VIEW pseudonim" + msgid "VIEW [mask | list | id]" -msgstr "VIEW [mască | listă | id]" +msgstr "VIEW [mască | listă | identificator]" msgid "VIEW [mask | list]" msgstr "VIEW [mască | listă]" +msgid "VIEW [nickname]" +msgstr "VIEW [pseudonim]" + +msgid "VIEW [vhost-mask | entry-num | list]" +msgstr "VIEW [mască | număr-intrare | listă]" + msgid "Validates a previously requested vhost using DNS" msgstr "Validează o gazdă virtuală solicitată, utilizând DNS" @@ -6556,6 +6686,26 @@ msgstr "Nu puteți solicita o confirmare atunci când vă trimiteți o misivă d msgid "You can not send a single message while you have messages queued." msgstr "Nu puteți trimite niciun mesaj cât timp aveți mesaje în coadă." +#, c-format +msgid "You can only have %d autokick masks on a channel." +msgstr "Puteți avea doar %d măști de izgoniri automate într-un canal." + +#, c-format +msgid "You can only have %d bad words entries on a channel." +msgstr "Puteți avea doar %d intrări de cuvinte nepotrivite într-un canal." + +#, c-format +msgid "You can only have %u access entry on a channel, including access entries from other channels." +msgid_plural "You can only have %u access entries on a channel, including access entries from other channels." +msgstr[0] "Pteți avea doar %u intrare de acces într-un canal, inclusiv intrările de accese în alte canale." +msgstr[1] "Puteți avea doar %u intrări de accese într-un canal, inclusiv intrările de accese în alte canale." + +#, c-format +msgid "You can only have %u access entry on a channel." +msgid_plural "You can only have %u access entries on a channel." +msgstr[0] "Puteți avea doar %u intrare de acces într-un canal." +msgstr[1] "Puteți avea doar %u intrări de accese într-un canal." + #, c-format msgid "You can't %s yourself!" msgstr "Nu puteți folosi %s asupra dumneavoastră!" @@ -6567,6 +6717,10 @@ msgstr "Nu puteți adăuga un canal la propria sa listă de acces." msgid "You can't logout %s, they are a Services Operator." msgstr "Nu puteți deidentifica pe %s deoarece este Operator de Servicii." +#, c-format +msgid "You cannot add a malformed mask to an access list. Did you mean to add %s instead?" +msgstr "Nu puteți adăuga o mască incorectă la o listă de accese. Ați dorit să adăugați %s în schimb?" + #, c-format msgid "You cannot set the %c flag." msgstr "Nu puteți seta stegulețul %c." @@ -6637,6 +6791,14 @@ msgstr[1] "Aveți %d misive noi." msgid "You have a new memo from %s. Type %s%zu to read it." msgstr "Aveți o misivă nouă de la %s. Tastați %s%zu pentru a o citi." +#, c-format +msgid "You have already exceeded your limit of %d channels." +msgstr "Ați depășit deja limita de %d canale." + +#, c-format +msgid "You have already reached your limit of %d channels." +msgstr "Ați atins deja limita de %d canale." + #, c-format msgid "You have been invited to %s by %s." msgstr "Ați fost invitat(ă) în %s de către %s." @@ -6684,8 +6846,8 @@ msgid "You may drop any nick within your account." msgstr "Puteți radia orice pseudonim din contul dumneavoastră." #, c-format -msgid "You may not (un)lock mode %c." -msgstr "Nu aveți dreptul să descuiați modul %c." +msgid "You may not (un)lock modes %s from %s." +msgstr "Nu puteți încuia sau descuia modurile %s din %s." msgid "You may not change the email address of an unconfirmed account." msgstr "Nu aveți dreptul să modificați adresa de email a unui cont neconfirmat." @@ -6729,12 +6891,18 @@ msgstr "Trebuie să fiți identificat(ă) într-un cont pentru a utiliza comanda msgid "You must confirm your account before you can register a channel." msgstr "Trebuie să vă confirmați contul înainte de a putea înregistra un canal." +msgid "You must confirm your account before you can view the host offer list." +msgstr "Trebuie să vă confirmați contul înainte de a putea vizualiza lista de oferte pentru gazde." + msgid "You must confirm your account before you may request a vhost." msgstr "Trebuie să vă confirmați contul înainte de a putea solicita o gazdă virtuală." msgid "You must confirm your account before you may send a memo." msgstr "Trebuie să vă confirmați contul înainte de a putea trimite o misivă." +msgid "You must confirm your account before you may take a vhost." +msgstr "Trebuie să vă confirmați contul înainte de a putea lua o gazdă virtuală." + #, c-format msgid "You must have the %s(ME) privilege on the channel to use this command." msgstr "Trebuie să aveți privilegiul %s(ME) în canal pentru a utiliza această comandă." @@ -6816,19 +6984,12 @@ msgstr "Serverul dumneavoastră de IRCd nu acceptă identități virtuale. Dacă #, c-format msgid "Your SSL certificate fingerprint %s has been automatically added to your certificate list." -msgstr "Amprenta electronică a certificatului SSL %s a fost adăugată automat la lista de certificate a dumneavoastră." +msgstr "Amprenta digitală a certificatului SSL %s a fost adăugată automat la lista de certificate a dumneavoastră." #, c-format msgid "Your account %s has been successfully created." msgstr "Contul dumneavoastră %s a fost creat cu succes." -msgid "Your account is not confirmed. To confirm it, follow the instructions that were emailed to you." -msgstr "Contul dumneavoastră nu este confirmat. Pentru a-l confirma, urmați instrucțiunile care v-au fost trimise prin email." - -#, c-format -msgid "Your account is not confirmed. To confirm it, type %s." -msgstr "Contul dumneavoastră nu este confirmat. Pentru a-l confirma, tastați %s." - #, c-format msgid "Your account will expire, if not confirmed, in %s." msgstr "Contul dumneavoastră va expira, dacă nu este confirmat, în %s." @@ -6896,12 +7057,12 @@ msgid "Your oper block doesn't require logging in." msgstr "Blocul de operare al dumneavoastră nu necesită autentificare." #, c-format -msgid "Your password is too long. It must be shorter than %u characters." -msgstr "Parola dumneavoastră este prea lungă. Aceasta trebuie să fie mai scurtă de %u caractere." +msgid "Your password is too long. It must be shorter than %zu characters." +msgstr "Parola dumneavoastră este prea lungă. Aceasta trebuie să fie mai scurtă de %zu caractere." #, c-format -msgid "Your password is too short. It must be longer than %u characters." -msgstr "Parola dumneavoastră este prea scurtă. Aceasta trebuie să fie mai lungă de %u caractere." +msgid "Your password is too short. It must be longer than %zu characters." +msgstr "Parola dumneavoastră este prea scurtă. Aceasta trebuie să fie mai lungă de %zu caractere." msgid "Your requested vhost has been approved." msgstr "Gazda virtuală solicitată de dumneavoastră a fost aprobată." @@ -6916,6 +7077,9 @@ msgstr "Gazda virtuală solicitată de dumneavoastră a fost respinsă. Motivul: msgid "Your requested vhost has been validated via DNS." msgstr "Gazda virtuală solicitată de dumneavoastră a fost validată prin DNS." +msgid "Your vhost" +msgstr "Gazda virtuală a dumneavoastră" + #, c-format msgid "Your vhost %s has been requested." msgstr "Gazda virtuală %s a fost solicitată pentru dumneavoastră." @@ -7001,7 +7165,7 @@ msgid "[channel] [nick]" msgstr "[canal] [pseudonim]" msgid "[channel] {num | list | LAST | ALL}" -msgstr "[canal] {număr | listă | LAST | ALL}" +msgstr "[canal] {numră | listă | LAST | ALL}" msgid "[channel] {num | list | LAST | NEW | ALL}" msgstr "[canal] {număr | listă | LAST | NEW | ALL}" @@ -7009,6 +7173,9 @@ msgstr "[canal] {număr | listă | LAST | NEW | ALL}" msgid "[key|#X-Y]" msgstr "[cheie|#X-Y]" +msgid "[language]" +msgstr "[limbă]" + msgid "[message]" msgstr "[mesaj]" @@ -7030,23 +7197,23 @@ msgstr "[pseudonim] cod" msgid "[parameter]" msgstr "[parametru]" +msgid "[timezone]" +msgstr "[fus-orar]" + +msgid "[vhost-mask | entry-num | list] [ALL]" +msgstr "[mască-virtuală | număr-intrare | listă] [ALL]" + msgid "[+daysd] [+limitl] pattern" msgstr "[+ziled] [+limităl] model" msgid "[+expiry] channel reason" msgstr "[+expirare] canal motiv" -msgid "[Hostname hidden]" -msgstr "[Numele de gazdă ascuns]" - msgid "[Suspended]" msgstr "[Suspendat]" -msgid "[Unconfirmed]" -msgstr "[Neconfirmat]" - msgid "[{pattern | channel} [INVISIBLE]]" -msgstr "[{model | canal} [INVISIBLE]]" +msgstr "[{șablon | canal} [INVISIBLE]]" msgid "[{pattern | nick} [SECRET]]" msgstr "[{model | pseudonim} [SECRET]]" @@ -7068,6 +7235,9 @@ msgstr "litere: %s, cuvinte: %s, linii: %s, zâmbete: %s, acțiuni: %s" msgid "not assigned yet" msgstr "încă neasociat" +msgid "value" +msgstr "valoare" + msgid "vhost" msgstr "gazdă virtuală" @@ -7149,6 +7319,24 @@ msgstr "{number}: {mask} = {level} -- creat de {creator}; ultima dată văzut msgid "{number}: {nick} = {vhost} -- created by {creator} at {created}" msgstr "{number}: {nick} = {vhost} -- creat de {creator} la {created}" +msgid "{number}: {offered_vhost} / {your_vhost} -- {expires}" +msgstr "{number}: {offered_vhost} / {your_vhost} -- {expires}" + +msgid "{number}: {offered_vhost} / {your_vhost} -- {expires} ({reason})" +msgstr "{number}: {offered_vhost} / {your_vhost} -- {expires} ({reason})" + +msgid "{number}: {vhost}" +msgstr "{number}: {vhost}" + +msgid "{number}: {vhost} ({reason})" +msgstr "{number}: {vhost} ({reason})" + +msgid "{number}: {vhost} -- created by {creator} on {created}; {expires}" +msgstr "{number}: {vhost} -- creat de {creator} pe {created}; {expires}" + +msgid "{number}: {vhost} -- created by {creator} on {created}; {expires} ({reason})" +msgstr "{number}: {vhost} -- creat de {creator} pe {created}; {expires} ({reason})" + msgid "{number}: {word} -- type: {type}" msgstr "{number}: {word} -- tip: {type}" diff --git a/modules/botserv/bs_badwords.cpp b/modules/botserv/bs_badwords.cpp index e7310b01bb..023d0dfb19 100644 --- a/modules/botserv/bs_badwords.cpp +++ b/modules/botserv/bs_badwords.cpp @@ -501,16 +501,23 @@ class CommandBSBadwords final "The \002LIST\002 command displays the bad words list. If " "a wildcard mask is given, only those entries matching the " "mask are displayed. If a list of entry numbers is given, " - "only those entries are shown; for example:\n" - " \002#channel\033LIST\0332-5,7-9\002\n" - " Lists bad words entries numbered 2 through 5 and\n" - " 7 through 9." + "only those entries are shown." "\n\n" "The \002CLEAR\002 command clears all entries from the " "bad words list." ), source.service->GetQueryCommand("generic/help").c_str(), source.command.nobreak().c_str()); + + ExampleWrapper examples; + examples.AddEntry("#channel LIST 2-5,7-9", _( + "Lists bad word entries on \037#channel\037 numbered 2 through 5 and 7 through 9." + )); + examples.AddEntry("#channel LIST *UwU*", _( + "Lists bad word entries on \037#channel\037 that match \037*UwU*\037." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/chanserv/cs_access.cpp b/modules/chanserv/cs_access.cpp index f7e72af54b..c0dcc1b3c0 100644 --- a/modules/chanserv/cs_access.cpp +++ b/modules/chanserv/cs_access.cpp @@ -635,10 +635,7 @@ class CommandCSAccess final "The \002%s\033LIST\002 command displays the access list. If " "a wildcard mask is given, only those entries matching the " "mask are displayed. If a list of entry numbers is given, " - "only those entries are shown; for example:\n" - " \002%s\033#channel\033LIST\0332-5,7-9\002\n" - " Lists access entries numbered 2 through 5 and\n" - " 7 through 9." + "only those entries are shown." "\n\n" "The \002%s\033VIEW\002 command displays the access list similar " "to \002%s\033LIST\002 but shows the creator and last used time." @@ -650,9 +647,17 @@ class CommandCSAccess final source.command.nobreak().c_str(), source.command.nobreak().c_str(), source.command.nobreak().c_str(), - source.command.nobreak().c_str(), source.command.nobreak().c_str()); + ExampleWrapper examples; + examples.AddEntry("#channel LIST 2-5,7-9", _( + "Lists access entries on \037#channel\037 numbered 2 through 5 and 7 through 9." + )); + examples.AddEntry("#channel LIST *nick*", _( + "Lists access entries on \037#channel\037 that match \037*nick*\037." + )); + examples.SendTo(source); + BotInfo *bi; Anope::string cmd; if (Command::FindCommandFromService("chanserv/levels", bi, cmd)) diff --git a/modules/chanserv/cs_list.cpp b/modules/chanserv/cs_list.cpp index f8d9b4157a..df6c452005 100644 --- a/modules/chanserv/cs_list.cpp +++ b/modules/chanserv/cs_list.cpp @@ -154,20 +154,23 @@ class CommandCSList final "flag set will be displayed. If multiple options are given, " "all channels matching at least one option will be displayed. " "Note that these options are limited to \037Services Operators\037." - "\n\n" - "Examples:" - "\n\n" - " \002LIST\033*anope*\002\n" - " Lists all registered channels with \002anope\002 in their\n" - " names (case insensitive)." - "\n\n" - " \002LIST\033*\033NOEXPIRE\002\n" - " Lists all registered channels which have been set to not expire." - "\n\n" - " \002LIST #51-100\002\n" - " Lists all registered channels within the given range (51-100)." )); + ExampleWrapper examples; + examples.AddEntry("*anope*", _( + "Lists all registered channels with \037anope\037 in their name (case insensitive). " + )); + examples.AddEntry("#51-100", _( + "Lists all registered channels within the given range (51-100)." + )); + examples.AddEntry("* NOEXPIRE", _( + "Lists all registered channels that have been set to not expire." + ), "chanserv/list"); + examples.AddEntry("* SUSPENDED", _( + "Lists all registered channels that have been suspended." + ), "chanserv/list"); + examples.SendTo(source); + if (!Config->GetBlock("options").Get("regexengine").empty()) { source.Reply(" "); diff --git a/modules/chanserv/cs_log.cpp b/modules/chanserv/cs_log.cpp index 61b25ca11f..9cbb4bb25f 100644 --- a/modules/chanserv/cs_log.cpp +++ b/modules/chanserv/cs_log.cpp @@ -286,15 +286,23 @@ class CommandCSLog final "to your channel. Status may be a channel status such as @ or +." "\n\n" "To remove a logging method use the same syntax as you would to add it." - "\n\n" - "Example:\n" - " %s\033#anope\033chanserv/access\033MESSAGE\033@\n" - " Would message any channel operators whenever someone used the " - "ACCESS command on ChanServ on the channel." ), - source.command.nobreak().c_str(), source.command.nobreak().c_str()); + ExampleWrapper examples; + examples.AddEntry("#anope chanserv/access MESSAGE @", _( + "Sends a message to channel operators and above when someone uses the chanserv/access " + "command on #anope." + )); + examples.AddEntry("#anope chanserv/flags NOTICE +", _( + "Sends a notice to channel voices and above when someone uses the chanserv/flags " + "command on #anope." + )); + examples.AddEntry("#anope chanserv/xop MEMO", _( + "Sends a memo to the channel when someone uses the chanserv/xop command on #anope." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/chanserv/cs_mode.cpp b/modules/chanserv/cs_mode.cpp index d9cc3ceace..bf72b47e60 100644 --- a/modules/chanserv/cs_mode.cpp +++ b/modules/chanserv/cs_mode.cpp @@ -816,29 +816,29 @@ class CommandCSMode final "command will clear all existing mode locks and set the new one given, while \002ADD\002 and \002DEL\002 " "modify the existing mode lock." "\n\n" - "Example:\n" - " \002%s\033#channel\033LOCK\033ADD\033+bmnt\033*!*@*.example.com\002\n" - "\n\n" "The \002%s\033SET\002 command allows you to set modes through services. Wildcards * and ? may " "be given as parameters for list and status modes." "\n\n" - "Example:\n" - " \002%s\033#channel\033SET\033+v\033*\002\n" - " Sets voice status to all users in the channel." - "\n\n" - " \002%s\033#channel\033SET\033-b\033~c:*\n" - " Clears all extended bans that start with ~c:" - "\n\n" "The \002%s\033CLEAR\002 command is an easy way to clear modes on a channel. \037what\037 may be " "any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and voices. If \037what\037 " "is not given then all basic modes are removed." ), source.command.nobreak().c_str(), source.command.nobreak().c_str(), - source.command.nobreak().c_str(), - source.command.nobreak().c_str(), - source.command.nobreak().c_str(), source.command.nobreak().c_str()); + + ExampleWrapper examples; + examples.AddEntry("#channel LOCK ADD +bmnt *!*@*.example.com", _( + "Adds a mode lock on the moderated, no external messages, topic lock flag modes as " + "well as a ban on \037*!*@*.example.com\037." + )); + examples.AddEntry("#channel SET +v *", _( + "Sets voice status on all users in the channel." + )); + examples.AddEntry("#channel SET -b channel:*", _( + "Clears all extended bans that start with \037channel:\037." + )); + return true; } }; diff --git a/modules/chanserv/cs_seen.cpp b/modules/chanserv/cs_seen.cpp index 8df1e238b7..447ca4ec97 100644 --- a/modules/chanserv/cs_seen.cpp +++ b/modules/chanserv/cs_seen.cpp @@ -226,16 +226,16 @@ class CommandOSSeen final this->SendSyntax(source); source.Reply(" "); source.Reply(_( - "The \002STATS\002 command prints out statistics about stored nicks and memory usage." - "\n\n" - "The \002CLEAR\002 command lets you clean the database by removing all entries from the " - "database that were added within \037time\037." - "\n\n" - "Example:\n" - " %s\033CLEAR\03330m\n" - " Will remove all entries that were added within the last 30 minutes." - ), - source.command.nobreak().c_str()); + "The \002STATS\002 command prints out statistics about stored nicks and memory usage." + "\n\n" + "The \002CLEAR\002 command lets you clean the database by removing all entries from the " + "database that were added within \037time\037." + )); + + ExampleWrapper examples; + examples.AddEntry("CLEAR 30m", _( + "Removes all entries that were added in the last 30 minutes." + )); return true; } }; diff --git a/modules/chanserv/cs_set_misc.cpp b/modules/chanserv/cs_set_misc.cpp index 9b6f0a1e15..2b1d7f9e3f 100644 --- a/modules/chanserv/cs_set_misc.cpp +++ b/modules/chanserv/cs_set_misc.cpp @@ -17,8 +17,18 @@ static Module *me; -static Anope::map descriptions; -static Anope::map numerics; +#define MISC_PREFIX "cs_set_misc:" + +struct CommandData final +{ + Anope::string description; + Anope::string pattern; + Anope::string syntax; + Anope::string title; + unsigned numeric = 0; +}; + +static Anope::map command_data; struct CSMiscData; static Anope::map *> items; @@ -100,17 +110,49 @@ static Anope::string GetAttribute(const Anope::string &command) { size_t sp = command.rfind(' '); if (sp != Anope::string::npos) - return command.substr(sp + 1); - return command; + return MISC_PREFIX + command.substr(sp + 1); + return MISC_PREFIX + command; +} + +static const char* GetTitle(ExtensibleItem *ext) +{ + auto it = command_data.find(ext->name); + if (it == command_data.end() || it->second.title.empty()) + return ext->name.c_str() + 12; + return it->second.title.c_str(); } class CommandCSSetMisc final : public Command { +private: + bool CheckSyntax(CommandSource &source, ExtensibleItem *ext, const Anope::string &value) const + { + auto it = command_data.find(ext->name); + if (it == command_data.end() || it->second.pattern.empty()) + return true; // No syntax validation. + + ServiceReference regex("Regex", Config->GetBlock("options").Get("regexengine")); + if (!regex) + return true; // No regex engine. + + auto ret = true; + try + { + auto *pattern = regex->Compile(it->second.pattern); + ret = pattern->Matches(value); + delete pattern; + } + catch (const RegexException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } + return ret; + } + public: CommandCSSetMisc(Module *creator, const Anope::string &cname = "chanserv/set/misc") : Command(creator, cname, 1, 2) { - this->SetSyntax(_("\037channel\037 [\037parameters\037]")); } void Execute(CommandSource &source, const std::vector ¶ms) override @@ -140,46 +182,70 @@ class CommandCSSetMisc final return; } - Anope::string scommand = GetAttribute(source.command); - Anope::string key = "cs_set_misc:" + scommand; + const auto key = GetAttribute(source.command); ExtensibleItem *item = GetItem(key); if (item == NULL) return; if (!param.empty()) { + if (!CheckSyntax(source, item, param)) + { + source.Reply(CHAN_SETTING_INVALID, GetTitle(item)); + this->SendSyntax(source); + return; + } + item->Set(ci, CSMiscData(ci, key, param)); Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change it to " << param; - source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), ci->name.c_str(), params[1].c_str()); + source.Reply(CHAN_SETTING_CHANGED, GetTitle(item), ci->name.c_str(), params[1].c_str()); } else { item->Unset(ci); Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset it"; - source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), ci->name.c_str()); + source.Reply(CHAN_SETTING_UNSET, GetTitle(item), ci->name.c_str()); } } void OnServHelp(CommandSource &source, HelpWrapper &help) override { - if (descriptions.count(source.command)) + auto it = command_data.find(GetAttribute(source.command)); + if (it != command_data.end() && !it->second.description.empty()) { - this->SetDesc(descriptions[source.command]); + this->SetDesc(it->second.description); Command::OnServHelp(source, help); } } bool OnHelp(CommandSource &source, const Anope::string &subcommand) override { - if (descriptions.count(source.command)) + auto it = command_data.find(GetAttribute(source.command)); + if (it != command_data.end() && !it->second.description.empty()) { this->SendSyntax(source); source.Reply(" "); - source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str())); + source.Reply("%s", Language::Translate(source.nc, it->second.description.c_str())); return true; } return false; } + + void SendSyntax(CommandSource &source) override + { + auto *value = _("value"); + auto it = command_data.find(GetAttribute(source.command)); + if (it != command_data.end() && !it->second.syntax.empty()) + value = it->second.syntax.c_str(); + + this->ClearSyntax(); + this->SetSyntax(Anope::Format( + Language::Translate(source.nc, _("\037channel\037 [\037%s\037]")), + Language::Translate(source.nc, value) + )); + + Command::SendSyntax(source); + } }; class CSSetMisc final @@ -204,37 +270,37 @@ class CSSetMisc final void OnReload(Configuration::Conf &conf) override { - descriptions.clear(); - numerics.clear(); - + command_data.clear(); for (int i = 0; i < conf.CountBlock("command"); ++i) { const auto &block = conf.GetBlock("command", i); - if (block.Get("command") != "chanserv/set/misc") continue; Anope::string cname = block.Get("name"); Anope::string desc = block.Get("misc_description"); - if (cname.empty() || desc.empty()) continue; - descriptions[cname] = desc; - // Force creation of the extension item. - const auto extname = "cs_set_misc:" + GetAttribute(cname); + const auto extname = GetAttribute(cname); GetItem(extname); - auto numeric = block.Get("misc_numeric"); + auto &data = command_data[extname]; + data.description = desc; + data.title = block.Get("misc_title"); + data.pattern = block.Get("misc_pattern"); + data.syntax = block.Get("misc_syntax"); + + const auto numeric = block.Get("misc_numeric"); if (numeric >= 1 && numeric <= 999) - numerics[extname] = numeric; + data.numeric = numeric; } } void OnJoinChannel(User *user, Channel *c) override { - if (!c->ci || !user->server->IsSynced() || user->server == Me || numerics.empty()) + if (!c->ci || !user->server->IsSynced() || user->server == Me || command_data.empty()) return; for (const auto &[name, ext] : items) @@ -243,9 +309,9 @@ class CSSetMisc final if (!data) continue; - auto numeric = numerics.find(name); - if (numeric != numerics.end()) - IRCD->SendNumeric(numeric->second, user->GetUID(), c->ci->name, data->data); + auto command = command_data.find(name); + if (command != command_data.end() && command->second.numeric) + IRCD->SendNumeric(command->second.numeric, user->GetUID(), c->ci->name, data->data); } } @@ -257,7 +323,7 @@ class CSSetMisc final MiscData *data = e->Get(ci); if (data != NULL) - info[e->name.substr(12).replace_all_cs("_", " ")] = data->data; + info[GetTitle(e)] = data->data; } } }; diff --git a/modules/chanserv/cs_updown.cpp b/modules/chanserv/cs_updown.cpp index 717d8a6e28..31f599bad6 100644 --- a/modules/chanserv/cs_updown.cpp +++ b/modules/chanserv/cs_updown.cpp @@ -143,7 +143,8 @@ class CommandCSDown final auto *memb = c->FindUser(u); if (memb != NULL) { - for (auto *mode : memb->status.Modes()) + auto modes = memb->status.Modes(); + for (auto *mode : modes) c->RemoveMode(NULL, mode, u->GetUID()); } } diff --git a/modules/chanserv/cs_xop.cpp b/modules/chanserv/cs_xop.cpp index abe0eaf7d8..f9de8c3752 100644 --- a/modules/chanserv/cs_xop.cpp +++ b/modules/chanserv/cs_xop.cpp @@ -614,10 +614,7 @@ class CommandCSXOP final "The \002%s\033LIST\002 command displays the %s list. If " "a wildcard mask is given, only those entries matching the " "mask are displayed. If a list of entry numbers is given, " - "only those entries are shown; for example:\n" - " \002%s\033#channel\033LIST\0332-5,7-9\002\n" - " Lists %s entries numbered 2 through 5 and\n" - " 7 through 9." + "only those entries are shown." "\n\n" "The \002%s\033CLEAR\002 command clears all entries of the " "%s list." @@ -629,10 +626,14 @@ class CommandCSXOP final cmd.c_str(), cmd.c_str(), cmd.c_str(), - cmd.c_str(), - cmd.c_str(), cmd.c_str()); + ExampleWrapper examples; + examples.AddEntry("#channel LIST 2-5,7-9", _( + "Lists access entries numbered 2 through 5 and 7 through 9." + )); + examples.SendTo(source); + BotInfo *access_bi, *flags_bi; Anope::string access_cmd, flags_cmd; Command::FindCommandFromService("chanserv/access", access_bi, access_cmd); diff --git a/modules/database/db_atheme.cpp b/modules/database/db_atheme.cpp index a475d8284f..5175f25769 100644 --- a/modules/database/db_atheme.cpp +++ b/modules/database/db_atheme.cpp @@ -170,6 +170,8 @@ class DBAtheme final ServiceReference sglinemgr; ServiceReference snlinemgr; ServiceReference sqlinemgr; + Anope::map csmiscdata; + Anope::map nsmiscdata; Anope::map> rowhandlers = { { "AC", &DBAtheme::HandleIgnore }, @@ -1080,7 +1082,26 @@ class DBAtheme final data->data = value; } else - Log(this) << "Unknown channel metadata for " << ci->name << ": " << key << " = " << value; + { + auto it = csmiscdata.find(key); + if (it == csmiscdata.end()) + { + Log(this) << "Unknown channel metadata for " << ci->name << ": " << key << " = " << value; + return true; + } + + ExtensibleRef extref("cs_set_misc:" + it->second); + if (!extref) + { + Log(this) << "Unknown imported channel metadata for " << ci->name << ": " << it->second << " = " << value; + return true; + } + + auto *data = extref->Set(ci); + data->object = ci->name; + data->name = it->second; + data->data = value; + } return true; } @@ -1193,7 +1214,26 @@ class DBAtheme final data->data = value; } else - Log(this) << "Unknown account metadata for " << nc->display << ": " << key << " = " << value; + { + auto it = nsmiscdata.find(key); + if (it == nsmiscdata.end()) + { + Log(this) << "Unknown public account metadata for " << nc->display << ": " << key << " = " << value; + return true; + } + + ExtensibleRef extref("ns_set_misc:" + it->second); + if (!extref) + { + Log(this) << "Unknown imported account metadata for " << nc->display << ": " << key << " = " << value; + return true; + } + + auto *data = extref->Set(nc); + data->object = nc->display; + data->name = it->second; + data->data = value; + } return true; } @@ -1541,6 +1581,28 @@ class DBAtheme final void OnReload(Configuration::Conf &conf) override { + const auto &modconf = conf.GetModule(this); + + csmiscdata.clear(); + for (auto idx = 0; idx < modconf.CountBlock("cs_set_misc"); ++idx) + { + const auto &data = modconf.GetBlock("cs_set_misc", idx); + const auto &anope = data.Get("anope"); + const auto &atheme = data.Get("atheme"); + if (!anope.empty() && !atheme.empty()) + csmiscdata[atheme] = anope.upper(); + } + + nsmiscdata.clear(); + for (auto idx = 0; idx < modconf.CountBlock("ns_set_misc"); ++idx) + { + const auto &data = modconf.GetBlock("ns_set_misc", idx); + const auto &anope = data.Get("anope"); + const auto &atheme = data.Get("atheme"); + if (!anope.empty() && !atheme.empty()) + nsmiscdata[atheme] = anope.upper(); + } + flags.clear(); for (int i = 0; i < Config->CountBlock("privilege"); ++i) { diff --git a/modules/database/db_json.cpp b/modules/database/db_json.cpp index 0be89ba04b..1ede48b09f 100644 --- a/modules/database/db_json.cpp +++ b/modules/database/db_json.cpp @@ -219,7 +219,12 @@ class DBJSON final return; for (auto it = entries.first; it != entries.second; ++it) - s_type->Unserialize(nullptr, it->second); + { + auto &data = it->second; + auto *obj = s_type->Unserialize(nullptr, data); + if (obj && data.id) + obj->object_id = data.id; + } } std::optional ReadDatabase(const Anope::string &dbname) diff --git a/modules/memoserv/ms_del.cpp b/modules/memoserv/ms_del.cpp index ecac891f26..70fcd7508e 100644 --- a/modules/memoserv/ms_del.cpp +++ b/modules/memoserv/ms_del.cpp @@ -134,19 +134,23 @@ class CommandMSDel final "Deletes the specified memo or memos. You can supply " "multiple memo numbers or ranges of numbers instead of a " "single number, as in the second example below." - "\n\n" - "If \002LAST\002 is given, the last memo will be deleted." - "\n\n" - "If \002ALL\002 is given, deletes all of your memos." - "\n\n" - "Examples:" - "\n\n" - " \002DEL\0331\002\n" - " Deletes your first memo." - "\n\n" - " \002DEL\0332-5,7-9\002\n" - " Deletes memos numbered 2 through 5 and 7 through 9." )); + + ExampleWrapper examples; + examples.AddEntry("ALL", _( + "Deletes all of your memos." + )); + examples.AddEntry("LAST", _( + "Deletes your last memo." + )); + examples.AddEntry("1", _( + "Deletes your first memo." + )); + examples.AddEntry("2-5,7-9", _( + "Deletes memos numbered 2 through 5 and 7 through 9." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/memoserv/ms_list.cpp b/modules/memoserv/ms_list.cpp index 8b399ab1a7..962b53306e 100644 --- a/modules/memoserv/ms_list.cpp +++ b/modules/memoserv/ms_list.cpp @@ -143,10 +143,18 @@ class CommandMSList final "Lists any memos you currently have. With \002NEW\002, lists only " "new (unread) memos. Unread memos are marked with a \"*\" " "to the left of the memo number. You can also specify a list " - "of numbers, as in the example below:\n" - " \002LIST 2-5,7-9\002\n" - " Lists memos numbered 2 through 5 and 7 through 9." + "of numbers." )); + + ExampleWrapper examples; + examples.AddEntry("NEW", _( + "Lists any new memos." + )); + examples.AddEntry("2-5,7-9", _( + "Lists memos numbered 2 through 5 and 7 through 9." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/memoserv/ms_read.cpp b/modules/memoserv/ms_read.cpp index 8cce4002ea..9a3be556bb 100644 --- a/modules/memoserv/ms_read.cpp +++ b/modules/memoserv/ms_read.cpp @@ -204,12 +204,24 @@ class CommandMSRead final "given, sends you the memo you most recently received. If " "NEW is given, sends you all of your new memos. If ALL is " "given, sends you all of your memos. Otherwise, sends you " - "memo number \037num\037. You can also give a list of numbers, " - "as in this example:" - "\n\n" - " \002READ 2-5,7-9\002\n" - " Displays memos numbered 2 through 5 and 7 through 9." + "memo number \037num\037. You can also give a list of numbers." )); + + ExampleWrapper examples; + examples.AddEntry("ALL", _( + "Displays all of your memos." + )); + examples.AddEntry("LAST", _( + "Displays your last memo." + )); + examples.AddEntry("NEW", _( + "Displays any new memos." + )); + examples.AddEntry("2-5,7-9", _( + "Displays memos numbered 2 through 5 and 7 through 9." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/nickserv/ns_cert.cpp b/modules/nickserv/ns_cert.cpp index 112b766f9b..9f8289e552 100644 --- a/modules/nickserv/ns_cert.cpp +++ b/modules/nickserv/ns_cert.cpp @@ -15,7 +15,20 @@ #include "module.h" #include "modules/nickserv/cert.h" -static Anope::unordered_map certmap; +#define NICKSERV_CERT_TYPE "NSCert" + +struct NSCertInfo final + : NickServ::Cert + , Serializable +{ + NSCertInfo(Extensible *ext) + : Serializable(NICKSERV_CERT_TYPE) + { + account = anope_dynamic_static_cast(ext); + } +}; + +static Anope::unordered_map certmap; struct CertServiceImpl final : NickServ::CertService @@ -27,9 +40,9 @@ struct CertServiceImpl final NickCore *FindAccountFromCert(const Anope::string &cert) override { - Anope::unordered_map::iterator it = certmap.find(cert); + auto it = certmap.find(cert); if (it != certmap.end()) - return it->second; + return it->second->account; return NULL; } @@ -48,8 +61,10 @@ struct CertServiceImpl final struct NSCertListImpl final : NickServ::CertList { + friend class NSCertInfoType; + Serialize::Reference nc; - std::vector certs; + std::vector certs; public: NSCertListImpl(Extensible *obj) : nc(anope_dynamic_static_cast(obj)) { } @@ -65,11 +80,15 @@ struct NSCertListImpl final * * Adds a new entry into the cert list. */ - void AddCert(const Anope::string &entry) override + NickServ::Cert *AddCert(const Anope::string &entry) override { - this->certs.push_back(entry); - certmap[entry] = nc; - FOREACH_MOD(OnNickAddCert, (this->nc, entry)); + auto *cert = new NSCertInfo(nc); + cert->fingerprint = entry; + + this->certs.push_back(cert); + certmap[entry] = cert; + FOREACH_MOD(OnNickAddCert, (this->nc, cert)); + return cert; } /** Get an entry from the nick's cert list by index @@ -79,10 +98,11 @@ struct NSCertListImpl final * * Retrieves an entry from the certificate list corresponding to the given index. */ - Anope::string GetCert(unsigned entry) const override + NickServ::Cert *GetCert(unsigned entry) const override { if (entry >= this->certs.size()) - return ""; + return nullptr; + return this->certs[entry]; } @@ -100,7 +120,10 @@ struct NSCertListImpl final */ bool FindCert(const Anope::string &entry) const override { - return std::find(this->certs.begin(), this->certs.end(), entry) != this->certs.end(); + auto it = std::find_if(this->certs.begin(), this->certs.end(), [&entry](const NSCertInfo *cert) { + return cert->fingerprint == entry; + }); + return it != this->certs.end(); } /** Erase a fingerprint from the nick's certificate list @@ -111,34 +134,45 @@ struct NSCertListImpl final */ void EraseCert(const Anope::string &entry) override { - std::vector::iterator it = std::find(this->certs.begin(), this->certs.end(), entry); + auto it = std::find_if(this->certs.begin(), this->certs.end(), [&entry](const NSCertInfo *cert) { + return cert->fingerprint == entry; + }); if (it != this->certs.end()) { - FOREACH_MOD(OnNickEraseCert, (this->nc, entry)); + FOREACH_MOD(OnNickEraseCert, (this->nc, *it)); certmap.erase(entry); + + delete *it; this->certs.erase(it); } } void ReplaceCert(const Anope::string &oldentry, const Anope::string &newentry) override { - auto it = std::find(this->certs.begin(), this->certs.end(), oldentry); - if (it == this->certs.end()) + auto oldit = std::find_if(this->certs.begin(), this->certs.end(), [&oldentry](const NSCertInfo *cert) { + return cert->fingerprint == oldentry; + }); + if (oldit == this->certs.end()) return; // We can't replace a non-existent cert. - FOREACH_MOD(OnNickEraseCert, (this->nc, oldentry)); + FOREACH_MOD(OnNickEraseCert, (this->nc, *oldit)); certmap.erase(oldentry); - if (std::find(this->certs.begin(), this->certs.end(), newentry) != this->certs.end()) + auto newit = std::find_if(this->certs.begin(), this->certs.end(), [&newentry](const NSCertInfo *cert) { + return cert->fingerprint == newentry; + }); + if (newit != this->certs.end()) { // The cert we're upgrading to already exists. - this->certs.erase(it); + delete *newit; + this->certs.erase(newit); return; } - *it = newentry; - certmap[newentry] = nc; - FOREACH_MOD(OnNickAddCert, (this->nc, newentry)); + auto *cert = *newit; + cert->fingerprint = newentry; + certmap[newentry] = cert; + FOREACH_MOD(OnNickAddCert, (this->nc, cert)); } /** Clears the entire nick's cert list @@ -148,8 +182,11 @@ struct NSCertListImpl final void ClearCert() override { FOREACH_MOD(OnNickClearCert, (this->nc)); - for (const auto &cert : certs) - certmap.erase(cert); + for (const auto *cert : certs) + { + delete cert; + certmap.erase(cert->fingerprint); + } this->certs.clear(); } @@ -164,53 +201,104 @@ struct NSCertListImpl final { ExtensibleItem(Module *m, const Anope::string &ename) : ::ExtensibleItem(m, ename) { } - void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const override - { - if (s->GetSerializableType()->GetName() != NICKCORE_TYPE) - return; - - const NickCore *n = anope_dynamic_static_cast(e); - auto *c = this->Get(n); - if (c == NULL || !c->GetCertCount()) - return; - - std::ostringstream oss; - for (unsigned i = 0; i < c->GetCertCount(); ++i) - oss << c->GetCert(i) << " "; - data.Store("cert", oss.str()); - } - void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) override { + // Begin 2.0 compatibility. if (s->GetSerializableType()->GetName() != NICKCORE_TYPE) return; - NickCore *n = anope_dynamic_static_cast(e); - auto *c = this->Require(n); + auto *nc = anope_dynamic_static_cast(e); + auto *cl = this->Require(nc); + + // Delete the old cert list. + for (const auto *cert : cl->certs) + { + delete cert; + certmap.erase(cert->fingerprint); + } + cl->certs.clear(); + // Add the new cert list Anope::string buf; data["cert"] >> buf; - spacesepstream sep(buf); - for (const auto &cert : c->certs) - certmap.erase(cert); - c->certs.clear(); - while (sep.GetToken(buf)) + for (spacesepstream sep(buf); sep.GetToken(buf); ) { - c->certs.push_back(buf); - certmap[buf] = n; + auto *cert = new NSCertInfo(e); + cert->fingerprint = buf; + cl->certs.push_back(cert); + certmap[buf] = cert; } + // End 2.0 compatibility. } }; }; + +class NSCertInfoType final + : public Serialize::Type +{ +public: + NSCertInfoType() + : Serialize::Type(NICKSERV_CERT_TYPE) + { + } + + void Serialize(Serializable *obj, Serialize::Data &data) const override + { + const auto *cert = static_cast(obj); + data.Store("account", cert->account->GetId()); + data.Store("created", cert->created); + data.Store("creator", cert->creator); + data.Store("description", cert->description); + data.Store("fingerprint", cert->fingerprint); + } + + Serializable *Unserialize(Serializable *obj, Serialize::Data &data) const override + { + uint64_t account = 0; + data["account"] >> account; + + auto *nc = NickCore::FindId(account); + if (!nc) + return nullptr; // Missing user. + + NSCertInfo *cert; + if (obj) + cert = anope_dynamic_static_cast(obj); + else + cert = new NSCertInfo(nc); + + data["created"] >> cert->created; + data["creator"] >> cert->creator; + data["description"] >> cert->description; + data["fingerprint"] >> cert->fingerprint; + + if (!obj) + { + auto *cl = nc->Require(NICKSERV_CERT_EXT); + cl->certs.push_back(cert); + certmap[cert->fingerprint] = cert; + } + + return cert; + } +}; + class CommandNSCert final : public Command { private: - void DoAdd(CommandSource &source, NickCore *nc, Anope::string certfp) + void DoAdd(CommandSource &source, const std::vector ¶ms) { - auto *cl = nc->Require(NICKSERV_CERT_EXT); + auto *nc = FindTarget(source, params.size() == 3 ? params[1] : "", true); + if (!nc) + return; + + const auto certfp = FindFingerprint(source, params, nc, false); + if (certfp.empty()) + return; + auto *cl = nc->Require(NICKSERV_CERT_EXT); const auto max = Config->GetModule(this->owner).Get("max", "5"); if (cl->GetCertCount() >= max) { @@ -219,19 +307,6 @@ class CommandNSCert final return; } - if (source.GetAccount() == nc) - { - User *u = source.GetUser(); - - if (!u || u->fingerprint.empty()) - { - source.Reply(_("You are not using a client certificate.")); - return; - } - - certfp = u->fingerprint; - } - if (cl->FindCert(certfp)) { source.Reply(_("Fingerprint \002%s\002 already present on %s's certificate list."), certfp.c_str(), nc->display.c_str()); @@ -244,28 +319,25 @@ class CommandNSCert final return; } - cl->AddCert(certfp); + auto *cert = cl->AddCert(certfp); + cert->created = Anope::CurTime; + cert->creator = source.GetNick(); + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD certificate fingerprint " << certfp << " to " << nc->display; source.Reply(_("\002%s\002 added to %s's certificate list."), certfp.c_str(), nc->display.c_str()); } - void DoDel(CommandSource &source, NickCore *nc, Anope::string certfp) + void DoDel(CommandSource &source, const std::vector ¶ms) { - auto *cl = nc->Require(NICKSERV_CERT_EXT); - - if (certfp.empty()) - { - User *u = source.GetUser(); - if (u) - certfp = u->fingerprint; - } + auto *nc = FindTarget(source, params.size() == 3 ? params[1] : "", true); + if (!nc) + return; + const auto certfp = FindFingerprint(source, params, nc, true); if (certfp.empty()) - { - this->OnSyntaxError(source, "DEL"); return; - } + auto *cl = nc->Require(NICKSERV_CERT_EXT); if (!cl->FindCert(certfp)) { source.Reply(_("\002%s\002 not found on %s's certificate list."), certfp.c_str(), nc->display.c_str()); @@ -278,81 +350,143 @@ class CommandNSCert final source.Reply(_("\002%s\002 deleted from %s's certificate list."), certfp.c_str(), nc->display.c_str()); } - static void DoList(CommandSource &source, const NickCore *nc) + void DoList(CommandSource &source, const std::vector ¶ms, bool full) { - auto *cl = nc->GetExt(NICKSERV_CERT_EXT); + auto *nc = FindTarget(source, params.size() > 1 ? params[1] : "", false); + if (!nc) + return; + auto *cl = nc->GetExt(NICKSERV_CERT_EXT); if (!cl || !cl->GetCertCount()) { source.Reply(_("%s's certificate list is empty."), nc->display.c_str()); return; } - source.Reply(_("Certificate list for %s:"), nc->display.c_str()); + ListFormatter list(source.GetAccount()); + list.AddColumn(_("Fingerprint")); + if (full) + { + list.AddColumn(_("Creator")).AddColumn(_("Created")); + list.SetFlexible([](ListFormatter::ListEntry &row) + { + return row["Description"].empty() + ? _("\002{fingerprint}\002 -- created by {creator} at {created}") + : _("\002{fingerprint}\002 -- created by {creator} at {created} ({description})"); + }); + } + else + { + list.SetFlexible([](ListFormatter::ListEntry &row) + { + return row["Description"].empty() + ? _("\002{fingerprint}\002") + : _("\002{fingerprint}\002 ({description})"); + }); + } + list.AddColumn(_("Description")); + for (unsigned i = 0; i < cl->GetCertCount(); ++i) { - Anope::string fingerprint = cl->GetCert(i); - source.Reply(" %s", fingerprint.c_str()); + auto *cert = cl->GetCert(i); + ListFormatter::ListEntry entry; + entry["Fingerprint"] = cert->fingerprint; + entry["Description"] = cert->description; + if (full) + { + entry["Created"] = cert->created + ? Anope::strftime(cert->created, nullptr, true) + : TIME_UNKNOWN; + + entry["Creator"] = cert->creator.empty() + ? TIME_UNKNOWN + : cert->creator; + } + list.AddEntry(entry); } - } -public: - CommandNSCert(Module *creator) : Command(creator, "nickserv/cert", 1, 3) - { - this->SetDesc(_("Modify the nickname client certificate list")); - this->SetSyntax(_("ADD [\037nickname\037] [\037fingerprint\037]")); - this->SetSyntax(_("DEL [\037nickname\037] \037fingerprint\037")); - this->SetSyntax(_("LIST [\037nickname\037]")); + source.Reply(_("Certificate list for %s:"), nc->display.c_str()); + list.SendTo(source); } - void Execute(CommandSource &source, const std::vector ¶ms) override + Anope::string FindFingerprint(CommandSource &source, const std::vector ¶ms, const NickCore *nc, bool del) { - const Anope::string &cmd = params[0]; - Anope::string nick, certfp; - - if (cmd.equals_ci("LIST")) - nick = params.size() > 1 ? params[1] : ""; - else + if (source.GetAccount() != nc || del) { - nick = params.size() == 3 ? params[1] : ""; - certfp = params.size() > 1 ? params[params.size() - 1] : ""; + if (params.size() > 1) + return params.back(); + + this->OnSyntaxError(source, params[0]); + return ""; } - NickCore *nc; + auto *u = source.GetUser(); + if (u && !u->fingerprint.empty()) + return u->fingerprint; + + source.Reply(_("You are not using a client certificate.")); + return ""; + } + + NickCore *FindTarget(CommandSource &source, const Anope::string &nick, bool modify) + { if (!nick.empty()) { - const NickAlias *na = NickAlias::Find(nick); - if (na == NULL) + const auto *na = NickAlias::Find(nick); + if (!na) { source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); - return; + return nullptr; } - else if (na->nc != source.GetAccount() && !source.HasPriv("nickserv/cert")) + + NickCore *nc = na->nc; + if (nc != source.GetAccount() && !source.HasPriv("nickserv/cert")) { source.Reply(ACCESS_DENIED); - return; + return nullptr; } - else if (Config->GetModule("nickserv").Get("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST")) + + if (modify) { - source.Reply(_("You may view but not modify the certificate list of other Services Operators.")); - return; + if (nc->HasExt("NS_SUSPENDED")) + { + source.Reply(NICK_X_SUSPENDED, nc->display.c_str()); + return nullptr; + } + if (Config->GetModule("nickserv").Get("secureadmins", "yes") && source.GetAccount() != nc && nc->IsServicesOper()) + { + source.Reply(_("You may view but not modify the certificate list of other Services Operators.")); + return nullptr; + } } - - nc = na->nc; + return nc; } - else - nc = source.nc; + return source.nc; + } + +public: + CommandNSCert(Module *creator) : Command(creator, "nickserv/cert", 1, 3) + { + this->SetDesc(_("Modify the nickname client certificate list")); + this->SetSyntax(_("ADD [\037nickname\037 \037fingerprint\037]")); + this->SetSyntax(_("DEL [\037nickname\037] \037fingerprint\037")); + this->SetSyntax(_("LIST [\037nickname\037]")); + this->SetSyntax(_("VIEW [\037nickname\037]")); + } + void Execute(CommandSource &source, const std::vector ¶ms) override + { + const Anope::string &cmd = params[0]; if (cmd.equals_ci("LIST")) - return this->DoList(source, nc); - else if (nc->HasExt("NS_SUSPENDED")) - source.Reply(NICK_X_SUSPENDED, nc->display.c_str()); + return this->DoList(source, params, false); + if (cmd.equals_ci("VIEW")) + return this->DoList(source, params, true); else if (Anope::ReadOnly) source.Reply(READ_ONLY_MODE); else if (cmd.equals_ci("ADD")) - return this->DoAdd(source, nc, certfp); + return this->DoAdd(source, params); else if (cmd.equals_ci("DEL")) - return this->DoDel(source, nc, certfp); + return this->DoDel(source, params); else this->OnSyntaxError(source, ""); } @@ -362,28 +496,148 @@ class CommandNSCert final this->SendSyntax(source); source.Reply(" "); source.Reply(_( - "Modifies or displays the certificate list for your nick. " - "If you connect to IRC and provide a client certificate with a " - "matching fingerprint in the cert list, you will be " - "automatically identified to services. Services Operators " - "may provide a nick to modify other users' certificate lists." - "\n\n" - "Examples:" - "\n\n" - " \002%s\033ADD\002\n" - " Adds your current fingerprint to the certificate list and\n" - " automatically identifies you when you connect to IRC\n" - " using this fingerprint." - "\n\n" - " \002%s\033DEL\033\002\n" - " Removes the fingerprint from your certificate list." - "\n\n" - " \002%s\033LIST\002\n" - " Displays the current certificate list." + "Modifies or displays the certificate list for your nick. If you connect to IRC and " + "provide a client certificate with a matching fingerprint in the cert list, you will " + "be automatically identified to services. Services Operators may provide a nick to " + "modify other users' certificate lists." + )); + + ExampleWrapper examples; + + examples.AddEntry("ADD", _( + "Adds your current fingerprint to your certificate list." + )); + examples.AddEntry(_("ADD \037nickname\037 \037fingerprint\037"), _( + "Adds the specified \037fingerprint\037 to the certificate list of \037nickname\037." + ), "nickserv/cert"); + + examples.AddEntry(_("DEL \037fingerprint\037"), _( + "Removes the specified \037fingerprint\037 from your certificate list." + )); + examples.AddEntry(_("DEL \037nickname\037 \037fingerprint\037"), _( + "Removes the specified \037fingerprint\037 from the certificate list of " + "\037nickname\037." + ), "nickserv/cert"); + + examples.AddEntry("LIST", _( + "Displays your current certificate list." + )); + examples.AddEntry(_("LIST \037nickname\037"), _( + "Displays the current certificate list of \037nickname\037." + ), "nickserv/cert"); + + examples.AddEntry("VIEW", _( + "Displays your current certificate list as well the details about who added each entry " + "and when they added it." + )); + examples.AddEntry(_("VIEW \037nickname\037"), _( + "Displays the current certificate list of \037nickname\037 as well as the details " + "about who added each entry and when they added it." + ), "nickserv/cert"); + + examples.SendTo(source); + + return true; + } +}; + +class CommandNSSetAutologin + : public Command +{ +public: + CommandNSSetAutologin(Module *creator, const Anope::string &sname = "nickserv/set/autologin", size_t min = 1) + : Command(creator, sname, min, min + 1) + { + this->SetDesc(_("Sets whether you should automatically be logged in when you connect using a known SSL certificate.")); + this->SetSyntax("{ON | OFF}"); + } + + void Run(CommandSource &source, const Anope::string &user, const Anope::string ¶m) + { + if (Anope::ReadOnly) + { + source.Reply(READ_ONLY_MODE); + return; + } + + const NickAlias *na = NickAlias::Find(user); + if (na == NULL) + { + source.Reply(NICK_X_NOT_REGISTERED, user.c_str()); + return; + } + NickCore *nc = na->nc; + + EventReturn MOD_RESULT; + FOREACH_RESULT(OnSetNickOption, MOD_RESULT, (source, this, nc, param)); + if (MOD_RESULT == EVENT_STOP) + return; + + if (param.equals_ci("ON")) + { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to enable autologin for " << na->nc->display; + nc->Extend("AUTOLOGIN"); + source.Reply(_("%s will now be automatically logged in when they connect using a known SSL certificate."), nc->display.c_str()); + } + else if (param.equals_ci("OFF")) + { + Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to disable autologin for " << na->nc->display; + nc->Shrink("AUTOLOGIN"); + source.Reply(_("%s will now not be automatically logged in when they connect using a known SSL certificate."), nc->display.c_str()); + } + else + this->OnSyntaxError(source, "AUTOLOGIN"); + } + + void Execute(CommandSource &source, const std::vector ¶ms) override + { + this->Run(source, source.nc->display, params[0]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply( + _( + "Sets whether you should automatically be logged in when you connect using a known " + "SSL certificate. You can configure your SSL certificate using the \002%s\002 " + "command." + ), + source.service->GetQueryCommand("nickserv/cert").c_str() + ); + return true; + } +}; + +class CommandNSSASetAutologin final + : public CommandNSSetAutologin +{ +public: + CommandNSSASetAutologin(Module *creator) + : CommandNSSetAutologin(creator, "nickserv/saset/autologin", 2) + { + this->ClearSyntax(); + this->SetSyntax(_("\037nickname\037 {ON | OFF}")); + } + + void Execute(CommandSource &source, const std::vector ¶ms) override + { + this->Run(source, params[0], params[1]); + } + + bool OnHelp(CommandSource &source, const Anope::string &) override + { + this->SendSyntax(source); + source.Reply(" "); + source.Reply( + _( + "Sets whether the given nickname should automatically be logged in when they " + "connect using a known SSL certificate. You can configure their SSL certificate " + "using the \002%s\002 command." ), - source.command.nobreak().c_str(), - source.command.nobreak().c_str(), - source.command.nobreak().c_str()); + source.service->GetQueryCommand("nickserv/cert").c_str() + ); return true; } }; @@ -391,15 +645,22 @@ class CommandNSCert final class NSCert final : public Module { +private: CommandNSCert commandnscert; + CommandNSSetAutologin commandnssetautologin; + CommandNSSASetAutologin commandnssasetautologin; NSCertListImpl::ExtensibleItem certs; CertServiceImpl cs; + NSCertInfoType cert_type; bool CanLogin(User *u, NickCore *nc) { if (!nc || nc->HasExt("NS_SUSPENDED")) return false; // Account suspended. + if (!nc->HasExt("AUTOLOGIN")) + return false; // Autologin disabled. + const auto maxlogins = Config->GetModule("ns_identify").Get("maxlogins"); if (maxlogins && nc->users.size() >= maxlogins) { @@ -416,6 +677,8 @@ class NSCert final NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR) , commandnscert(this) + , commandnssetautologin(this) + , commandnssasetautologin(this) , certs(this, NICKSERV_CERT_EXT) , cs(this) { @@ -449,7 +712,9 @@ class NSCert final return; auto *cl = certs.Require(na->nc); - cl->AddCert(u->fingerprint); + auto *cert = cl->AddCert(u->fingerprint); + cert->created = Anope::CurTime; + cert->creator = u->nick; auto *NickServ = Config->GetClient("NickServ"); u->SendMessage(NickServ, _("Your SSL certificate fingerprint \002%s\002 has been automatically added to your certificate list."), u->fingerprint.c_str()); diff --git a/modules/nickserv/ns_list.cpp b/modules/nickserv/ns_list.cpp index 2e2be40915..246c1ff624 100644 --- a/modules/nickserv/ns_list.cpp +++ b/modules/nickserv/ns_list.cpp @@ -67,12 +67,12 @@ class CommandNSList final } ListFormatter list(source.GetAccount()); - list.AddColumn(_("Nick")).AddColumn(_("Last mask")); + list.AddColumn(_("Nick")).AddColumn(_("Account")).AddColumn(_("Status")); list.SetFlexible([](ListFormatter::ListEntry &row) { - return row["Last mask"].empty() - ? _("\002{nick}\002") - : _("\002{nick}\002 (last mask: {last_mask})"); + return row["Status"].empty() + ? _("\002{nick}\002 (account: {account})") + : _("\002{nick}\002 -- {status} (account: {account})"); }); Anope::map ordered_map; @@ -96,11 +96,7 @@ class CommandNSList final else if (unconfirmed && !na->nc->HasExt("UNCONFIRMED")) continue; - /* We no longer compare the pattern against the output buffer. - * Instead we build a nice nick!user@host buffer to compare. - * The output is then generated separately. -TheShadow */ - Anope::string buf = Anope::Format("%s!%s", na->nick.c_str(), !na->last_userhost.empty() ? na->last_userhost.c_str() : "*@*"); - if (na->nick.equals_ci(pattern) || Anope::Match(buf, pattern, false, true)) + if (na->nick.equals_ci(pattern) || Anope::Match(na->nick, pattern, false, true)) { if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= listmax) { @@ -110,14 +106,13 @@ class CommandNSList final ListFormatter::ListEntry entry; entry["Nick"] = (isnoexpire ? "!" : "") + na->nick; - if (na->nc->HasExt("HIDE_MASK") && !is_servadmin && na->nc != mync) - entry["Last mask"] = Language::Translate(source.GetAccount(), _("[Hostname hidden]")); - else if (na->nc->HasExt("NS_SUSPENDED")) - entry["Last mask"] = Language::Translate(source.GetAccount(), _("[Suspended]")); + entry["Account"] = na->nc->display; + + auto &status = entry["Status"]; + if (na->nc->HasExt("NS_SUSPENDED")) + status = Language::Translate(source.GetAccount(), _("Suspended")); else if (na->nc->HasExt("UNCONFIRMED")) - entry["Last mask"] = Language::Translate(source.GetAccount(), _("[Unconfirmed]")); - else - entry["Last mask"] = is_servadmin ? na->last_userhost_real : na->last_userhost; + status = Language::Translate(source.GetAccount(), _("Unconfirmed")); list.AddEntry(entry); } ++count; @@ -147,23 +142,29 @@ class CommandNSList final "suspended, or are unconfirmed will be shown. If multiple options are " "given, nicks must match every option to be shown. " "Note that these options are limited to \037Services Operators\037." - "\n\n" - "Examples:" - "\n\n" - " \002LIST *!joeuser@foo.com\002\n" - " Lists all registered nicks owned by joeuser@foo.com." - "\n\n" - " \002LIST *Bot*!*@*\002\n" - " Lists all registered nicks with \002Bot\002 in their\n" - " names (case insensitive)." - "\n\n" - " \002LIST * NOEXPIRE\002\n" - " Lists all registered nicks which have been set to not expire." - "\n\n" - " \002LIST #51-100\002\n" - " Lists all registered nicks within the given range (51-100)." )); + ExampleWrapper examples; + examples.AddEntry("*Bot*", _( + "Lists all registered nicks with \037Bot\037 in their name (case insensitive)." + )); + examples.AddEntry("#51-100", _( + "Lists all registered nicks within the given range (51-100)." + )); + examples.AddEntry("* DISPLAY", _( + "Lists all registered nicks that are the display nickname for their account." + ), "nickserv/list"); + examples.AddEntry("* NOEXPIRE", _( + "Lists all registered nicks that have been set to not expire." + ), "nickserv/list"); + examples.AddEntry("* SUSPENDED", _( + "Lists all registered nicks that have been suspended." + ), "nickserv/list"); + examples.AddEntry("* UNCONFIRMED", _( + "Lists all registered nicks that have not been confirmed yet." + ), "nickserv/list"); + examples.SendTo(source); + const Anope::string ®exengine = Config->GetBlock("options").Get("regexengine"); if (!regexengine.empty()) { diff --git a/modules/nickserv/ns_set_misc.cpp b/modules/nickserv/ns_set_misc.cpp index ad21c6da6f..372bfea2f8 100644 --- a/modules/nickserv/ns_set_misc.cpp +++ b/modules/nickserv/ns_set_misc.cpp @@ -17,7 +17,20 @@ static Module *me; -static Anope::map descriptions; +#define MISC_PREFIX "ns_set_misc:" + +struct CommandData final +{ + Anope::string saset_description; + Anope::string set_description; + Anope::string pattern; + Anope::string syntax; + Anope::string title; + bool swhois = false; +}; + +static Anope::map command_data; + struct NSMiscData; static Anope::map *> items; @@ -99,13 +112,65 @@ static Anope::string GetAttribute(const Anope::string &command) { size_t sp = command.rfind(' '); if (sp != Anope::string::npos) - return command.substr(sp + 1); - return command; + return MISC_PREFIX + command.substr(sp + 1); + return MISC_PREFIX + command; +} + +static const char* GetTitle(ExtensibleItem *ext) +{ + auto it = command_data.find(ext->name); + if (it == command_data.end() || it->second.title.empty()) + return ext->name.c_str() + 12; + return it->second.title.c_str(); +} + +static void CheckSWhois(User* u, const Anope::string &name, ExtensibleItem *ext) +{ + auto it = command_data.find(name); + if (it == command_data.end() || !it->second.swhois) + return; // No swhois. + + auto *nickserv = Config->GetClient("NickServ"); + + auto *nc = u->Account(); + auto *data = nc ? ext->Get(nc) : nullptr; + if (data) + IRCD->SendSWhois(nickserv, u, name, Anope::Format("%s: %s", GetTitle(ext), data->data.c_str())); + else + IRCD->SendSWhoisDel(nickserv, u, name, ""); } class CommandNSSetMisc : public Command { +protected: + bool saset = false; + +private: + bool CheckSyntax(CommandSource &source, ExtensibleItem *ext, const Anope::string &value) const + { + auto it = command_data.find(ext->name); + if (it == command_data.end() || it->second.pattern.empty()) + return true; // No syntax validation. + + ServiceReference regex("Regex", Config->GetBlock("options").Get("regexengine")); + if (!regex) + return true; // No regex engine. + + auto ret = true; + try + { + auto *pattern = regex->Compile(it->second.pattern); + ret = pattern->Matches(value); + delete pattern; + } + catch (const RegexException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } + return ret; + } + public: CommandNSSetMisc(Module *creator, const Anope::string &cname = "nickserv/set/misc", size_t min = 0) : Command(creator, cname, min, min + 1) { @@ -133,22 +198,31 @@ class CommandNSSetMisc if (MOD_RESULT == EVENT_STOP) return; - Anope::string scommand = GetAttribute(source.command); - Anope::string key = "ns_set_misc:" + scommand; + const auto key = GetAttribute(source.command); ExtensibleItem *item = GetItem(key); if (item == NULL) return; if (!param.empty()) { + if (!CheckSyntax(source, item, param)) + { + source.Reply(CHAN_SETTING_INVALID, GetTitle(item)); + this->SendSyntax(source); + return; + } + item->Set(nc, NSMiscData(nc, key, param)); - source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), nc->display.c_str(), param.c_str()); + source.Reply(CHAN_SETTING_CHANGED, GetTitle(item), nc->display.c_str(), param.c_str()); } else { item->Unset(nc); - source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), nc->display.c_str()); + source.Reply(CHAN_SETTING_UNSET, GetTitle(item), nc->display.c_str()); } + + for (auto *u : nc->users) + CheckSWhois(u, key, item); } void Execute(CommandSource &source, const std::vector ¶ms) override @@ -158,23 +232,45 @@ class CommandNSSetMisc void OnServHelp(CommandSource &source, HelpWrapper &help) override { - if (descriptions.count(source.command)) - { - this->SetDesc(descriptions[source.command]); - Command::OnServHelp(source, help); - } + auto it = command_data.find(GetAttribute(source.command)); + if (it == command_data.end()) + return; + + const auto &desc = saset ? it->second.saset_description : it->second.set_description; + if (desc.empty()) + return; + + this->SetDesc(desc); + Command::OnServHelp(source, help); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) override { - if (descriptions.count(source.command)) - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply("%s", Language::Translate(source.nc, descriptions[source.command].c_str())); - return true; - } - return false; + auto it = command_data.find(GetAttribute(source.command)); + if (it == command_data.end()) + return false; + + const auto &desc = saset ? it->second.saset_description : it->second.set_description; + if (desc.empty()) + return false; + + this->SendSyntax(source); + source.Reply(" "); + source.Reply("%s", Language::Translate(source.nc, desc.c_str())); + return true; + } + + void SendSyntax(CommandSource &source) override + { + auto *value = _("value"); + auto it = command_data.find(GetAttribute(source.command)); + if (it != command_data.end() && !it->second.syntax.empty()) + value = it->second.syntax.c_str(); + + this->ClearSyntax(); + this->SetSyntax(Anope::Format("[\037%s\037]", Language::Translate(source.nc, value))); + + Command::SendSyntax(source); } }; @@ -184,14 +280,29 @@ class CommandNSSASetMisc final public: CommandNSSASetMisc(Module *creator) : CommandNSSetMisc(creator, "nickserv/saset/misc", 1) { - this->ClearSyntax(); - this->SetSyntax(_("\037nickname\037 [\037parameter\037]")); + this->saset = true; } void Execute(CommandSource &source, const std::vector ¶ms) override { this->Run(source, params[0], params.size() > 1 ? params[1] : ""); } + + void SendSyntax(CommandSource &source) override + { + auto *value = _("value"); + auto it = command_data.find(GetAttribute(source.command)); + if (it != command_data.end() && !it->second.syntax.empty()) + value = it->second.syntax.c_str(); + + this->ClearSyntax(); + this->SetSyntax(Anope::Format( + Language::Translate(source.nc, _("\037nickname\037 [\037%s\037]")), + Language::Translate(source.nc, value) + )); + + Command::SendSyntax(source); + } }; class NSSetMisc final @@ -218,30 +329,52 @@ class NSSetMisc final void OnReload(Configuration::Conf &conf) override { - descriptions.clear(); - + command_data.clear(); for (int i = 0; i < conf.CountBlock("command"); ++i) { const auto &block = conf.GetBlock("command", i); - const Anope::string &cmd = block.Get("command"); - if (cmd != "nickserv/set/misc" && cmd != "nickserv/saset/misc") continue; Anope::string cname = block.Get("name"); Anope::string desc = block.Get("misc_description"); - if (cname.empty() || desc.empty()) continue; - descriptions[cname] = desc; - // Force creation of the extension item. - GetItem("ns_set_misc:" + GetAttribute(cname)); + const auto extname = GetAttribute(cname); + GetItem(extname); + + auto &data = command_data[extname]; + if (cmd == "nickserv/saset/misc") + { + data.saset_description = desc; + continue; + } + + data.set_description = desc; + data.pattern = block.Get("misc_pattern"); + data.syntax = block.Get("misc_syntax"); + data.title = block.Get("misc_title"); + data.swhois = block.Get("misc_swhois"); } } + void OnUserLogin(User *u) override + { + if (u->server == Me || command_data.empty() || !IRCD->CanSendMultipleSWhois) + return; + + for (const auto &[name, ext] : items) + CheckSWhois(u, name, ext); + } + + void OnNickLogout(User *u) override + { + OnUserLogin(u); + } + void OnNickInfo(CommandSource &source, NickAlias *na, InfoFormatter &info, bool) override { for (const auto &[_, e] : items) @@ -249,7 +382,7 @@ class NSSetMisc final NSMiscData *data = e->Get(na->nc); if (data != NULL) - info[e->name.substr(12).replace_all_cs("_", " ")] = data->data; + info[GetTitle(e)] = data->data; } } }; diff --git a/modules/operserv/os_akill.cpp b/modules/operserv/os_akill.cpp index e873b991b0..1917e8dd8d 100644 --- a/modules/operserv/os_akill.cpp +++ b/modules/operserv/os_akill.cpp @@ -480,10 +480,7 @@ class CommandOSAKill final "The \002%s\033LIST\002 command displays the AKILL list. " "If a wildcard mask is given, only those entries matching the " "mask are displayed. If a list of entry numbers is given, " - "only those entries are shown; for example:\n" - " \002%s\033LIST\0332-5,7-9\002\n" - " Lists AKILL entries numbered 2 through 5 and 7\n" - " through 9." + "only those entries are shown." "\n\n" "\002%s\033VIEW\002 is a more verbose version of \002%s\033LIST\002, and " "will show who added an AKILL, the date it was added, and when " @@ -495,8 +492,14 @@ class CommandOSAKill final source.command.nobreak().c_str(), source.command.nobreak().c_str(), source.command.nobreak().c_str(), - source.command.nobreak().c_str(), source.command.nobreak().c_str()); + + ExampleWrapper examples; + examples.AddEntry("2-5,7-9", _( + "Lists AKILL entries numbered 2 through 5 and 7 through 9." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/operserv/os_config.cpp b/modules/operserv/os_config.cpp index 890dddf4c4..790c550813 100644 --- a/modules/operserv/os_config.cpp +++ b/modules/operserv/os_config.cpp @@ -119,10 +119,17 @@ class CommandOSConfig final "Settings changed by this command are temporary and will not be reflected " "back into the configuration file, and will be lost if Anope is shut down, " "restarted, or the configuration is reloaded." - "\n\n" - "Example:\n" - " \002MODIFY\033nickserv\033regdelay\03315m\002" )); + + ExampleWrapper examples; + examples.AddEntry("MODIFY nickserv regdelay 15m", _( + "Changes the registration delay to 15 minutes." + )); + examples.AddEntry("VIEW", _( + "Shows the current server configuration." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/operserv/os_logsearch.cpp b/modules/operserv/os_logsearch.cpp index 9eaff7ed5c..dce76f81ab 100644 --- a/modules/operserv/os_logsearch.cpp +++ b/modules/operserv/os_logsearch.cpp @@ -157,12 +157,15 @@ class CommandOSLogSearch final "and the number of replies to limit to. By default this " "command searches one week of logs, and limits replies " "to 50." - "\n\n" - "For example:\n" - " \002LOGSEARCH\033+21d\033+500l\033Anope\002\n" - " Searches the last 21 days worth of logs for messages\n" - " containing Anope and lists the most recent 500 of them." )); + + ExampleWrapper examples; + examples.AddEntry("+21d +500l Anope", _( + "Searches the last 21 days worth of logs for messages containing Anope and lists the " + "most recent 500 of them." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/operserv/os_mode.cpp b/modules/operserv/os_mode.cpp index dc846ae5ec..38b45db298 100644 --- a/modules/operserv/os_mode.cpp +++ b/modules/operserv/os_mode.cpp @@ -50,13 +50,14 @@ class CommandOSMode final if (all) { - for (const auto &[_, uc] : c->users) + for (const auto &[_, memb] : c->users) { - if (uc->user->HasMode("OPER")) + if (memb->user->HasMode("OPER")) continue; - for (auto *mode : uc->status.Modes()) - c->RemoveMode(c->WhoSends(), mode, uc->user->GetUID(), false); + auto modes = memb->status.Modes(); + for (auto *mode : modes) + c->RemoveMode(c->WhoSends(), mode, memb->user->GetUID(), false); } source.Reply(_("All modes cleared on %s."), c->name.c_str()); diff --git a/modules/operserv/os_sxline.cpp b/modules/operserv/os_sxline.cpp index f5205a055c..e1d50a04b1 100644 --- a/modules/operserv/os_sxline.cpp +++ b/modules/operserv/os_sxline.cpp @@ -493,10 +493,7 @@ class CommandOSSNLine final "The \002SNLINE\033LIST\002 command displays the SNLINE list. " "If a wildcard mask is given, only those entries matching the " "mask are displayed. If a list of entry numbers is given, " - "only those entries are shown; for example:\n" - " \002SNLINE\033LIST\0332-5,7-9\002\n" - " Lists SNLINE entries numbered 2 through 5 and 7\n" - " through 9." + "only those entries are shown." "\n\n" "\002SNLINE\033VIEW\002 is a more verbose version of \002SNLINE\033LIST\002, and " "will show who added an SNLINE, the date it was added, and when " @@ -504,6 +501,13 @@ class CommandOSSNLine final "\n\n" "\002SNLINE\033CLEAR\002 clears all entries of the SNLINE list." )); + + ExampleWrapper examples; + examples.AddEntry("LIST 2-5,7-9", _( + "Lists SNLINE entries numbered 2 through 5 and 7 through 9." + )); + examples.SendTo(source); + return true; } }; @@ -733,10 +737,7 @@ class CommandOSSQLine final "The \002SQLINE\033LIST\002 command displays the SQLINE list. " "If a wildcard mask is given, only those entries matching the " "mask are displayed. If a list of entry numbers is given, " - "only those entries are shown; for example:\n" - " \002SQLINE\033LIST\0332-5,7-9\002\n" - " Lists SQLINE entries numbered 2 through 5 and 7\n" - " through 9." + "only those entries are shown." "\n\n" "\002SQLINE\033VIEW\002 is a more verbose version of \002SQLINE\033LIST\002, and " "will show who added an SQLINE, the date it was added, and when " @@ -744,6 +745,13 @@ class CommandOSSQLine final "\n\n" "\002SQLINE\033CLEAR\002 clears all entries of the SQLINE list." )); + + ExampleWrapper examples; + examples.AddEntry("LIST 2-5,7-9", _( + "Lists SQLINE entries numbered 2 through 5 and 7 through 9." + )); + examples.SendTo(source); + return true; } }; diff --git a/modules/protocol/inspircd.cpp b/modules/protocol/inspircd.cpp index c797513efb..b84ffb9e05 100644 --- a/modules/protocol/inspircd.cpp +++ b/modules/protocol/inspircd.cpp @@ -1705,7 +1705,7 @@ struct IRCDMessageFIdent final { User *u = source.GetUser(); if (params[0] != "*") - u->SetDisplayedHost(params[0]); + u->SetIdent(params[0]); } }; @@ -2404,7 +2404,7 @@ struct IRCDMessageUID final * 3: host * 4: dhost * 5: ident - * 6: dident (v4 only) + * 6: dident * 7: ip * 8: signon * 9+: modes and params -- IMPORTANT, some modes (e.g. +s) may have parameters. So don't assume a fixed position of realname! @@ -2412,7 +2412,6 @@ struct IRCDMessageUID final */ void Run(MessageSource &source, const std::vector ¶ms, const Anope::map &tags) override { - size_t offset = params[8][0] == '+' ? 0 : 1; auto ts = IRCD->ExtractTimestamp(params[1]); NickAlias *na = NULL; @@ -2432,9 +2431,9 @@ struct IRCDMessageUID final ++it; } - auto *u = User::OnIntroduce(params[2], params[5+offset], params[3], params[4], params[6+offset], source.GetServer(), params[params.size() - 1], ts, params[8 + offset], params[0], na ? *na->nc : NULL, { params.begin() + 9 + offset, params.end() - 1 }); + auto *u = User::OnIntroduce(params[2], params[6], params[3], params[4], params[7], source.GetServer(), params[params.size() - 1], ts, params[9], params[0], na ? *na->nc : NULL, { params.begin() + 10, params.end() - 1 }); if (u) - u->signon = IRCD->ExtractTimestamp(params[7+offset]); + u->signon = IRCD->ExtractTimestamp(params[8]); } }; diff --git a/modules/protocol/solanum.cpp b/modules/protocol/solanum.cpp index 32b9e3647b..091f1843a7 100644 --- a/modules/protocol/solanum.cpp +++ b/modules/protocol/solanum.cpp @@ -421,12 +421,15 @@ struct IRCDMessagePass final struct IRCDMessageNotice final : Message::Notice { - IRCDMessageNotice(Module *creator) : Message::Notice(creator) { } + IRCDMessageNotice(Module *creator) + : Message::Notice(creator) + { + } void Run(MessageSource &source, const std::vector ¶ms, const Anope::map &tags) override { if (Servers::Capab.count("ECHO")) - Uplink::Send("ECHO", 'N', source.GetSource(), params[1]); + Uplink::Send(tags, "ECHO", 'N', source.GetSource(), params[1]); Message::Notice::Run(source, params, tags); } @@ -435,17 +438,38 @@ struct IRCDMessageNotice final struct IRCDMessagePrivmsg final : Message::Privmsg { - IRCDMessagePrivmsg(Module *creator) : Message::Privmsg(creator) { } + IRCDMessagePrivmsg(Module *creator) + : Message::Privmsg(creator) + { + } void Run(MessageSource &source, const std::vector ¶ms, const Anope::map &tags) override { if (Servers::Capab.count("ECHO")) - Uplink::Send("ECHO", 'P', source.GetSource(), params[1]); + Uplink::Send(tags, "ECHO", 'P', source.GetSource(), params[1]); Message::Privmsg::Run(source, params, tags); } }; +struct IRCDMessageTagmsg final + : IRCDMessage +{ + IRCDMessageTagmsg(Module *creator) + : IRCDMessage(creator, "TAGMSG", 1) + { + SetFlag(FLAG_REQUIRE_USER); + } + + void Run(MessageSource &source, const std::vector ¶ms, const Anope::map &tags) override + { + if (Servers::Capab.count("ECHO")) + Uplink::Send(tags, "ECHO", 'T', source.GetSource()); + + // We only care about implementing ECHO for now. + } +}; + class ProtoSolanum final : public Module { @@ -487,6 +511,7 @@ class ProtoSolanum final IRCDMessagePass message_pass; IRCDMessagePrivmsg message_privmsg; IRCDMessageServer message_server; + IRCDMessageTagmsg message_tagmsg; static void AddModes() { @@ -550,6 +575,7 @@ class ProtoSolanum final , message_pass(this) , message_privmsg(this) , message_server(this) + , message_tagmsg(this) { if (ModuleManager::LoadModule("ratbox", User::Find(creator)) != MOD_ERR_OK) throw ModuleException("Unable to load ratbox"); diff --git a/modules/protocol/unrealircd.cpp b/modules/protocol/unrealircd.cpp index e2266cb2c3..e9f83f6976 100644 --- a/modules/protocol/unrealircd.cpp +++ b/modules/protocol/unrealircd.cpp @@ -253,10 +253,12 @@ class UnrealIRCdProto final // NEXTBANS: enables receiving named extended bans. // SJSBY: enables receiving list mode setters and set timestamps. // SID: communicates the unique identifier of the local server. + // TS: communicates the current time for clock synchronisation purposes. // VHP: enable receiving the vhost in UID. Uplink::Send("PROTOCTL", "BIGLINES", "EXTSWHOIS", "MLOCK", "MTAGS", "NEXTBANS", "SJSBY", "VHP"); Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort()); Uplink::Send("PROTOCTL", "SID=" + Me->GetSID()); + Uplink::Send("PROTOCTL", "TS=" + Anope::ToString(Anope::CurTime)); SendServer(Me); } diff --git a/modules/webcpanel/pages/nickserv/cert.cpp b/modules/webcpanel/pages/nickserv/cert.cpp index 5ede15da19..2edc5c0ba4 100644 --- a/modules/webcpanel/pages/nickserv/cert.cpp +++ b/modules/webcpanel/pages/nickserv/cert.cpp @@ -41,7 +41,7 @@ bool WebCPanel::NickServ::Cert::OnRequest(HTTP::Provider *server, const Anope::s auto *cl = na->nc->GetExt<::NickServ::CertList>(NICKSERV_CERT_EXT); if (cl) for (unsigned i = 0; i < cl->GetCertCount(); ++i) - replacements["CERTS"] = cl->GetCert(i); + replacements["CERTS"] = cl->GetCert(i)->fingerprint; TemplateFileServer page("nickserv/cert.html"); page.Serve(server, page_name, client, message, reply, replacements); diff --git a/src/command.cpp b/src/command.cpp index 281b8ae78b..5e4538b579 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -209,7 +209,13 @@ void Command::OnServHelp(CommandSource &source, HelpWrapper &help) help.AddEntry(source.command, this->GetDesc(source)); } -bool Command::OnHelp(CommandSource &source, const Anope::string &subcommand) { return false; } +bool Command::OnHelp(CommandSource &source, const Anope::string &subcommand) +{ + this->SendSyntax(source); + source.Reply(" "); + source.Reply(this->GetDesc(source)); + return true; +} void Command::OnSyntaxError(CommandSource &source, const Anope::string &subcommand) { diff --git a/src/config.cpp b/src/config.cpp index 3ab46b1ecc..9f47ee2836 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -385,7 +385,8 @@ Conf::Conf() : Block("") auto *memb = c->FindUser(bi); if (memb != NULL) { - for (auto mode : memb->status.Modes()) + auto modes = memb->status.Modes(); + for (auto mode : modes) c->RemoveMode(bi, mode, bi->GetUID()); } /* Set the new modes */ diff --git a/src/misc.cpp b/src/misc.cpp index 650e5ccc58..c5d22475d8 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -310,6 +310,59 @@ void InfoFormatter::AddOption(const Anope::string &opt) this->options.push_back(Language::Translate(nc, opt.c_str())); } +ExampleWrapper &ExampleWrapper::AddEntry(const Anope::string &example, const Anope::string &desc, const Anope::string &priv) +{ + auto &entry = entries.emplace_back(); + entry.example = example; + entry.description = desc; + entry.privilege = priv; + return *this; +} + +void ExampleWrapper::SendTo(CommandSource &source) +{ + const auto *sourcenc = source.GetAccount(); + const auto flexible = sourcenc ? sourcenc->HasExt("NS_FLEXIBLE") : false; + const auto *monospace = !flexible && sourcenc && sourcenc->HasExt("NS_MONOSPACE") ? "\021" : ""; + + const auto max_length = Config->GetBlock("options").Get("linelength", "100"); + + auto header = true; + for (const auto &entry : entries) + { + if (!entry.privilege.empty() && !source.HasPriv(entry.privilege)) + continue; + + if (header) + { + source.Reply(" "); + source.Reply(_("Examples:")); + header = false; + } + + const auto *trans_example = Language::Translate(source.nc, entry.example.c_str()); + const auto *trans_description = Language::Translate(source.nc, entry.description.c_str()); + if (flexible) + { + source.Reply("\002%s%s%s\002: %s", source.command.c_str(), *trans_example ? " " : "", + trans_example, trans_description); + } + else + { + source.Reply(" "); + const auto full_example = Anope::Format("%s%s%s", source.command.c_str(), + *trans_example ? " " : "", trans_example); + + LineWrapper elw(full_example, max_length - 2); + for (Anope::string line; elw.GetLine(line); ) + source.Reply("%s \002%s\002", monospace, line.c_str()); + + LineWrapper dlw(trans_description, max_length - 4); + for (Anope::string line; dlw.GetLine(line); ) + source.Reply("%s %s", monospace, line.c_str()); + } + } +} void HelpWrapper::AddEntry(const Anope::string &name, const Anope::string &desc) { diff --git a/src/tools/mkauthors b/src/tools/mkauthors index d67c0d43df..704b243904 100755 --- a/src/tools/mkauthors +++ b/src/tools/mkauthors @@ -21,6 +21,11 @@ use warnings FATAL => qw(all); use File::Basename qw(dirname); use File::Spec::Functions qw(catfile); use FindBin qw($RealDir); +use Digest::SHA qw(sha256_hex); + +my @ignored_committers = ( + '2f51f982f0630009bad5e02e49212112d1f25785e6ce76847a48774b42dce7e4' # requested via email +); my %committers; for my $committer (split /\n+/, `git log --pretty='%an <%ae>%n%(trailers:key=Co-Authored-By,valueonly)' HEAD`) { @@ -34,9 +39,18 @@ for my $committer (keys %committers) { chomp(my $author = <$fh>); close $fh; - $author = $1 if $author =~ /^(.+) <(?:\S+\@localhost|\S+\@users.noreply.github.com)>$/; - next if $author =~ /\[bot\]$/; - next if $author =~ /^\(svnadmin\)$/; + next unless $author =~ /^(.+) <(.+)>$/; + my ($author_name, $author_email) = ($1, $2); + + # Skip bots and other non-human committers. + next if $author_name =~ /\[bot\]$/; + next if $author_name =~ /^\(svnadmin\)$/; + + # Skip ignored committers. + next if grep { $_ eq sha256_hex($author_email) } @ignored_committers; + + # Omit uncontactable email addresses. + $author = $author_name if $author_email =~ /^(?:\S+\@localhost|\S+\@users.noreply.github.com)$/; $authors{$author} ||= 0; $authors{$author} += $committers{$committer}; diff --git a/src/version.sh b/src/version.sh index 1a563c4dfe..b20712177a 100644 --- a/src/version.sh +++ b/src/version.sh @@ -2,5 +2,5 @@ VERSION_MAJOR=2 VERSION_MINOR=1 -VERSION_PATCH=22 +VERSION_PATCH=23 VERSION_EXTRA="-git"