From 14c2b6e9b00575cefca13717dd48f34af46a1e19 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Wed, 22 Mar 2023 09:35:36 +0100 Subject: [PATCH 1/3] Update formats (#14) * Add missing docstring section to `Deck::singleton` * Add `Deck::unlimited_champions` * Fix typo in `Deck::singleton` docstring * Rename *Standard* to *Eternal* * Allow displaying *Unlimited Champions* * Add more legality tests --- src/data/deckcode/deck.rs | 72 +++++++++++++++++++++++++++++++-------- src/discord/handler.rs | 6 ++-- src/telegram/display.rs | 7 ++-- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/data/deckcode/deck.rs b/src/data/deckcode/deck.rs index 8b17946..bb6da9e 100644 --- a/src/data/deckcode/deck.rs +++ b/src/data/deckcode/deck.rs @@ -440,7 +440,7 @@ impl Deck { /// Get the number of cards in the deck. /// - /// In the *Standard* and *Singleton* formats, this is never more than 40. + /// In the *Eternal* and *Singleton* formats, this is never more than 40. /// /// # Example /// @@ -460,7 +460,7 @@ impl Deck { /// Get the number of champion cards in the deck. /// - /// In the *Standard* and *Singleton* format, this is never more than 6. + /// In the *Eternal* and *Singleton* format, this is never more than 6. /// /// # Example /// @@ -544,13 +544,13 @@ impl Deck { } } - /// Check if the [`Deck`] is legal for play in the *Standard* format. + /// Check if the [`Deck`] is legal for play in the *Eternal* format. /// /// # Returns /// - /// - `None` if the deck is not legal for *Standard* play. - /// - `Some(regions)` if the deck is legal for *Standard* play considering the specified region set. - pub fn standard(&self, cards: &CardIndex) -> Option> { + /// - `None` if the deck is not legal for *Eternal* play. + /// - `Some(regions)` if the deck is legal for *Eternal* play considering the specified region set. + pub fn eternal(&self, cards: &CardIndex) -> Option> { let copies_limit = self.contents.values().all(|n| n <= &3); let cards_limit = self.card_count() == 40; let champions_limit = self.champions_count(cards) <= 6; @@ -563,6 +563,11 @@ impl Deck { } /// Check if the [`Deck`] is legal for play in the *Singleton* format. + /// + /// # Returns + /// + /// - `None` if the deck is not legal for *Singleton* play. + /// - `Some(regions)` if the deck is legal for *Singleton* play considering the specified region set. pub fn singleton(&self, cards: &CardIndex) -> Option> { let copies_limit = self.contents.values().all(|n| n <= &1); let cards_limit = self.card_count() == 40; @@ -574,6 +579,23 @@ impl Deck { true => regions, } } + + /// Check if the [`Deck`] is legal to play in the *Unlimited Champions* format. + /// + /// # Returns + /// + /// - `None` if the deck is not legal for *Unlimited Champions* play. + /// - `Some(regions)` if the deck is legal for *Unlimited Champions* play considering the specified region set. + pub fn unlimited_champions(&self, cards: &CardIndex) -> Option> { + let copies_limit = self.contents.values().all(|n| n <= &3); + let cards_limit = self.card_count() == 40; + let regions = self.regions(cards, 2); + + match copies_limit && cards_limit { + false => None, + true => regions, + } + } } /// An error occoured while decoding a [`Deck`] from a code. @@ -855,24 +877,24 @@ mod tests { } test_legality!( - test_legality_standard_lonelyporo1, + test_legality_eternal_lonelyporo1, deck!("CEAAAAIBAEAQQ"), - Deck::standard, false + Deck::eternal, false ); test_legality!( - test_legality_standard_twistedshrimp, + test_legality_eternal_twistedshrimp, deck!("CICACBAFAEBAGBQICABQCBJLF4YQOAQGAQEQYEQUDITAAAIBAMCQO"), - Deck::standard, true + Deck::eternal, true ); test_legality!( - test_legality_standard_poros, + test_legality_eternal_poros, deck!("CQDQCAQBAMAQGAICAECACDYCAECBIFYCAMCBEEYCAUFIYANAAEBQCAIICA2QCAQBAEVTSAA"), - Deck::standard, true + Deck::eternal, true ); test_legality!( - test_legality_standard_sand, + test_legality_eternal_sand, deck!("CMBAGBAHANTXEBQBAUCAOFJGFIYQEAIBAUOQIBAHGM5HM6ICAECAOOYCAECRSGY"), - Deck::standard, true + Deck::eternal, true ); test_legality!( @@ -900,4 +922,26 @@ mod tests { deck!("CQAAADABAICACAIFBLAACAIFAEHQCBQBEQBAGBADAQBAIAIKBUBAKBAWDUBQIBACA4GAMAIBAMCAYHJBGADAMBAOCQKRMKBLA4AQIAQ3D4QSIKZYBACAODJ3JRIW3AABQIAYUAI"), Deck::singleton, true ); + + // From https://lor.cardsrealm.com/en-us/articles/new-game-modes-in-lor-unlimited-and-free-decks-to-discover + test_legality!( + test_legality_unlchamp_gwenkataelise, + deck!("CUCACAIDFIAQEAYJAMDAKDAQBYCACBJVCYUDCAQCAEBRGOAEAYCSMHANEAAQCAIDFY"), + Deck::unlimited_champions, true + ); + test_legality!( + test_legality_unlchamp_norraveigarsenna, + deck!("CUCQCBIFBEAQMBIUAIAQKKABAMDAUDYVCECAKCS5MIY2MAICAECQVGABAECQKCADAECQVVIBAECQKCQBAYFBO"), + Deck::unlimited_champions, true + ); + test_legality!( + test_legality_unlchamp_poros, + deck!("CQDQCAQBAMAQGAICAECACDYCAECBIFYCAMCBEEYCAUFIYANAAEBQCAIICA2QCAQBAEVTSAA"), + Deck::unlimited_champions, true + ); + test_legality!( + test_legality_unlchamp_paltri, + deck!("CQAAADABAICACAIFBLAACAIFAEHQCBQBEQBAGBADAQBAIAIKBUBAKBAWDUBQIBACA4GAMAIBAMCAYHJBGADAMBAOCQKRMKBLA4AQIAQ3D4QSIKZYBACAODJ3JRIW3AABQIAYUAI"), + Deck::unlimited_champions, false + ); } diff --git a/src/discord/handler.rs b/src/discord/handler.rs index 01d41a0..ccdb718 100644 --- a/src/discord/handler.rs +++ b/src/discord/handler.rs @@ -226,8 +226,10 @@ impl EventHandler { None => format!("```text\n{}\n```", deck.to_code(DeckCodeFormat::F1).expect("to be able to serialize the deck code")), }); - let (format, regions) = if let Some(regions) = deck.standard(&engine.cards) { - ("<:neutral:1056022926660481094> Standard", regions) + let (format, regions) = if let Some(regions) = deck.eternal(&engine.cards) { + ("<:neutral:1056022926660481094> Eternal", regions) + } else if let Some(regions) = deck.unlimited_champions(&engine.cards) { + ("<:neutral:1056022926660481094> Unlimited Champions", regions) } else if let Some(regions) = deck.singleton(&engine.cards) { ("<:neutral:1056022926660481094> Singleton", regions) } else { diff --git a/src/telegram/display.rs b/src/telegram/display.rs index f8d7752..a5dde0d 100644 --- a/src/telegram/display.rs +++ b/src/telegram/display.rs @@ -204,8 +204,11 @@ pub fn display_deck(index: &CardIndex, deck: &Deck, code: &str, name: &Option<&s let mut tags: Vec<&'static str> = vec![]; - let regions = if let Some(regions) = deck.standard(index) { - tags.push("#Standard"); + let regions = if let Some(regions) = deck.eternal(index) { + tags.push("#Eternal"); + regions + } else if let Some(regions) = deck.unlimited_champions(index) { + tags.push("#UnlimitedChampions"); regions } else if let Some(regions) = deck.singleton(index) { tags.push("#Singleton"); From ce6a585505c5e8b2c7c4cd94a80261ff5090bce7 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 23 Mar 2023 18:51:35 +0100 Subject: [PATCH 2/3] Update README --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 966fc1d..e2a58d6 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,23 @@ # ![](icon.png) Patched Porobot -Legends of Runeterra card library and bots +Legends of Runeterra game data crate and chat bots -\[ **[Telegram]** | **[Discord]** | [Documentation] \] +## Links -[Telegram]: https://t.me/patchedporobot -[Discord]: https://discord.com/api/oauth2/authorize?client_id=1071989978743193672&scope=applications.commands -[Documentation]: https://docs.rs/crate/patched_porobot/latest +[![Telegram Bot](https://img.shields.io/badge/telegram%20bot-done-success)](https://t.me/patchedporobot) +  +[![Discord Bot](https://img.shields.io/badge/discord%20bot-done-success)](https://discord.com/api/oauth2/authorize?client_id=1071989978743193672&scope=applications.commands) +  +![Matrix Bot](https://img.shields.io/badge/matrix%20bot-to%20do-inactive) -## Legal - -patched-porobot isn't endorsed by Riot Games and doesn't reflect the views or opinions of Riot Games or anyone officially involved in producing or managing Riot Games properties. Riot Games, and all associated properties are trademarks or registered trademarks of Riot Games, Inc. +[![Crates.io](https://img.shields.io/crates/v/patched_porobot)](https://crates.io/crates/patched_porobot) +  +[![Documentation](https://img.shields.io/docsrs/patched_porobot)](https://docs.rs/patched_porobot/0.9.2/patched_porobot/) +  +[![Chat](https://img.shields.io/matrix/patched_porobot:ryg.one?server_fqdn=matrix.ryg.one)](https://matrix.to/#/#patched_porobot:ryg.one) ## Screenshots -> Click on a caption to view the related screenshot! - ### Telegram bot
@@ -52,3 +54,33 @@ patched-porobot isn't endorsed by Riot Games and doesn't reflect the views or op ![](media/td-message.png)
+ +## Licenses + +Patched Porobot isn't endorsed by Riot Games and doesn't reflect the views or opinions of Riot Games or anyone officially involved in producing or managing Riot Games properties. Riot Games, and all associated properties are trademarks or registered trademarks of Riot Games, Inc. + +
+List of licenses as output by cargo license + +- **(Apache-2.0 OR MIT) AND BSD-3-Clause** (1): encoding_rs +- **(MIT OR Apache-2.0) AND Unicode-DFS-2016** (1): unicode-ident +- **0BSD OR Apache-2.0 OR MIT** (1): adler +- **AGPL-3.0-or-later** (1): patched_porobot +- **Apache-2.0** (2): fail, varint-rs +- **Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT** (1): wasi +- **Apache-2.0 OR BSL-1.0** (1): ryu +- **Apache-2.0 OR ISC OR MIT** (4): hyper-rustls, rustls, rustls-pemfile, sct +- **Apache-2.0 OR MIT** (154): ahash, anyhow, arc-swap, async-trait, autocfg, base64, base64, bitflags, block-buffer, bumpalo, cc, cfg-if, chrono, cpufeatures, crc32fast, crossbeam-channel, crossbeam-deque, crossbeam-epoch, crossbeam-utils, crypto-common, digest, downcast-rs, either, env_logger, erasable, fastrand, flate2, fnv, form_urlencoded, fs2, futures, futures-channel, futures-core, futures-executor, futures-io, futures-macro, futures-sink, futures-task, futures-util, generator, getrandom, glob, hashbrown, hermit-abi, hermit-abi, http, httparse, httpdate, humantime, ident_case, idna, indexmap, ipnet, itertools, itertools, itoa, js-sys, lazy_static, libc, lock_api, log, md5, memmap2, mime, num-integer, num-traits, num_cpus, once_cell, oneshot, parking_lot, parking_lot_core, percent-encoding, pin-project, pin-project-internal, pin-project-lite, pin-utils, ppv-lite86, pretty_env_logger, proc-macro-error, proc-macro-error-attr, proc-macro2, quick-error, quote, rand, rand_chacha, rand_core, rayon, rayon-core, rc-box, regex, regex-syntax, remove_dir_all, reqwest, rustc-hash, rustc_version, rustversion, scoped-tls, scopeguard, semver, serde, serde_derive, serde_json, serde_urlencoded, serde_with_macros, sha-1, signal-hook-registry, smallvec, socket2, stable_deref_trait, syn, tempfile, thiserror, thiserror-impl, thread_local, time, time-core, time-macros, tokio-rustls, tungstenite, typenum, unicase, unicode-bidi, unicode-normalization, url, utf-8, uuid, version_check, wasm-bindgen, wasm-bindgen-backend, wasm-bindgen-futures, wasm-bindgen-macro, wasm-bindgen-macro-support, wasm-bindgen-shared, wasm-streams, web-sys, winapi, winapi-i686-pc-windows-gnu, winapi-x86_64-pc-windows-gnu, windows, windows-sys, windows-sys, windows-targets, windows_aarch64_gnullvm, windows_aarch64_msvc, windows_aarch64_msvc, windows_i686_gnu, windows_i686_gnu, windows_i686_msvc, windows_i686_msvc, windows_x86_64_gnu, windows_x86_64_gnu, windows_x86_64_gnullvm, windows_x86_64_msvc, windows_x86_64_msvc +- **Apache-2.0 OR MIT OR MPL-2.0** (1): htmlescape +- **Apache-2.0 OR MIT OR Zlib** (3): miniz_oxide, tinyvec, tinyvec_macros +- **BSD-3-Clause** (2): instant, never +- **BSD-3-Clause OR MIT** (1): rust-stemmers +- **Custom License File** (2): ring, webpki +- **ISC** (3): serenity, typemap_rev, untrusted +- **MIT** (62): aquamarine, async-tungstenite, atty, bitpacking, bytes, census, combine, convert_case, crunchy, darling, darling_core, darling_macro, dashmap, data-encoding, derive_more, dptree, fastfield_codecs, generic-array, h2, http-body, hyper, levenshtein_automata, loom, lru, lz4_flex, matchers, memoffset, mime_guess, mio, murmurhash32, nu-ansi-term, ordered-float, overload, ownedbytes, redox_syscall, serde-value, sharded-slab, slab, spin, strsim, take_mut, takecell, tantivy, tantivy-bitpacker, tantivy-common, tantivy-query-grammar, teloxide, teloxide-core, tokio, tokio-macros, tokio-stream, tokio-util, tower-service, tracing, tracing-attributes, tracing-core, tracing-log, tracing-subscriber, try-lock, valuable, want, winreg +- **MIT OR Unlicense** (8): aho-corasick, byteorder, memchr, regex-automata, tantivy-fst, termcolor, utf8-ranges, winapi-util +- **MPL-2.0** (1): webpki-roots +- **Unlicense** (1): measure_time +- **zlib-acknowledgement** (1): fastdivide + +
\ No newline at end of file From 649ec0c2490cb5461024a53df52b82c2c7e4bbeb Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 23 Mar 2023 18:52:46 +0100 Subject: [PATCH 3/3] Remove strikethrough over "Usage of the Discord bot" --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 8f64fa7..3b1076a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! If you are looking for the documentation of its implementations, please visit one of the following pages: //! //! - [Usage of the Telegram bot](../patched_porobot_telegram/index.html) -//! - ~~[Usage of the Discord bot](../patched_porobot_discord/index.html)~~ +//! - [Usage of the Discord bot](../patched_porobot_discord/index.html) //! - ~~[Usage of the Matrix bot](../patched_porobot_matrix/index.html)~~ //! //! # Features